Two independent chages:
(a) support import NAME.NAME...NAME; (b) support doc strings in modules, classes and function definitions
This commit is contained in:
parent
06186519e5
commit
1f4fa50176
183
Python/compile.c
183
Python/compile.c
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue