cinap_lenrekadd hg and python4bb9e2215 years agoHistory
3292 lines · 89.5 KB · C
RawDownload
    if (!listcomps)    	return NULL;     ch = CHILD(n, 1);    for (i = 0; i < n_fors; i++) {	comprehension_ty lc;	asdl_seq *t;        expr_ty expression;        node *for_ch; 	REQ(ch, list_for);         for_ch = CHILD(ch, 1);        t = ast_for_exprlist(c, for_ch, Store);        if (!t)            return NULL;        expression = ast_for_testlist(c, CHILD(ch, 3));        if (!expression)            return NULL;         /* Check the # of children rather than the length of t, since           [x for x, in ... ] has 1 element in t, but still requires a Tuple. */	if (NCH(for_ch) == 1)	    lc = comprehension((expr_ty)asdl_seq_GET(t, 0), expression, NULL,                               c->c_arena);	else	    lc = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,                                     c->c_arena),                               expression, NULL, c->c_arena);        if (!lc)            return NULL; 	if (NCH(ch) == 5) {	    int j, n_ifs;	    asdl_seq *ifs;	    expr_ty list_for_expr; 	    ch = CHILD(ch, 4);	    n_ifs = count_list_ifs(ch);            if (n_ifs == -1)                return NULL; 	    ifs = asdl_seq_new(n_ifs, c->c_arena);	    if (!ifs)		return NULL; 	    for (j = 0; j < n_ifs; j++) {            REQ(ch, list_iter);		    ch = CHILD(ch, 0);		    REQ(ch, list_if);            		    list_for_expr = ast_for_expr(c, CHILD(ch, 1));		    if (!list_for_expr)		        return NULL;     		asdl_seq_SET(ifs, j, list_for_expr);    		if (NCH(ch) == 3)	    	    ch = CHILD(ch, 2);	        }	        /* on exit, must guarantee that ch is a list_for */	        if (TYPE(ch) == list_iter)		        ch = CHILD(ch, 0);            lc->ifs = ifs;	    }	    asdl_seq_SET(listcomps, i, lc);    }     return ListComp(elt, listcomps, LINENO(n), n->n_col_offset, c->c_arena);} /*   Count the number of 'for' loops in a generator expression.    Helper for ast_for_genexp().*/ static intcount_gen_fors(const node *n){	int n_fors = 0;	node *ch = CHILD(n, 1);  count_gen_for:	n_fors++;	REQ(ch, gen_for);	if (NCH(ch) == 5)		ch = CHILD(ch, 4);	else		return n_fors; count_gen_iter:	REQ(ch, gen_iter);	ch = CHILD(ch, 0);	if (TYPE(ch) == gen_for)		goto count_gen_for;	else if (TYPE(ch) == gen_if) {		if (NCH(ch) == 3) {			ch = CHILD(ch, 2);			goto count_gen_iter;		}		else		    return n_fors;	} 	/* Should never be reached */	PyErr_SetString(PyExc_SystemError,			"logic error in count_gen_fors");	return -1;} /* Count the number of 'if' statements in a generator expression.    Helper for ast_for_genexp().*/ static intcount_gen_ifs(const node *n){	int n_ifs = 0; 	while (1) {		REQ(n, gen_iter);		if (TYPE(CHILD(n, 0)) == gen_for)			return n_ifs;		n = CHILD(n, 0);		REQ(n, gen_if);		n_ifs++;		if (NCH(n) == 2)			return n_ifs;		n = CHILD(n, 2);	}} /* TODO(jhylton): Combine with list comprehension code? */static expr_tyast_for_genexp(struct compiling *c, const node *n){    /* testlist_gexp: test ( gen_for | (',' test)* [','] )       argument: [test '='] test [gen_for]	 # Really [keyword '='] test */    expr_ty elt;    asdl_seq *genexps;    int i, n_fors;    node *ch;        assert(TYPE(n) == (testlist_gexp) || TYPE(n) == (argument));    assert(NCH(n) > 1);        elt = ast_for_expr(c, CHILD(n, 0));    if (!elt)        return NULL;        n_fors = count_gen_fors(n);    if (n_fors == -1)        return NULL;     genexps = asdl_seq_new(n_fors, c->c_arena);    if (!genexps)        return NULL;     ch = CHILD(n, 1);    for (i = 0; i < n_fors; i++) {        comprehension_ty ge;        asdl_seq *t;        expr_ty expression;        node *for_ch;                REQ(ch, gen_for);                for_ch = CHILD(ch, 1);        t = ast_for_exprlist(c, for_ch, Store);        if (!t)            return NULL;        expression = ast_for_expr(c, CHILD(ch, 3));        if (!expression)            return NULL;         /* Check the # of children rather than the length of t, since           (x for x, in ...) has 1 element in t, but still requires a Tuple. */        if (NCH(for_ch) == 1)            ge = comprehension((expr_ty)asdl_seq_GET(t, 0), expression,                               NULL, c->c_arena);        else            ge = comprehension(Tuple(t, Store, LINENO(ch), ch->n_col_offset,                                     c->c_arena),                               expression, NULL, c->c_arena);         if (!ge)            return NULL;         if (NCH(ch) == 5) {            int j, n_ifs;            asdl_seq *ifs;                        ch = CHILD(ch, 4);            n_ifs = count_gen_ifs(ch);            if (n_ifs == -1)                return NULL;             ifs = asdl_seq_new(n_ifs, c->c_arena);            if (!ifs)                return NULL;             for (j = 0; j < n_ifs; j++) {                REQ(ch, gen_iter);                ch = CHILD(ch, 0);                REQ(ch, gen_if);                                expression = ast_for_expr(c, CHILD(ch, 1));                if (!expression)                    return NULL;                asdl_seq_SET(ifs, j, expression);                if (NCH(ch) == 3)                    ch = CHILD(ch, 2);            }            /* on exit, must guarantee that ch is a gen_for */            if (TYPE(ch) == gen_iter)                ch = CHILD(ch, 0);            ge->ifs = ifs;        }        asdl_seq_SET(genexps, i, ge);    }        return GeneratorExp(elt, genexps, LINENO(n), n->n_col_offset, c->c_arena);} static expr_tyast_for_atom(struct compiling *c, const node *n){    /* atom: '(' [yield_expr|testlist_gexp] ')' | '[' [listmaker] ']'       | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING+    */    node *ch = CHILD(n, 0);        switch (TYPE(ch)) {    case NAME:	/* All names start in Load context, but may later be	   changed. */	return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), n->n_col_offset, c->c_arena);    case STRING: {	PyObject *str = parsestrplus(c, n);	if (!str)	    return NULL; 	PyArena_AddPyObject(c->c_arena, str);	return Str(str, LINENO(n), n->n_col_offset, c->c_arena);    }    case NUMBER: {	PyObject *pynum = parsenumber(STR(ch));	if (!pynum)	    return NULL; 	PyArena_AddPyObject(c->c_arena, pynum);	return Num(pynum, LINENO(n), n->n_col_offset, c->c_arena);    }    case LPAR: /* some parenthesized expressions */	ch = CHILD(n, 1);		if (TYPE(ch) == RPAR)	    return Tuple(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);		if (TYPE(ch) == yield_expr)	    return ast_for_expr(c, ch);		if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == gen_for))	    return ast_for_genexp(c, ch);		return ast_for_testlist_gexp(c, ch);    case LSQB: /* list (or list comprehension) */	ch = CHILD(n, 1);		if (TYPE(ch) == RSQB)	    return List(NULL, Load, LINENO(n), n->n_col_offset, c->c_arena);		REQ(ch, listmaker);	if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {	    asdl_seq *elts = seq_for_testlist(c, ch);	    if (!elts)		return NULL; 	    return List(elts, Load, LINENO(n), n->n_col_offset, c->c_arena);	}	else	    return ast_for_listcomp(c, ch);    case LBRACE: {	/* dictmaker: test ':' test (',' test ':' test)* [','] */	int i, size;	asdl_seq *keys, *values;		ch = CHILD(n, 1);	size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */	keys = asdl_seq_new(size, c->c_arena);	if (!keys)	    return NULL;		values = asdl_seq_new(size, c->c_arena);	if (!values)	    return NULL;		for (i = 0; i < NCH(ch); i += 4) {	    expr_ty expression;	    	    expression = ast_for_expr(c, CHILD(ch, i));	    if (!expression)		return NULL; 	    asdl_seq_SET(keys, i / 4, expression); 	    expression = ast_for_expr(c, CHILD(ch, i + 2));	    if (!expression)		return NULL; 	    asdl_seq_SET(values, i / 4, expression);	}	return Dict(keys, values, LINENO(n), n->n_col_offset, c->c_arena);    }    case BACKQUOTE: { /* repr */	expr_ty expression = ast_for_testlist(c, CHILD(n, 1));	if (!expression)	    return NULL; 	return Repr(expression, LINENO(n), n->n_col_offset, c->c_arena);    }    default:	PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));	return NULL;    }} static slice_tyast_for_slice(struct compiling *c, const node *n){    node *ch;    expr_ty lower = NULL, upper = NULL, step = NULL;     REQ(n, subscript);     /*       subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]       sliceop: ':' [test]    */    ch = CHILD(n, 0);    if (TYPE(ch) == DOT)	return Ellipsis(c->c_arena);     if (NCH(n) == 1 && TYPE(ch) == test) {        /* 'step' variable hold no significance in terms of being used over           other vars */        step = ast_for_expr(c, ch);         if (!step)            return NULL;            	return Index(step, c->c_arena);    }     if (TYPE(ch) == test) {	lower = ast_for_expr(c, ch);        if (!lower)            return NULL;    }     /* If there's an upper bound it's in the second or third position. */    if (TYPE(ch) == COLON) {	if (NCH(n) > 1) {	    node *n2 = CHILD(n, 1); 	    if (TYPE(n2) == test) {		upper = ast_for_expr(c, n2);                if (!upper)                    return NULL;            }	}    } else if (NCH(n) > 2) {	node *n2 = CHILD(n, 2); 	if (TYPE(n2) == test) {	    upper = ast_for_expr(c, n2);            if (!upper)                return NULL;        }    }     ch = CHILD(n, NCH(n) - 1);    if (TYPE(ch) == sliceop) {        if (NCH(ch) == 1) {            /* No expression, so step is None */            ch = CHILD(ch, 0);            step = Name(new_identifier("None", c->c_arena), Load,                        LINENO(ch), ch->n_col_offset, c->c_arena);            if (!step)                return NULL;        } else {            ch = CHILD(ch, 1);            if (TYPE(ch) == test) {                step = ast_for_expr(c, ch);                if (!step)                    return NULL;            }        }    }     return Slice(lower, upper, step, c->c_arena);} static expr_tyast_for_binop(struct compiling *c, const node *n){	/* Must account for a sequence of expressions.	   How should A op B op C by represented?  	   BinOp(BinOp(A, op, B), op, C).	*/ 	int i, nops;	expr_ty expr1, expr2, result;        operator_ty newoperator;         expr1 = ast_for_expr(c, CHILD(n, 0));        if (!expr1)            return NULL;         expr2 = ast_for_expr(c, CHILD(n, 2));        if (!expr2)            return NULL;         newoperator = get_operator(CHILD(n, 1));        if (!newoperator)            return NULL; 	result = BinOp(expr1, newoperator, expr2, LINENO(n), n->n_col_offset,                       c->c_arena);	if (!result)            return NULL; 	nops = (NCH(n) - 1) / 2;	for (i = 1; i < nops; i++) {		expr_ty tmp_result, tmp;		const node* next_oper = CHILD(n, i * 2 + 1); 		newoperator = get_operator(next_oper);                if (!newoperator)                    return NULL;                 tmp = ast_for_expr(c, CHILD(n, i * 2 + 2));                if (!tmp)                    return NULL;                 tmp_result = BinOp(result, newoperator, tmp, 				   LINENO(next_oper), next_oper->n_col_offset,                                   c->c_arena);		if (!tmp) 			return NULL;		result = tmp_result;	}	return result;} static expr_tyast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr){    /* trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME        subscriptlist: subscript (',' subscript)* [',']       subscript: '.' '.' '.' | test | [test] ':' [test] [sliceop]     */    REQ(n, trailer);    if (TYPE(CHILD(n, 0)) == LPAR) {        if (NCH(n) == 2)            return Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n),                        n->n_col_offset, c->c_arena);        else            return ast_for_call(c, CHILD(n, 1), left_expr);    }    else if (TYPE(CHILD(n, 0)) == DOT ) {        return Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load,                         LINENO(n), n->n_col_offset, c->c_arena);    }    else {        REQ(CHILD(n, 0), LSQB);        REQ(CHILD(n, 2), RSQB);        n = CHILD(n, 1);        if (NCH(n) == 1) {            slice_ty slc = ast_for_slice(c, CHILD(n, 0));            if (!slc)                return NULL;            return Subscript(left_expr, slc, Load, LINENO(n), n->n_col_offset,                             c->c_arena);        }        else {            /* The grammar is ambiguous here. The ambiguity is resolved                by treating the sequence as a tuple literal if there are               no slice features.            */            int j;            slice_ty slc;            expr_ty e;            bool simple = true;            asdl_seq *slices, *elts;            slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);            if (!slices)                return NULL;            for (j = 0; j < NCH(n); j += 2) {                slc = ast_for_slice(c, CHILD(n, j));                if (!slc)

Lines 1001–1500 of 3292. Previous lines