summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c100
1 files changed, 78 insertions, 22 deletions
diff --git a/Python/compile.c b/Python/compile.c
index a178bdb..df81f8f 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -782,19 +782,72 @@ com_apply_subscript(c, n)
}
}
+static int
+com_argument(c, n, inkeywords)
+ struct compiling *c;
+ node *n; /* argument */
+ int inkeywords;
+{
+ node *m;
+ REQ(n, argument); /* [test '='] test; really [ keyword '='] keyword */
+ if (NCH(n) == 1) {
+ if (inkeywords) {
+ err_setstr(SyntaxError,
+ "non-keyword arg after keyword arg");
+ c->c_errors++;
+ }
+ else {
+ com_node(c, CHILD(n, 0));
+ }
+ return 0;
+ }
+ m = n;
+ do {
+ m = CHILD(m, 0);
+ } while (NCH(m) == 1);
+ if (TYPE(m) != NAME) {
+ err_setstr(SyntaxError, "keyword can't be an expression");
+ c->c_errors++;
+ }
+ else {
+ object *v = newstringobject(STR(m));
+ if (v == NULL)
+ c->c_errors++;
+ else {
+ com_addoparg(c, LOAD_CONST, com_addconst(c, v));
+ DECREF(v);
+ }
+ }
+ com_node(c, CHILD(n, 2));
+ return 1;
+}
+
static void
com_call_function(c, n)
struct compiling *c;
- node *n; /* EITHER testlist OR ')' */
+ node *n; /* EITHER arglist OR ')' */
{
if (TYPE(n) == RPAR) {
- com_addoparg(c, BUILD_TUPLE, 0);
- com_addbyte(c, BINARY_CALL);
+ com_addoparg(c, CALL_FUNCTION, 0);
}
else {
- REQ(n, testlist);
- com_list(c, n, 1);
- com_addbyte(c, BINARY_CALL);
+ int inkeywords, i, na, nk;
+ REQ(n, arglist);
+ inkeywords = 0;
+ na = 0;
+ nk = 0;
+ for (i = 0; i < NCH(n); i += 2) {
+ inkeywords = com_argument(c, CHILD(n, i), inkeywords);
+ if (!inkeywords)
+ na++;
+ else
+ nk++;
+ }
+ if (na > 255 || nk > 255) {
+ err_setstr(SyntaxError, "more than 255 arguments");
+ c->c_errors++;
+ }
+ com_addoparg(c, CALL_FUNCTION, na | (nk << 8));
}
}
@@ -1482,13 +1535,18 @@ com_raise_stmt(c, n)
struct compiling *c;
node *n;
{
- REQ(n, raise_stmt); /* 'raise' test [',' test] */
+ REQ(n, raise_stmt); /* 'raise' test [',' test [',' test]] */
com_node(c, CHILD(n, 1));
if (NCH(n) > 3)
com_node(c, CHILD(n, 3));
else
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
- com_addbyte(c, RAISE_EXCEPTION);
+ if (NCH(n) > 5) {
+ com_node(c, CHILD(n, 5));
+ com_addoparg(c, RAISE_VARARGS, 3);
+ }
+ else
+ com_addbyte(c, RAISE_EXCEPTION);
}
static void
@@ -1980,19 +2038,16 @@ com_argdefs(c, n, argcount_return)
if (TYPE(n) != varargslist)
return -1;
/* varargslist:
- (fpdef ['=' test] ',')* '*' NAME |
+ (fpdef ['=' test] ',')* '*' NAME ....... |
fpdef ['=' test] (',' fpdef ['=' test])* [','] */
nch = NCH(n);
- if (nch >= 2 && TYPE(CHILD(n, nch-2)) == STAR) {
- star = 1;
- nch -= 2;
- }
- else
- star = 0;
nargs = 0;
ndefs = 0;
+ star = 0;
for (i = 0; i < nch; i++) {
int t;
+ if (TYPE(CHILD(n, i)) == STAR)
+ break;
nargs++;
i++;
if (i >= nch)
@@ -2285,17 +2340,18 @@ com_arglist(c, n)
int nch, op, nargs, i, t;
REQ(n, varargslist);
/* varargslist:
- (fpdef ['=' test] ',')* '*' NAME |
+ (fpdef ['=' test] ',')* '*' NAME ..... |
fpdef ['=' test] (',' fpdef ['=' test])* [','] */
nch = NCH(n);
- if (nch >= 2 && TYPE(CHILD(n, nch-2)) == STAR) {
- op = UNPACK_VARARG;
- nch -= 2;
- }
- else
- op = UNPACK_ARG;
+ op = UNPACK_ARG;
nargs = 0;
for (i = 0; i < nch; i++) {
+ if (TYPE(CHILD(n, i)) == STAR) {
+ nch = i;
+ if (TYPE(CHILD(n, i+1)) != STAR)
+ op = UNPACK_VARARG;
+ break;
+ }
nargs++;
i++;
if (i >= nch)