]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Two independent chages:
authorGuido van Rossum <guido@python.org>
Sat, 7 Jan 1995 12:41:23 +0000 (12:41 +0000)
committerGuido van Rossum <guido@python.org>
Sat, 7 Jan 1995 12:41:23 +0000 (12:41 +0000)
(a) support import NAME.NAME...NAME;
(b) support doc strings in modules, classes and function definitions

Python/compile.c

index a83f9296386d42d2d0db21dc7e2c4351505b7209..07c514ccf12648d468948ae2d85aee197eb3ea41 100644 (file)
@@ -446,21 +446,14 @@ com_addname(c, v)
 }
 
 static void
-com_addopname(c, op, n)
+com_addopnamestr(c, op, name)
        struct compiling *c;
        int op;
-       node *n;
+       char *name;
 {
        object *v;
        int i;
-       char *name;
-       if (TYPE(n) == STAR)
-               name = "*";
-       else {
-               REQ(n, NAME);
-               name = STR(n);
-       }
-       if ((v = newstringobject(name)) == NULL) {
+       if (name == NULL || (v = newstringobject(name)) == NULL) {
                c->c_errors++;
                i = 255;
        }
@@ -484,6 +477,45 @@ com_addopname(c, op, n)
        com_addoparg(c, op, i);
 }
 
+static void
+com_addopname(c, op, n)
+       struct compiling *c;
+       int op;
+       node *n;
+{
+       object *v;
+       char *name;
+       char buffer[1000];
+       /* XXX it is possible to write this code without the 1000
+          chars on the total length of dotted names, I just can't be
+          bothered right now */
+       if (TYPE(n) == STAR)
+               name = "*";
+       else if (TYPE(n) == dotted_name) {
+               char *p = buffer;
+               int i;
+               name = buffer;
+               for (i = 0; i < NCH(n); i += 2) {
+                       char *s = STR(CHILD(n, i));
+                       if (p + strlen(s) > buffer + (sizeof buffer) - 2) {
+                               err_setstr(MemoryError,
+                                          "dotted_name too long");
+                               name == NULL;
+                               break;
+                       }
+                       if (p != buffer)
+                               *p++ = '.';
+                       strcpy(p, s);
+                       p = strchr(p, '\0');
+               }
+       }
+       else {
+               REQ(n, NAME);
+               name = STR(n);
+       }
+       com_addopnamestr(c, op, name);
+}
+
 static object *
 parsenumber(s)
        char *s;
@@ -593,6 +625,22 @@ parsestr(s)
        return v;
 }
 
+static object *
+parsestrplus(n)
+       node *n;
+{
+       object *v;
+       int i;
+       REQ(CHILD(n, 0), STRING);
+       if ((v = parsestr(STR(CHILD(n, 0)))) != NULL) {
+               /* String literal concatenation */
+               for (i = 1; i < NCH(n) && v != NULL; i++) {
+                       joinstring_decref(&v, parsestr(STR(CHILD(n, i))));
+               }
+       }
+       return v;
+}
+
 static void
 com_list_constructor(c, n)
        struct compiling *c;
@@ -671,13 +719,7 @@ com_atom(c, n)
                com_addoparg(c, LOAD_CONST, i);
                break;
        case STRING:
-               if ((v = parsestr(STR(ch))) != NULL) {
-                       /* String literal concatenation */
-                       for (i = 1; i < NCH(n) && v != NULL; i++) {
-                               joinstring_decref(&v,
-                                       parsestr(STR(CHILD(n, i))));
-                       }
-               }
+               v = parsestrplus(n);
                if (v == NULL) {
                        c->c_errors++;
                        i = 255;
@@ -1457,11 +1499,11 @@ com_import_stmt(c, n)
 {
        int i;
        REQ(n, import_stmt);
-       /* 'import' NAME (',' NAME)* |
-          'from' NAME 'import' ('*' | NAME (',' NAME)*) */
+       /* 'import' dotted_name (',' dotted_name)* |
+          'from' dotted_name 'import' ('*' | NAME (',' NAME)*) */
        if (STR(CHILD(n, 0))[0] == 'f') {
-               /* 'from' NAME 'import' ... */
-               REQ(CHILD(n, 1), NAME);
+               /* 'from' dotted_name 'import' ... */
+               REQ(CHILD(n, 1), dotted_name);
                com_addopname(c, IMPORT_NAME, CHILD(n, 1));
                for (i = 3; i < NCH(n); i += 2)
                        com_addopname(c, IMPORT_FROM, CHILD(n, i));
@@ -1470,8 +1512,9 @@ com_import_stmt(c, n)
        else {
                /* 'import' ... */
                for (i = 1; i < NCH(n); i += 2) {
+                       REQ(CHILD(n, i), dotted_name);
                        com_addopname(c, IMPORT_NAME, CHILD(n, i));
-                       com_addopname(c, STORE_NAME, CHILD(n, i));
+                       com_addopname(c, STORE_NAME, CHILD(CHILD(n, i), 0));
                }
        }
 }
@@ -1821,6 +1864,56 @@ com_try_stmt(c, n)
                com_try_except(c, n);
 }
 
+static object *
+get_docstring(n)
+       node *n;
+{
+       switch (TYPE(n)) {
+
+       case suite:
+               if (NCH(n) == 1)
+                       return get_docstring(CHILD(n, 0));
+               else {
+                       int i;
+                       for (i = 0; i < NCH(n); i++) {
+                               node *ch = CHILD(n, i);
+                               if (TYPE(ch) == stmt)
+                                       return get_docstring(ch);
+                       }
+               }
+               break;
+
+       case stmt:
+       case simple_stmt:
+       case small_stmt:
+               return get_docstring(CHILD(n, 0));
+
+       case expr_stmt:
+       case testlist:
+       case test:
+       case and_test:
+       case not_test:
+       case comparison:
+       case expr:
+       case xor_expr:
+       case and_expr:
+       case shift_expr:
+       case arith_expr:
+       case term:
+       case factor:
+               if (NCH(n) == 1)
+                       return get_docstring(CHILD(n, 0));
+               break;
+
+       case atom:
+               if (TYPE(CHILD(n, 0)) == STRING)
+                       return parsestrplus(n);
+               break;
+
+       }
+       return NULL;
+}
+
 static void
 com_suite(c, n)
        struct compiling *c;
@@ -2235,7 +2328,15 @@ com_file_input(c, n)
        node *n;
 {
        int i;
+       object *doc;
        REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */
+       doc = get_docstring(n);
+       if (doc != NULL) {
+               int i = com_addconst(c, doc);
+               DECREF(doc);
+               com_addoparg(c, LOAD_CONST, i);
+               com_addopnamestr(c, STORE_NAME, "__doc__");
+       }
        for (i = 0; i < NCH(n); i++) {
                node *ch = CHILD(n, i);
                if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
@@ -2250,9 +2351,15 @@ compile_funcdef(c, n)
        struct compiling *c;
        node *n;
 {
+       object *doc;
        node *ch;
        REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
        c->c_name = STR(CHILD(n, 1));
+       doc = get_docstring(CHILD(n, 4));
+       if (doc != NULL) {
+               (void) com_addconst(c, doc);
+               DECREF(doc);
+       }
        com_addoparg(c, RESERVE_FAST, com_addconst(c, None)); /* Patched! */
        ch = CHILD(n, 2); /* parameters: '(' [varargslist] ')' */
        ch = CHILD(ch, 1); /* ')' | varargslist */
@@ -2277,6 +2384,7 @@ compile_lambdef(c, n)
        c->c_name = "<lambda>";
 
        ch = CHILD(n, 1);
+       (void) com_addconst(c, None);
        if (TYPE(ch) == COLON) {
                com_addoparg(c, UNPACK_ARG, 0);
                com_node(c, CHILD(n, 2));
@@ -2290,6 +2398,31 @@ compile_lambdef(c, n)
        com_addbyte(c, RETURN_VALUE);
 }
 
+static void
+compile_classdef(c, n)
+       struct compiling *c;
+       node *n;
+{
+       node *ch;
+       object *doc;
+       REQ(n, classdef);
+       /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */
+       c->c_name = STR(CHILD(n, 1));
+       ch = CHILD(n, NCH(n)-1); /* The suite */
+       doc = get_docstring(ch);
+       if (doc != NULL) {
+               int i = com_addconst(c, doc);
+               DECREF(doc);
+               com_addoparg(c, LOAD_CONST, i);
+               com_addopnamestr(c, STORE_NAME, "__doc__");
+       }
+       else
+               (void) com_addconst(c, None);
+       com_node(c, ch);
+       com_addbyte(c, LOAD_LOCALS);
+       com_addbyte(c, RETURN_VALUE);
+}
+
 static void
 compile_node(c, n)
        struct compiling *c;
@@ -2330,11 +2463,7 @@ compile_node(c, n)
                break;
        
        case classdef: /* A class definition */
-               /* 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);
+               compile_classdef(c, n);
                break;
        
        default: