Two independent chages:

(a) support import NAME.NAME...NAME;
(b) support doc strings in modules, classes and function definitions
This commit is contained in:
Guido van Rossum 1995-01-07 12:41:23 +00:00
parent 06186519e5
commit 1f4fa50176
1 changed files with 156 additions and 27 deletions

View File

@ -446,21 +446,14 @@ com_addname(c, v)
} }
static void static void
com_addopname(c, op, n) com_addopnamestr(c, op, name)
struct compiling *c; struct compiling *c;
int op; int op;
node *n; char *name;
{ {
object *v; object *v;
int i; int i;
char *name; if (name == NULL || (v = newstringobject(name)) == NULL) {
if (TYPE(n) == STAR)
name = "*";
else {
REQ(n, NAME);
name = STR(n);
}
if ((v = newstringobject(name)) == NULL) {
c->c_errors++; c->c_errors++;
i = 255; i = 255;
} }
@ -484,6 +477,45 @@ com_addopname(c, op, n)
com_addoparg(c, op, i); 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 * static object *
parsenumber(s) parsenumber(s)
char *s; char *s;
@ -593,6 +625,22 @@ parsestr(s)
return v; 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 static void
com_list_constructor(c, n) com_list_constructor(c, n)
struct compiling *c; struct compiling *c;
@ -671,13 +719,7 @@ com_atom(c, n)
com_addoparg(c, LOAD_CONST, i); com_addoparg(c, LOAD_CONST, i);
break; break;
case STRING: case STRING:
if ((v = parsestr(STR(ch))) != NULL) { v = parsestrplus(n);
/* String literal concatenation */
for (i = 1; i < NCH(n) && v != NULL; i++) {
joinstring_decref(&v,
parsestr(STR(CHILD(n, i))));
}
}
if (v == NULL) { if (v == NULL) {
c->c_errors++; c->c_errors++;
i = 255; i = 255;
@ -1457,11 +1499,11 @@ com_import_stmt(c, n)
{ {
int i; int i;
REQ(n, import_stmt); REQ(n, import_stmt);
/* 'import' NAME (',' NAME)* | /* 'import' dotted_name (',' dotted_name)* |
'from' NAME 'import' ('*' | NAME (',' NAME)*) */ 'from' dotted_name 'import' ('*' | NAME (',' NAME)*) */
if (STR(CHILD(n, 0))[0] == 'f') { if (STR(CHILD(n, 0))[0] == 'f') {
/* 'from' NAME 'import' ... */ /* 'from' dotted_name 'import' ... */
REQ(CHILD(n, 1), NAME); REQ(CHILD(n, 1), dotted_name);
com_addopname(c, IMPORT_NAME, CHILD(n, 1)); com_addopname(c, IMPORT_NAME, CHILD(n, 1));
for (i = 3; i < NCH(n); i += 2) for (i = 3; i < NCH(n); i += 2)
com_addopname(c, IMPORT_FROM, CHILD(n, i)); com_addopname(c, IMPORT_FROM, CHILD(n, i));
@ -1470,8 +1512,9 @@ com_import_stmt(c, n)
else { else {
/* 'import' ... */ /* 'import' ... */
for (i = 1; i < NCH(n); i += 2) { 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, 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); 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 static void
com_suite(c, n) com_suite(c, n)
struct compiling *c; struct compiling *c;
@ -2235,7 +2328,15 @@ com_file_input(c, n)
node *n; node *n;
{ {
int i; int i;
object *doc;
REQ(n, file_input); /* (NEWLINE | stmt)* ENDMARKER */ 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++) { for (i = 0; i < NCH(n); i++) {
node *ch = CHILD(n, i); node *ch = CHILD(n, i);
if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE) if (TYPE(ch) != ENDMARKER && TYPE(ch) != NEWLINE)
@ -2250,9 +2351,15 @@ compile_funcdef(c, n)
struct compiling *c; struct compiling *c;
node *n; node *n;
{ {
object *doc;
node *ch; node *ch;
REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */ REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
c->c_name = STR(CHILD(n, 1)); 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! */ com_addoparg(c, RESERVE_FAST, com_addconst(c, None)); /* Patched! */
ch = CHILD(n, 2); /* parameters: '(' [varargslist] ')' */ ch = CHILD(n, 2); /* parameters: '(' [varargslist] ')' */
ch = CHILD(ch, 1); /* ')' | varargslist */ ch = CHILD(ch, 1); /* ')' | varargslist */
@ -2277,6 +2384,7 @@ compile_lambdef(c, n)
c->c_name = "<lambda>"; c->c_name = "<lambda>";
ch = CHILD(n, 1); ch = CHILD(n, 1);
(void) com_addconst(c, None);
if (TYPE(ch) == COLON) { if (TYPE(ch) == COLON) {
com_addoparg(c, UNPACK_ARG, 0); com_addoparg(c, UNPACK_ARG, 0);
com_node(c, CHILD(n, 2)); com_node(c, CHILD(n, 2));
@ -2290,6 +2398,31 @@ compile_lambdef(c, n)
com_addbyte(c, RETURN_VALUE); 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 static void
compile_node(c, n) compile_node(c, n)
struct compiling *c; struct compiling *c;
@ -2330,11 +2463,7 @@ compile_node(c, n)
break; break;
case classdef: /* A class definition */ case classdef: /* A class definition */
/* classdef: 'class' NAME ['(' testlist ')'] ':' suite */ compile_classdef(c, n);
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);
break; break;
default: default: