summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1995-07-07 22:53:21 (GMT)
committerGuido van Rossum <guido@python.org>1995-07-07 22:53:21 (GMT)
commitf10570b9eb556b015a4a068377cf6cadf380a39d (patch)
tree8f09829510f76aabfed036e1229a8f2571594461 /Python
parent7faeab3103dd81d8e9cc7ff1d95d4909d6523032 (diff)
downloadcpython-f10570b9eb556b015a4a068377cf6cadf380a39d.zip
cpython-f10570b9eb556b015a4a068377cf6cadf380a39d.tar.gz
cpython-f10570b9eb556b015a4a068377cf6cadf380a39d.tar.bz2
3rd arg for raise; INCOMPLETE keyword parameter passing (currently f(kw=value) is seen as f('kw', value))
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c181
-rw-r--r--Python/compile.c100
2 files changed, 229 insertions, 52 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 3fa03c0..a55451c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -775,43 +775,88 @@ eval_code(co, globals, locals, owner, arg)
case BREAK_LOOP:
why = WHY_BREAK;
break;
-
+
case RAISE_EXCEPTION:
- v = POP();
- w = POP();
+ oparg = 2;
+ /* Fallthrough */
+ case RAISE_VARARGS:
+ u = v = w = NULL;
+ switch (oparg) {
+ case 3:
+ u = POP(); /* traceback */
+ if (u == None) {
+ DECREF(u);
+ u = NULL;
+ }
+ else if (strcmp(u->ob_type->tp_name,
+ "traceback") != 0) {
+ /* XXX traceback.h needs to define
+ is_traceback() */
+ err_setstr(TypeError,
+ "raise 3rd arg must be traceback or None");
+ goto raise_error;
+ }
+ /* Fallthrough */
+ case 2:
+ v = POP(); /* value */
+ /* Fallthrough */
+ case 1:
+ w = POP(); /* exc */
+ break;
+ default:
+ err_setstr(SystemError,
+ "bad RAISE_VARARGS oparg");
+ goto raise_error;
+ }
+ if (v == NULL) {
+ v = None;
+ INCREF(v);
+ }
/* A tuple is equivalent to its first element here */
while (is_tupleobject(w) && gettuplesize(w) > 0) {
- u = w;
- w = GETTUPLEITEM(u, 0);
+ object *t = w;
+ w = GETTUPLEITEM(t, 0);
INCREF(w);
- DECREF(u);
+ DECREF(t);
}
if (is_stringobject(w)) {
- err_setval(w, v);
+ ;
} else if (is_classobject(w)) {
if (!is_instanceobject(v)
|| !issubclass((object*)((instanceobject*)v)->in_class,
- w))
+ w)) {
err_setstr(TypeError,
"a class exception must have a value that is an instance of the class");
- else
- err_setval(w,v);
+ goto raise_error;
+ }
} else if (is_instanceobject(w)) {
- if (v != None)
+ if (v != None) {
err_setstr(TypeError,
"an instance exception may not have a separate value");
+ goto raise_error;
+ }
else {
DECREF(v);
v = w;
w = (object*) ((instanceobject*)w)->in_class;
INCREF(w);
- err_setval(w, v);
}
- } else
+ }
+ else {
err_setstr(TypeError,
"exceptions must be strings, classes, or instances");
- DECREF(v);
- DECREF(w);
+ goto raise_error;
+ }
+ err_restore(w, v, u);
+ if (u == NULL)
+ why = WHY_EXCEPTION;
+ else
+ why = WHY_RERAISE;
+ break;
+ raise_error:
+ XDECREF(v);
+ XDECREF(w);
+ XDECREF(u);
why = WHY_EXCEPTION;
break;
@@ -876,11 +921,8 @@ eval_code(co, globals, locals, owner, arg)
}
else if (is_stringobject(v) || is_classobject(v)) {
w = POP();
- err_setval(v, w);
- DECREF(w);
- w = POP();
- tb_store(w);
- DECREF(w);
+ u = POP();
+ err_restore(v, w, u);
why = WHY_RERAISE;
}
else if (v != None) {
@@ -1000,6 +1042,7 @@ eval_code(co, globals, locals, owner, arg)
err_setstr(TypeError,
"bad argument list");
why = WHY_EXCEPTION;
+ DECREF(v);
break;
}
n = gettuplesize(v);
@@ -1308,8 +1351,7 @@ eval_code(co, globals, locals, owner, arg)
}
x = call_object(x, w);
DECREF(w);
- if (x)
- PUSH(x);
+ PUSH(x);
break;
case IMPORT_FROM:
@@ -1402,6 +1444,85 @@ eval_code(co, globals, locals, owner, arg)
f, "line", None);
}
break;
+
+ case CALL_FUNCTION:
+ {
+ /* XXX To do:
+ - fill in default arguments here
+ - proper handling of keyword parameters
+ - change eval_code interface to take an
+ array of arguments instead of a tuple
+ */
+ int na = oparg & 0xff;
+ int nk = (oparg>>8) & 0xff;
+ int n = na + 2*nk;
+ object **pfunc = stack_pointer - n - 1;
+ object *func = *pfunc;
+ object *self = NULL;
+ object *class = NULL;
+ object *args;
+ f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
+ INCREF(func);
+ if (is_instancemethodobject(func)) {
+ self = instancemethodgetself(func);
+ if (self != NULL) {
+ class = instancemethodgetclass(func);
+ DECREF(func);
+ func = instancemethodgetfunc(func);
+ INCREF(func);
+ INCREF(self);
+ DECREF(*pfunc);
+ *pfunc = self;
+ na++;
+ n++;
+ }
+ }
+ args = newtupleobject(n);
+ if (args == NULL)
+ x = NULL;
+ else {
+ while (--n >= 0) {
+ w = POP();
+ SETTUPLEITEM(args, n, w);
+ }
+ if (self == NULL)
+ POP();
+ if (is_funcobject(func)) {
+ int argcount;
+ object *argdefs =
+ getfuncargstuff(func, &argcount);
+ if (argdefs == NULL) { /* Fast path */
+ object *co, *loc, *glob;
+ co = getfunccode(func);
+ loc = newdictobject();
+ if (loc == NULL) {
+ x = NULL;
+ DECREF(func);
+ break;
+ }
+ glob = getfuncglobals(func);
+ INCREF(glob);
+ x = eval_code(
+ (codeobject *)co,
+ glob,
+ loc,
+ class,
+ args);
+ DECREF(glob);
+ DECREF(loc);
+ DECREF(args);
+ DECREF(func);
+ PUSH(x);
+ break;
+ }
+ }
+ x = call_object(func, args);
+ DECREF(args);
+ PUSH(x);
+ }
+ DECREF(func);
+ break;
+ }
default:
fprintf(stderr,
@@ -1613,7 +1734,7 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
char *msg;
object *arg;
{
- object *arglist, *what;
+ object *args, *what;
object *res = NULL;
static int tracing = 0;
@@ -1626,26 +1747,26 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
return 0;
}
- arglist = newtupleobject(3);
- if (arglist == NULL)
+ args = newtupleobject(3);
+ if (args == NULL)
goto cleanup;
what = newstringobject(msg);
if (what == NULL)
goto cleanup;
INCREF(f);
- SETTUPLEITEM(arglist, 0, (object *)f);
- SETTUPLEITEM(arglist, 1, what);
+ SETTUPLEITEM(args, 0, (object *)f);
+ SETTUPLEITEM(args, 1, what);
if (arg == NULL)
arg = None;
INCREF(arg);
- SETTUPLEITEM(arglist, 2, arg);
+ SETTUPLEITEM(args, 2, arg);
tracing++;
fast_2_locals(f);
- res = call_object(*p_trace, arglist); /* May clear *p_trace! */
+ res = call_object(*p_trace, args); /* May clear *p_trace! */
locals_2_fast(f, 1);
tracing--;
cleanup:
- XDECREF(arglist);
+ XDECREF(args);
if (res == NULL) {
/* The trace proc raised an exception */
tb_here(f);
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)