Skip to content

Commit

Permalink
AST-reflecting approach
Browse files Browse the repository at this point in the history
  • Loading branch information
thatbirdguythatuknownot committed Oct 30, 2023
1 parent ec72c74 commit 661af74
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 31 deletions.
4 changes: 2 additions & 2 deletions Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -1075,13 +1075,13 @@ starred_expression[expr_ty]:
kwarg_or_starred[KeywordOrStarred*]:
| invalid_kwarg
| a=NAME '=' b=expression? {
_PyPegen_keyword_or_starred(p, CHECK(keyword_ty, _PyAST_keyword(a->v.Name.id, b ? b : a, EXTRA)), 1) }
_PyPegen_keyword_or_starred(p, CHECK(keyword_ty, _PyAST_keyword(a->v.Name.id, b, EXTRA)), 1) }
| a=starred_expression { _PyPegen_keyword_or_starred(p, a, 0) }

kwarg_or_double_starred[KeywordOrStarred*]:
| invalid_kwarg
| a=NAME '=' b=expression? {
_PyPegen_keyword_or_starred(p, CHECK(keyword_ty, _PyAST_keyword(a->v.Name.id, b ? b : a, EXTRA)), 1) }
_PyPegen_keyword_or_starred(p, CHECK(keyword_ty, _PyAST_keyword(a->v.Name.id, b, EXTRA)), 1) }
| '**' a=expression { _PyPegen_keyword_or_starred(p, CHECK(keyword_ty, _PyAST_keyword(NULL, a, EXTRA)), 1) }

# ASSIGNMENT TARGETS
Expand Down
2 changes: 1 addition & 1 deletion Parser/Python.asdl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ module Python
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)

-- keyword arguments supplied to call (NULL identifier for **kwargs)
keyword = (identifier? arg, expr value)
keyword = (identifier? arg, expr? value)
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)

-- import name with optional 'as' alias.
Expand Down
4 changes: 2 additions & 2 deletions Parser/parser.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 6 additions & 9 deletions Python/Python-ast.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Python/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ static int
validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
{
assert(!PyErr_Occurred());
for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++)
if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++) {
keyword_ty k = asdl_seq_GET(keywords, i);
if (k->value && !validate_expr(state, k->value, Load))
return 0;
}
return 1;
}

Expand Down
2 changes: 1 addition & 1 deletion Python/ast_opt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1169,7 +1169,7 @@ astfold_expr(expr_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
static int
astfold_keyword(keyword_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
{
CALL(astfold_expr, expr_ty, node_->value);
CALL_OPT(astfold_expr, expr_ty, node_->value);
return 1;
}

Expand Down
22 changes: 19 additions & 3 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5237,7 +5237,12 @@ compiler_subkwargs(struct compiler *c, location loc,
if (n > 1 && !big) {
for (i = begin; i < end; i++) {
kw = asdl_seq_GET(keywords, i);
VISIT(c, expr, kw->value);
if (kw->value) {
VISIT(c, expr, kw->value);
}
else {
RETURN_IF_ERROR(compiler_nameop(c, loc, kw->arg, Load));
}
}
keys = PyTuple_New(n);
if (keys == NULL) {
Expand All @@ -5257,7 +5262,12 @@ compiler_subkwargs(struct compiler *c, location loc,
for (i = begin; i < end; i++) {
kw = asdl_seq_GET(keywords, i);
ADDOP_LOAD_CONST(c, loc, kw->arg);
VISIT(c, expr, kw->value);
if (kw->value) {
VISIT(c, expr, kw->value);
}
else {
RETURN_IF_ERROR(compiler_nameop(c, loc, kw->arg, Load));
}
if (big) {
ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
}
Expand Down Expand Up @@ -5370,6 +5380,7 @@ compiler_call_helper(struct compiler *c, location loc,
ADDOP_I(c, loc, BUILD_MAP, 0);
have_dict = 1;
}
assert(kw->value);
VISIT(c, expr, kw->value);
ADDOP_I(c, loc, DICT_MERGE, 1);
}
Expand Down Expand Up @@ -6018,7 +6029,12 @@ compiler_dictcomp(struct compiler *c, expr_ty e)
static int
compiler_visit_keyword(struct compiler *c, keyword_ty k)
{
VISIT(c, expr, k->value);
if (k->value) {
VISIT(c, expr, k->value);
}
else {
RETURN_IF_ERROR(compiler_nameop(c, LOC(k), k->arg, Load));
}
return SUCCESS;
}

Expand Down
38 changes: 27 additions & 11 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,26 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e)
return 1;
}

static int
symtable_name(struct symtable *st, identifier name, expr_context_ty ctx,
int lineno, int col_offset, int end_lineno, int end_col_offset)
{
if (!symtable_add_def(st, name,
ctx == Load ? USE : DEF_LOCAL,
lineno, col_offset, end_lineno, end_col_offset))
return 0;
/* Special-case super: it counts as a use of __class__ */
if (ctx == Load &&
_PyST_IsFunctionLike(st->st_cur) &&
_PyUnicode_EqualToASCIIString(name, "super")) {
if (!symtable_add_def(st, &_Py_ID(__class__), USE,
lineno, col_offset,
end_lineno, end_col_offset))
return 0;
}
return 1;
}

static int
symtable_visit_expr(struct symtable *st, expr_ty e)
{
Expand Down Expand Up @@ -2089,16 +2109,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
VISIT(st, expr, e->v.Slice.step)
break;
case Name_kind:
if (!symtable_add_def(st, e->v.Name.id,
e->v.Name.ctx == Load ? USE : DEF_LOCAL, LOCATION(e)))
if (!symtable_name(st, e->v.Name.id, e->v.Name.ctx, LOCATION(e)))
VISIT_QUIT(st, 0);
/* Special-case super: it counts as a use of __class__ */
if (e->v.Name.ctx == Load &&
_PyST_IsFunctionLike(st->st_cur) &&
_PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e)))
VISIT_QUIT(st, 0);
}
break;
/* child nodes of List and Tuple will have expr_context set */
case List_kind:
Expand Down Expand Up @@ -2423,8 +2435,12 @@ symtable_visit_comprehension(struct symtable *st, comprehension_ty lc)
static int
symtable_visit_keyword(struct symtable *st, keyword_ty k)
{
VISIT(st, expr, k->value);
return 1;
if (k->value) {
VISIT(st, expr, k->value);
return 1;
}

return symtable_name(st, k->arg, Load, LOCATION(k));
}


Expand Down

0 comments on commit 661af74

Please sign in to comment.