summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1993-05-19 14:50:45 (GMT)
committerGuido van Rossum <guido@python.org>1993-05-19 14:50:45 (GMT)
commit25831652fd4c03323066d4cafdc0551c396a993e (patch)
tree69588df0f98b3280402cad3ed95865d06fa21702 /Python/compile.c
parent687dd13bfec51849c93db7c538ff41d4c8ecddcb (diff)
downloadcpython-25831652fd4c03323066d4cafdc0551c396a993e.zip
cpython-25831652fd4c03323066d4cafdc0551c396a993e.tar.gz
cpython-25831652fd4c03323066d4cafdc0551c396a993e.tar.bz2
Several changes in one:
(1) dictionaries/mappings now have attributes values() and items() as well as keys(); at the C level, use the new function mappinggetnext() to iterate over a dictionary. (2) "class C(): ..." is now illegal; you must write "class C: ...". (3) Class objects now know their own name (finally!); and minor improvements to the way how classes, functions and methods are represented as strings. (4) Added an "access" statement and semantics. (This is still experimental -- as long as you don't use the keyword 'access' nothing should be changed.)
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c137
1 files changed, 82 insertions, 55 deletions
diff --git a/Python/compile.c b/Python/compile.c
index dd79937..d9d661c 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1408,6 +1408,65 @@ com_global_stmt(c, n)
}
}
+#define strequ(a, b) (strcmp((a), (b)) == 0)
+
+static void
+com_access_stmt(c, n)
+ struct compiling *c;
+ node *n;
+{
+ int i, j, k, mode, imode;
+ object *vmode;
+ REQ(n, access_stmt);
+ /* 'access' NAME (',' NAME)* ':' accesstype (',' accesstype)*
+ accesstype: NAME+ */
+
+ /* Find where the colon is */
+ i = 1;
+ while (TYPE(CHILD(n,i-1)) != COLON)
+ i += 1;
+
+ /* Calculate the mode mask */
+ mode = 0;
+ for (j = i; j < NCH(n); j += 2) {
+ int r=0,w=0,p=0;
+ for (k=0; k<NCH(CHILD(n,j)); k++) {
+ if (strequ(STR(CHILD(CHILD(n,j),k)), "public"))
+ p = 0;
+ else if (strequ(STR(CHILD(CHILD(n,j),k)), "protected"))
+ p = 1;
+ else if (strequ(STR(CHILD(CHILD(n,j),k)), "private"))
+ p = 2;
+ else if (strequ(STR(CHILD(CHILD(n,j),k)), "read"))
+ r = 1;
+ else if (strequ(STR(CHILD(CHILD(n,j),k)), "write"))
+ w = 1;
+ else /* XXX should make this an exception */
+ fprintf(stderr, "bad access type %s\n",
+ STR(CHILD(CHILD(n,j),k)));
+ }
+ if (r == 0 && w == 0)
+ r =w = 1;
+ if (p == 0) {
+ if (r == 1) mode |= AC_R_PUBLIC;
+ if (w == 1) mode |= AC_W_PUBLIC;
+ } else if (p == 1) {
+ if (r == 1) mode |= AC_R_PROTECTED;
+ if (w == 1) mode |= AC_W_PROTECTED;
+ } else {
+ if (r == 1) mode |= AC_R_PRIVATE;
+ if (w == 1) mode |= AC_W_PRIVATE;
+ }
+ }
+ vmode = newintobject((long)mode);
+ imode = com_addconst(c, vmode);
+ XDECREF(vmode);
+ for (i = 1; TYPE(CHILD(n,i-1)) != COLON; i+=2) {
+ com_addoparg(c, LOAD_CONST, imode);
+ com_addopname(c, ACCESS_MODE, CHILD(n, i));
+ }
+}
+
static void
com_if_stmt(c, n)
struct compiling *c;
@@ -1726,23 +1785,7 @@ com_funcdef(c, n)
}
static void
-com_oldbases(c, n)
- struct compiling *c;
- node *n;
-{
- int i;
- REQ(n, baselist);
- /*
- baselist: atom arguments (',' atom arguments)*
- 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)
+com_bases(c, n)
struct compiling *c;
node *n;
{
@@ -1759,46 +1802,28 @@ com_classdef(c, n)
struct compiling *c;
node *n;
{
+ int i;
object *v;
REQ(n, classdef);
- /*
- classdef: 'class' NAME
- ['(' testlist ')' |'(' ')' ['=' baselist]] ':' suite
- baselist: atom arguments (',' atom arguments)*
- arguments: '(' ')'
- */
- /* 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));
- }
+ /* classdef: class NAME ['(' testlist ')'] ':' suite */
+ if ((v = newstringobject(STR(CHILD(n, 1)))) == NULL) {
+ c->c_errors++;
+ return;
}
+ /* Push the class name on the stack */
+ i = com_addconst(c, v);
+ com_addoparg(c, LOAD_CONST, i);
+ DECREF(v);
+ /* Push the tuple of base classes on the stack */
+ if (TYPE(CHILD(n, 2)) != LPAR)
+ com_addoparg(c, BUILD_TUPLE, 0);
+ else
+ com_bases(c, CHILD(n, 3));
v = (object *)compile(n, c->c_filename);
if (v == NULL)
c->c_errors++;
else {
- int i = com_addconst(c, v);
+ i = com_addconst(c, v);
com_addoparg(c, LOAD_CONST, i);
com_addbyte(c, BUILD_FUNCTION);
com_addbyte(c, UNARY_CALL);
@@ -1882,6 +1907,9 @@ com_node(c, n)
case global_stmt:
com_global_stmt(c, n);
break;
+ case access_stmt:
+ com_access_stmt(c, n);
+ break;
case if_stmt:
com_if_stmt(c, n);
break;
@@ -2084,9 +2112,8 @@ compile_node(c, n)
break;
case classdef: /* A class definition */
- /* classdef: 'class' NAME
- ['(' testlist ')' |'(' ')' ['=' baselist]]
- ':' suite */
+ /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
+ c->c_name = STR(CHILD(n, 1));
com_node(c, CHILD(n, NCH(n)-1)); /* The suite */
com_addbyte(c, LOAD_LOCALS);
com_addbyte(c, RETURN_VALUE);
@@ -2114,8 +2141,8 @@ compile_node(c, n)
There is one problem: 'from foo import *' introduces local variables
that we can't know while compiling. If this is the case, wo don't
- optimize at all (this rarely happens, since import is mostly used
- at the module level).
+ optimize at all (this rarely happens, since this form of import
+ statement is mostly used at the module level).
Note that, because of this optimization, code like the following
won't work: