mirror of https://github.com/python/cpython
* import.c (get_module): pass .py filename to parse_file, not .pyc filename!
* funcobject.c (func_repr): don't call getstringvalue(None) for anonymous functions. * bltinmodule.c: removed lambda (which is now a built-in function); removed implied lambda for string arg to filter/map/reduce. * Grammar, graminit.[ch], compile.[ch]: replaced lambda as built-in function by lambda as grammar entity: instead of "lambda('x: x+1')" you write "lambda x: x+1". * Xtmodule.c (checkargdict): return 0, not NULL, for error.
This commit is contained in:
parent
8732d6aeea
commit
590baa4a7a
|
@ -2,6 +2,9 @@
|
|||
|
||||
# Change log:
|
||||
|
||||
# 30-Nov-93:
|
||||
# Removed lambda_input, added lambdef
|
||||
|
||||
# 25-Oct-93:
|
||||
# Added lambda_input
|
||||
|
||||
|
@ -77,14 +80,12 @@
|
|||
# Start symbols for the grammar:
|
||||
# single_input is a single interactive statement;
|
||||
# file_input is a module or sequence of commands read from an input file;
|
||||
# eval_input is the input for the eval() and input() functions;
|
||||
# lambda_input is the input for the proposed lambda() function.
|
||||
# eval_input is the input for the eval() and input() functions.
|
||||
|
||||
# NB: compound_stmt in single_input is followed by extra NEWLINE!
|
||||
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
|
||||
file_input: (NEWLINE | stmt)* ENDMARKER
|
||||
eval_input: testlist NEWLINE* ENDMARKER
|
||||
lambda_input: varargslist ':' testlist NEWLINE* ENDMARKER
|
||||
|
||||
funcdef: 'def' NAME parameters ':' suite
|
||||
parameters: '(' [varargslist] ')'
|
||||
|
@ -134,7 +135,10 @@ shift_expr: arith_expr (('<<'|'>>') arith_expr)*
|
|||
arith_expr: term (('+'|'-') term)*
|
||||
term: factor (('*'|'/'|'%') factor)*
|
||||
factor: ('+'|'-'|'~') factor | atom trailer*
|
||||
atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING
|
||||
atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | lambdef | NAME | NUMBER | STRING
|
||||
# Note ambiguity in grammar: "lambda x: x[1]" could mean "(lambda x: x)[1]"
|
||||
# but the parser is eager so interprets it as "lambda x: (x[1])"...
|
||||
lambdef: 'lambda' [varargslist] ':' test
|
||||
trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME
|
||||
subscript: test | [test] ':' [test]
|
||||
exprlist: expr (',' expr)* [',']
|
||||
|
|
|
@ -54,12 +54,10 @@ extern typeobject Codetype;
|
|||
|
||||
/* Public interface */
|
||||
struct _node; /* Declare the existence of this type */
|
||||
codeobject *_compile PROTO((struct _node *, char *, int));
|
||||
codeobject *compile PROTO((struct _node *, char *));
|
||||
codeobject *newcodeobject
|
||||
PROTO((object *, object *, object *, object *, object *));
|
||||
|
||||
#define compile(n,f) (_compile((n),(f),0))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,49 +1,49 @@
|
|||
#define single_input 256
|
||||
#define file_input 257
|
||||
#define eval_input 258
|
||||
#define lambda_input 259
|
||||
#define funcdef 260
|
||||
#define parameters 261
|
||||
#define varargslist 262
|
||||
#define fpdef 263
|
||||
#define fplist 264
|
||||
#define stmt 265
|
||||
#define simple_stmt 266
|
||||
#define small_stmt 267
|
||||
#define expr_stmt 268
|
||||
#define print_stmt 269
|
||||
#define del_stmt 270
|
||||
#define pass_stmt 271
|
||||
#define flow_stmt 272
|
||||
#define break_stmt 273
|
||||
#define continue_stmt 274
|
||||
#define return_stmt 275
|
||||
#define raise_stmt 276
|
||||
#define import_stmt 277
|
||||
#define global_stmt 278
|
||||
#define access_stmt 279
|
||||
#define accesstype 280
|
||||
#define exec_stmt 281
|
||||
#define compound_stmt 282
|
||||
#define if_stmt 283
|
||||
#define while_stmt 284
|
||||
#define for_stmt 285
|
||||
#define try_stmt 286
|
||||
#define except_clause 287
|
||||
#define suite 288
|
||||
#define test 289
|
||||
#define and_test 290
|
||||
#define not_test 291
|
||||
#define comparison 292
|
||||
#define comp_op 293
|
||||
#define expr 294
|
||||
#define xor_expr 295
|
||||
#define and_expr 296
|
||||
#define shift_expr 297
|
||||
#define arith_expr 298
|
||||
#define term 299
|
||||
#define factor 300
|
||||
#define atom 301
|
||||
#define funcdef 259
|
||||
#define parameters 260
|
||||
#define varargslist 261
|
||||
#define fpdef 262
|
||||
#define fplist 263
|
||||
#define stmt 264
|
||||
#define simple_stmt 265
|
||||
#define small_stmt 266
|
||||
#define expr_stmt 267
|
||||
#define print_stmt 268
|
||||
#define del_stmt 269
|
||||
#define pass_stmt 270
|
||||
#define flow_stmt 271
|
||||
#define break_stmt 272
|
||||
#define continue_stmt 273
|
||||
#define return_stmt 274
|
||||
#define raise_stmt 275
|
||||
#define import_stmt 276
|
||||
#define global_stmt 277
|
||||
#define access_stmt 278
|
||||
#define accesstype 279
|
||||
#define exec_stmt 280
|
||||
#define compound_stmt 281
|
||||
#define if_stmt 282
|
||||
#define while_stmt 283
|
||||
#define for_stmt 284
|
||||
#define try_stmt 285
|
||||
#define except_clause 286
|
||||
#define suite 287
|
||||
#define test 288
|
||||
#define and_test 289
|
||||
#define not_test 290
|
||||
#define comparison 291
|
||||
#define comp_op 292
|
||||
#define expr 293
|
||||
#define xor_expr 294
|
||||
#define and_expr 295
|
||||
#define shift_expr 296
|
||||
#define arith_expr 297
|
||||
#define term 298
|
||||
#define factor 299
|
||||
#define atom 300
|
||||
#define lambdef 301
|
||||
#define trailer 302
|
||||
#define subscript 303
|
||||
#define exprlist 304
|
||||
|
|
|
@ -100,9 +100,12 @@ func_repr(op)
|
|||
funcobject *op;
|
||||
{
|
||||
char buf[140];
|
||||
sprintf(buf, "<function %.100s at %lx>",
|
||||
getstringvalue(op->func_name),
|
||||
(long)op);
|
||||
if (op->func_name == None)
|
||||
sprintf(buf, "<anonymous function at %lx>", (long)op);
|
||||
else
|
||||
sprintf(buf, "<function %.100s at %lx>",
|
||||
getstringvalue(op->func_name),
|
||||
(long)op);
|
||||
return newstringobject(buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,23 +79,13 @@ builtin_filter(self, args)
|
|||
if (!getargs(args, "(OO)", &func, &seq))
|
||||
return NULL;
|
||||
|
||||
if (is_stringobject(func)) {
|
||||
if ((func = exec_eval(func, lambda_input)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
INCREF(func);
|
||||
}
|
||||
|
||||
if (is_stringobject(seq)) {
|
||||
object *r = filterstring(func, seq);
|
||||
DECREF(func);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (is_tupleobject(seq)) {
|
||||
object *r = filtertuple(func, seq);
|
||||
DECREF(func);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -150,13 +140,11 @@ builtin_filter(self, args)
|
|||
if (setlistslice(result, j, len, NULL) < 0)
|
||||
goto Fail_1;
|
||||
|
||||
DECREF(func);
|
||||
return result;
|
||||
|
||||
Fail_1:
|
||||
DECREF(result);
|
||||
Fail_2:
|
||||
DECREF(func);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -306,10 +294,10 @@ exec_eval(v, start)
|
|||
globals != NULL && !is_dictobject(globals) ||
|
||||
locals != NULL && !is_dictobject(locals)) {
|
||||
err_setstr(TypeError,
|
||||
"eval/lambda arguments must be (string|code)[,dict[,dict]]");
|
||||
"eval arguments must be (string|code)[,dict[,dict]]");
|
||||
return NULL;
|
||||
}
|
||||
/* XXX The following is only correct for eval(), not for lambda() */
|
||||
|
||||
if (is_codeobject(str))
|
||||
return eval_code((codeobject *) str, globals, locals,
|
||||
(object *)NULL, (object *)NULL);
|
||||
|
@ -318,7 +306,7 @@ exec_eval(v, start)
|
|||
err_setstr(ValueError, "embedded '\\0' in string arg");
|
||||
return NULL;
|
||||
}
|
||||
if (start == eval_input || start == lambda_input) {
|
||||
if (start == eval_input) {
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
}
|
||||
|
@ -460,14 +448,6 @@ builtin_map(self, args)
|
|||
func = gettupleitem(args, 0);
|
||||
n = gettuplesize(args) - 1;
|
||||
|
||||
if (is_stringobject(func)) {
|
||||
if ((func = exec_eval(func, lambda_input)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
INCREF(func);
|
||||
}
|
||||
|
||||
if ((seqs = NEW(sequence, n)) == NULL) {
|
||||
err_nomem();
|
||||
goto Fail_2;
|
||||
|
@ -549,13 +529,11 @@ builtin_map(self, args)
|
|||
}
|
||||
|
||||
if (seqs) DEL(seqs);
|
||||
DECREF(func);
|
||||
return result;
|
||||
|
||||
Fail_1:
|
||||
DECREF(result);
|
||||
Fail_2:
|
||||
DECREF(func);
|
||||
if (seqs) DEL(seqs);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -638,14 +616,6 @@ builtin_int(self, v)
|
|||
return (*nb->nb_int)(v);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_lambda(self, v)
|
||||
object *self;
|
||||
object *v;
|
||||
{
|
||||
return exec_eval(v, lambda_input);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_len(self, v)
|
||||
object *self;
|
||||
|
@ -977,14 +947,6 @@ builtin_reduce(self, args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (is_stringobject(func)) {
|
||||
if ((func = exec_eval(func, lambda_input)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
INCREF(func);
|
||||
}
|
||||
|
||||
if ((len = (*sqf->sq_length)(seq)) < 0)
|
||||
goto Fail_2;
|
||||
|
||||
|
@ -1025,7 +987,6 @@ builtin_reduce(self, args)
|
|||
}
|
||||
|
||||
DECREF(args);
|
||||
DECREF(func);
|
||||
|
||||
return result;
|
||||
|
||||
|
@ -1035,7 +996,6 @@ Fail_0:
|
|||
Fail_1:
|
||||
DECREF(result);
|
||||
Fail_2:
|
||||
DECREF(func);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1093,6 @@ static struct methodlist builtin_methods[] = {
|
|||
{"id", builtin_id},
|
||||
{"input", builtin_input},
|
||||
{"int", builtin_int},
|
||||
{"lambda", builtin_lambda},
|
||||
{"len", builtin_len},
|
||||
{"long", builtin_long},
|
||||
{"map", builtin_map},
|
||||
|
|
|
@ -153,7 +153,7 @@ newcodeobject(code, consts, names, filename, name)
|
|||
if (code == NULL || !is_stringobject(code) ||
|
||||
consts == NULL || !is_listobject(consts) ||
|
||||
names == NULL || !is_listobject(names) ||
|
||||
name == NULL || !is_stringobject(name)) {
|
||||
name == NULL || !(is_stringobject(name) || name == None)) {
|
||||
err_badcall();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -194,7 +194,6 @@ struct compiling {
|
|||
int c_nexti; /* index into c_code */
|
||||
int c_errors; /* counts errors occurred */
|
||||
int c_infunction; /* set when compiling a function */
|
||||
int c_inlambda; /* set when compiling an expression */
|
||||
int c_loops; /* counts nested loops */
|
||||
int c_begin; /* begin of current loop, for 'continue' */
|
||||
int c_block[MAXBLOCKS]; /* stack of block types */
|
||||
|
@ -236,7 +235,7 @@ block_pop(c, type)
|
|||
|
||||
/* Prototypes */
|
||||
|
||||
static int com_init PROTO((struct compiling *, char *, int));
|
||||
static int com_init PROTO((struct compiling *, char *));
|
||||
static void com_free PROTO((struct compiling *));
|
||||
static void com_done PROTO((struct compiling *));
|
||||
static void com_node PROTO((struct compiling *, struct _node *));
|
||||
|
@ -252,10 +251,9 @@ static void com_addopname PROTO((struct compiling *, int, node *));
|
|||
static void com_list PROTO((struct compiling *, node *, int));
|
||||
|
||||
static int
|
||||
com_init(c, filename, inlambda)
|
||||
com_init(c, filename)
|
||||
struct compiling *c;
|
||||
char *filename;
|
||||
int inlambda;
|
||||
{
|
||||
if ((c->c_code = newsizedstringobject((char *)NULL, 1000)) == NULL)
|
||||
goto fail_3;
|
||||
|
@ -268,7 +266,6 @@ com_init(c, filename, inlambda)
|
|||
c->c_nexti = 0;
|
||||
c->c_errors = 0;
|
||||
c->c_infunction = 0;
|
||||
c->c_inlambda = inlambda;
|
||||
c->c_loops = 0;
|
||||
c->c_begin = 0;
|
||||
c->c_nblocks = 0;
|
||||
|
@ -662,6 +659,18 @@ com_atom(c, n)
|
|||
}
|
||||
com_addoparg(c, LOAD_CONST, i);
|
||||
break;
|
||||
case lambdef:
|
||||
if ((v = (object *) compile(ch, c->c_filename)) == NULL) {
|
||||
c->c_errors++;
|
||||
i = 255;
|
||||
}
|
||||
else {
|
||||
i = com_addconst(c, v);
|
||||
DECREF(v);
|
||||
}
|
||||
com_addoparg(c, LOAD_CONST, i);
|
||||
com_addbyte(c, BUILD_FUNCTION);
|
||||
break;
|
||||
case NAME:
|
||||
com_addopname(c, LOAD_NAME, ch);
|
||||
break;
|
||||
|
@ -1825,7 +1834,7 @@ com_funcdef(c, n)
|
|||
{
|
||||
object *v;
|
||||
REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
|
||||
v = (object *)_compile(n, c->c_filename, 0);
|
||||
v = (object *)compile(n, c->c_filename);
|
||||
if (v == NULL)
|
||||
c->c_errors++;
|
||||
else {
|
||||
|
@ -1837,25 +1846,6 @@ com_funcdef(c, n)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
com_lambda(c, n)
|
||||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
object *v;
|
||||
REQ(n, lambda_input);
|
||||
v = (object *)_compile(n, c->c_filename, 1);
|
||||
if (v == NULL)
|
||||
c->c_errors++;
|
||||
else {
|
||||
int i = com_addconst(c, v);
|
||||
DECREF(v);
|
||||
com_addoparg(c, LOAD_CONST, i);
|
||||
com_addbyte(c, BUILD_FUNCTION);
|
||||
com_addbyte(c, RETURN_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
com_bases(c, n)
|
||||
struct compiling *c;
|
||||
|
@ -1891,7 +1881,7 @@ com_classdef(c, n)
|
|||
com_addoparg(c, BUILD_TUPLE, 0);
|
||||
else
|
||||
com_bases(c, CHILD(n, 3));
|
||||
v = (object *)_compile(n, c->c_filename, 0);
|
||||
v = (object *)compile(n, c->c_filename);
|
||||
if (v == NULL)
|
||||
c->c_errors++;
|
||||
else {
|
||||
|
@ -2149,13 +2139,25 @@ compile_funcdef(c, n)
|
|||
}
|
||||
|
||||
static void
|
||||
compile_lambda(c, n)
|
||||
compile_lambdef(c, n)
|
||||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
REQ(n, lambda_input)
|
||||
com_arglist(c, CHILD(n, 0));
|
||||
com_node(c, CHILD(n, 2));
|
||||
node *ch;
|
||||
REQ(n, lambdef); /* lambdef: 'lambda' [parameters] ':' test */
|
||||
c->c_name = NULL;
|
||||
|
||||
ch = CHILD(n, 1);
|
||||
if (TYPE(ch) == COLON) {
|
||||
com_addoparg(c, UNPACK_ARG, 0);
|
||||
com_node(c, CHILD(n, 2));
|
||||
}
|
||||
else {
|
||||
com_addoparg(c, RESERVE_FAST, com_addconst(c, None));
|
||||
com_arglist(c, ch);
|
||||
com_node(c, CHILD(n, 3));
|
||||
}
|
||||
|
||||
com_addbyte(c, RETURN_VALUE);
|
||||
}
|
||||
|
||||
|
@ -2183,15 +2185,15 @@ compile_node(c, n)
|
|||
com_addbyte(c, RETURN_VALUE);
|
||||
break;
|
||||
|
||||
case lambda_input: /* Built-in function lambda() */
|
||||
(c->c_inlambda ? compile_lambda : com_lambda)(c, n);
|
||||
break;
|
||||
|
||||
case eval_input: /* Built-in functions eval() and input() */
|
||||
case eval_input: /* Built-in function input() */
|
||||
com_node(c, CHILD(n, 0));
|
||||
com_addbyte(c, RETURN_VALUE);
|
||||
break;
|
||||
|
||||
case lambdef: /* anonymous function definition */
|
||||
compile_lambdef(c, n);
|
||||
break;
|
||||
|
||||
case funcdef: /* A function definition */
|
||||
compile_funcdef(c, n);
|
||||
break;
|
||||
|
@ -2347,24 +2349,28 @@ optimize(c)
|
|||
}
|
||||
|
||||
codeobject *
|
||||
_compile(n, filename, inlambda)
|
||||
compile(n, filename)
|
||||
node *n;
|
||||
char *filename;
|
||||
int inlambda;
|
||||
{
|
||||
struct compiling sc;
|
||||
codeobject *co;
|
||||
if (!com_init(&sc, filename, inlambda))
|
||||
if (!com_init(&sc, filename))
|
||||
return NULL;
|
||||
compile_node(&sc, n);
|
||||
com_done(&sc);
|
||||
if (TYPE(n) == funcdef && sc.c_errors == 0)
|
||||
if ((TYPE(n) == funcdef || TYPE(n) == lambdef) && sc.c_errors == 0)
|
||||
optimize(&sc);
|
||||
co = NULL;
|
||||
if (sc.c_errors == 0) {
|
||||
object *v, *w;
|
||||
v = newstringobject(sc.c_filename);
|
||||
w = newstringobject(sc.c_name);
|
||||
if (sc.c_name)
|
||||
w = newstringobject(sc.c_name);
|
||||
else {
|
||||
INCREF(None);
|
||||
w = None;
|
||||
}
|
||||
if (v != NULL && w != NULL)
|
||||
co = newcodeobject(sc.c_code, sc.c_consts,
|
||||
sc.c_names, v, w);
|
||||
|
|
1286
Python/graminit.c
1286
Python/graminit.c
File diff suppressed because it is too large
Load Diff
|
@ -174,7 +174,8 @@ get_module(m, name, m_ret)
|
|||
|
||||
case PY_SOURCE:
|
||||
mtime = getmtime(namebuf);
|
||||
strcat(namebuf, "c");
|
||||
len = strlen(namebuf);
|
||||
strcpy(namebuf + len, "c");
|
||||
fpc = fopen(namebuf, "rb");
|
||||
if (fpc != NULL) {
|
||||
magic = rd_long(fpc);
|
||||
|
@ -204,6 +205,7 @@ get_module(m, name, m_ret)
|
|||
}
|
||||
fclose(fpc);
|
||||
}
|
||||
namebuf[len] = '\0';
|
||||
err = parse_file(fp, namebuf, file_input, &n);
|
||||
if (err != E_DONE) {
|
||||
err_input(err);
|
||||
|
@ -215,9 +217,9 @@ get_module(m, name, m_ret)
|
|||
return NULL;
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"import %s # from %.*s\n",
|
||||
name, strlen(namebuf)-1, namebuf);
|
||||
"import %s # from %s\n", name, namebuf);
|
||||
/* Now write the code object to the ".pyc" file */
|
||||
strcpy(namebuf + len, "c");
|
||||
fpc = fopen(namebuf, "wb");
|
||||
if (fpc == NULL) {
|
||||
if (verbose)
|
||||
|
|
Loading…
Reference in New Issue