mirror of https://github.com/python/cpython
Implement 'global' and new class syntax.
This commit is contained in:
parent
e2966a6362
commit
c5e96291d0
107
Python/compile.c
107
Python/compile.c
|
@ -136,6 +136,7 @@ struct compiling {
|
|||
object *c_code; /* string */
|
||||
object *c_consts; /* list of objects */
|
||||
object *c_names; /* list of strings (names) */
|
||||
object *c_globals; /* dictionary */
|
||||
int c_nexti; /* index into c_code */
|
||||
int c_errors; /* counts errors occurred */
|
||||
int c_infunction; /* set when compiling a function */
|
||||
|
@ -204,6 +205,8 @@ com_init(c, filename)
|
|||
goto fail_2;
|
||||
if ((c->c_names = newlistobject(0)) == NULL)
|
||||
goto fail_1;
|
||||
if ((c->c_globals = newdictobject()) == NULL)
|
||||
goto fail_0;
|
||||
c->c_nexti = 0;
|
||||
c->c_errors = 0;
|
||||
c->c_infunction = 0;
|
||||
|
@ -213,6 +216,8 @@ com_init(c, filename)
|
|||
c->c_filename = filename;
|
||||
return 1;
|
||||
|
||||
fail_0:
|
||||
DECREF(c->c_names);
|
||||
fail_1:
|
||||
DECREF(c->c_consts);
|
||||
fail_2:
|
||||
|
@ -228,6 +233,7 @@ com_free(c)
|
|||
XDECREF(c->c_code);
|
||||
XDECREF(c->c_consts);
|
||||
XDECREF(c->c_names);
|
||||
XDECREF(c->c_globals);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -381,6 +387,19 @@ com_addopname(c, op, n)
|
|||
i = com_addname(c, v);
|
||||
DECREF(v);
|
||||
}
|
||||
/* Hack to replace *_NAME opcodes by *_GLOBAL if necessary */
|
||||
switch (op) {
|
||||
case LOAD_NAME:
|
||||
case STORE_NAME:
|
||||
case DELETE_NAME:
|
||||
if (dictlookup(c->c_globals, name) != NULL) {
|
||||
switch (op) {
|
||||
case LOAD_NAME: op = LOAD_GLOBAL; break;
|
||||
case STORE_NAME: op = STORE_GLOBAL; break;
|
||||
case DELETE_NAME: op = DELETE_GLOBAL; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
com_addoparg(c, op, i);
|
||||
}
|
||||
|
||||
|
@ -390,10 +409,15 @@ parsenumber(s)
|
|||
{
|
||||
extern long strtol();
|
||||
extern double strtod();
|
||||
char *end = s;
|
||||
char *end;
|
||||
long x;
|
||||
double xx;
|
||||
errno = 0;
|
||||
end = s + strlen(s) - 1;
|
||||
if (*end == 'l' || *end == 'L') {
|
||||
extern object *long_scan();
|
||||
return long_scan(s, 0);
|
||||
}
|
||||
x = strtol(s, &end, 0);
|
||||
if (*end == '\0') {
|
||||
if (errno != 0) {
|
||||
|
@ -402,10 +426,6 @@ parsenumber(s)
|
|||
}
|
||||
return newintobject(x);
|
||||
}
|
||||
if (*end == 'l' || *end == 'L') {
|
||||
extern object *long_scan();
|
||||
return long_scan(s, 0);
|
||||
}
|
||||
errno = 0;
|
||||
xx = strtod(s, &end);
|
||||
if (*end == '\0') {
|
||||
|
@ -1341,6 +1361,21 @@ com_import_stmt(c, n)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
com_global_stmt(c, n)
|
||||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
int i;
|
||||
object *v;
|
||||
REQ(n, global_stmt);
|
||||
/* 'global' NAME (',' NAME)* */
|
||||
for (i = 1; i < NCH(n); i += 2) {
|
||||
if (dictinsert(c->c_globals, STR(CHILD(n, i)), None) != 0)
|
||||
c->c_errors++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
com_if_stmt(c, n)
|
||||
struct compiling *c;
|
||||
|
@ -1654,7 +1689,7 @@ com_funcdef(c, n)
|
|||
}
|
||||
|
||||
static void
|
||||
com_bases(c, n)
|
||||
com_oldbases(c, n)
|
||||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
|
@ -1662,13 +1697,26 @@ com_bases(c, n)
|
|||
REQ(n, baselist);
|
||||
/*
|
||||
baselist: atom arguments (',' atom arguments)*
|
||||
arguments: '(' [testlist] ')'
|
||||
arguments: '(' ')'
|
||||
*/
|
||||
for (i = 0; i < NCH(n); i += 3)
|
||||
com_node(c, CHILD(n, i));
|
||||
com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 3);
|
||||
}
|
||||
|
||||
static void
|
||||
com_newbases(c, n)
|
||||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
int i, nbases;
|
||||
REQ(n, testlist);
|
||||
/* testlist: test (',' test)* [','] */
|
||||
for (i = 0; i < NCH(n); i += 2)
|
||||
com_node(c, CHILD(n, i));
|
||||
com_addoparg(c, BUILD_TUPLE, (NCH(n)+1) / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
com_classdef(c, n)
|
||||
struct compiling *c;
|
||||
|
@ -1677,14 +1725,38 @@ com_classdef(c, n)
|
|||
object *v;
|
||||
REQ(n, classdef);
|
||||
/*
|
||||
classdef: 'class' NAME parameters ['=' baselist] ':' suite
|
||||
classdef: 'class' NAME
|
||||
['(' testlist ')' |'(' ')' ['=' baselist]] ':' suite
|
||||
baselist: atom arguments (',' atom arguments)*
|
||||
arguments: '(' [testlist] ')'
|
||||
arguments: '(' ')'
|
||||
*/
|
||||
if (NCH(n) == 7)
|
||||
com_bases(c, CHILD(n, 4));
|
||||
else
|
||||
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
|
||||
/* This piece of code must push a tuple on the stack (the bases) */
|
||||
if (TYPE(CHILD(n, 2)) != LPAR) {
|
||||
/* New syntax without base classes:
|
||||
class NAME ':' suite
|
||||
___________^
|
||||
*/
|
||||
com_addoparg(c, BUILD_TUPLE, 0);
|
||||
}
|
||||
else {
|
||||
if (TYPE(CHILD(n, 3)) == RPAR) {
|
||||
/* Old syntax with or without base classes:
|
||||
class NAME '(' ')' ['=' baselist] ':' suite
|
||||
_______________^....^...^
|
||||
*/
|
||||
if (TYPE(CHILD(n, 4)) == EQUAL)
|
||||
com_oldbases(c, CHILD(n, 5));
|
||||
else
|
||||
com_addoparg(c, BUILD_TUPLE, 0);
|
||||
}
|
||||
else {
|
||||
/* New syntax with base classes:
|
||||
class NAME '(' testlist ')' ':' suite
|
||||
_______________^
|
||||
*/
|
||||
com_newbases(c, CHILD(n, 3));
|
||||
}
|
||||
}
|
||||
v = (object *)compile(n, c->c_filename);
|
||||
if (v == NULL)
|
||||
c->c_errors++;
|
||||
|
@ -1770,6 +1842,9 @@ com_node(c, n)
|
|||
case import_stmt:
|
||||
com_import_stmt(c, n);
|
||||
break;
|
||||
case global_stmt:
|
||||
com_global_stmt(c, n);
|
||||
break;
|
||||
case if_stmt:
|
||||
com_if_stmt(c, n);
|
||||
break;
|
||||
|
@ -1950,9 +2025,11 @@ compile_node(c, n)
|
|||
break;
|
||||
|
||||
case classdef: /* A class definition */
|
||||
/* 'class' NAME parameters ['=' baselist] ':' suite */
|
||||
/* classdef: 'class' NAME
|
||||
['(' testlist ')' |'(' ')' ['=' baselist]]
|
||||
':' suite */
|
||||
com_addbyte(c, REFUSE_ARGS);
|
||||
com_node(c, CHILD(n, NCH(n)-1));
|
||||
com_node(c, CHILD(n, NCH(n)-1)); /* The suite */
|
||||
com_addbyte(c, LOAD_LOCALS);
|
||||
com_addbyte(c, RETURN_VALUE);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue