mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
some up
This commit is contained in:
parent
23b523b788
commit
0963929a30
@ -1047,7 +1047,7 @@ bool SubscrExpr__emit_del(Expr* self_, Ctx* ctx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SubscrExpr* SubscrExpr__new(int line, Expr* lhs, Expr* rhs) {
|
||||
SubscrExpr* SubscrExpr__new(int line) {
|
||||
const static ExprVt Vt = {
|
||||
.dtor = SubscrExpr__dtor,
|
||||
.emit_ = SubscrExpr__emit_,
|
||||
@ -1061,8 +1061,8 @@ SubscrExpr* SubscrExpr__new(int line, Expr* lhs, Expr* rhs) {
|
||||
SubscrExpr* self = PoolExpr_alloc();
|
||||
self->vt = &Vt;
|
||||
self->line = line;
|
||||
self->lhs = lhs;
|
||||
self->rhs = rhs;
|
||||
self->lhs = NULL;
|
||||
self->rhs = NULL;
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -1132,7 +1132,7 @@ typedef struct CallExpr {
|
||||
EXPR_COMMON_HEADER
|
||||
Expr* callable;
|
||||
c11_vector /*T=Expr* */ args;
|
||||
// **a will be interpreted as a special keyword argument: {"**": a}
|
||||
// **a will be interpreted as a special keyword argument: {{0}: a}
|
||||
c11_vector /*T=CallExprKwArg */ kwargs;
|
||||
} CallExpr;
|
||||
|
||||
@ -1178,7 +1178,7 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
|
||||
if(e->val->vt->is_starred) {
|
||||
// **kwargs
|
||||
StarredExpr* se = (StarredExpr*)e->val;
|
||||
assert(se->level == 2);
|
||||
assert(se->level == 2 && e->key == 0);
|
||||
vtemit_(e->val, ctx);
|
||||
} else {
|
||||
// k=v
|
||||
@ -1431,7 +1431,7 @@ static Error* EXPR_VARS(Compiler* self) {
|
||||
// if(count > 1){
|
||||
// TupleExpr* e = make_expr<TupleExpr>(count);
|
||||
// for(int i=count-1; i>=0; i--)
|
||||
// e->items[i] = ctx()->s_popx();
|
||||
// e->items[i] = Ctx__s_popx(ctx());
|
||||
// ctx()->s_push(e);
|
||||
// }
|
||||
return NULL;
|
||||
@ -1680,12 +1680,189 @@ static Error* exprLiteral0(Compiler* self) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprList(Compiler* self);
|
||||
static Error* exprMap(Compiler* self);
|
||||
static Error* exprCall(Compiler* self);
|
||||
static Error* exprSlice0(Compiler* self);
|
||||
static Error* exprSlice1(Compiler* self);
|
||||
static Error* exprSubscr(Compiler* self);
|
||||
static Error* consume_comp(Compiler* self, Opcode op0, Opcode op1) {
|
||||
// [expr]
|
||||
Error* err;
|
||||
int line = prev()->line;
|
||||
bool has_cond = false;
|
||||
check(EXPR_VARS(self)); // [expr, vars]
|
||||
consume(TK_IN);
|
||||
check(parse_expression(self, PREC_TERNARY + 1, false)); // [expr, vars, iter]
|
||||
check_newlines_repl();
|
||||
if(match(TK_IF)) {
|
||||
check(parse_expression(self, PREC_TERNARY + 1, false)); // [expr, vars, iter, cond]
|
||||
has_cond = true;
|
||||
}
|
||||
CompExpr* ce = CompExpr__new(line, op0, op1);
|
||||
if(has_cond) ce->cond = Ctx__s_popx(ctx());
|
||||
ce->iter = Ctx__s_popx(ctx());
|
||||
ce->vars = Ctx__s_popx(ctx());
|
||||
ce->expr = Ctx__s_popx(ctx());
|
||||
Ctx__s_push(ctx(), (Expr*)ce);
|
||||
check_newlines_repl();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprList(Compiler* self) {
|
||||
Error* err;
|
||||
int line = prev()->line;
|
||||
int count = 0;
|
||||
do {
|
||||
check_newlines_repl();
|
||||
if(curr()->type == TK_RBRACKET) break;
|
||||
check(EXPR(self));
|
||||
count += 1;
|
||||
check_newlines_repl();
|
||||
if(count == 1 && match(TK_FOR)) {
|
||||
check(consume_comp(self, OP_BUILD_LIST, OP_LIST_APPEND));
|
||||
consume(TK_RBRACKET);
|
||||
return NULL;
|
||||
}
|
||||
check_newlines_repl();
|
||||
} while(match(TK_COMMA));
|
||||
consume(TK_RBRACKET);
|
||||
SequenceExpr* e = ListExpr__new(line, count);
|
||||
for(int i = count - 1; i >= 0; i--) {
|
||||
c11__setitem(Expr*, &e->items, i, Ctx__s_popx(ctx()));
|
||||
}
|
||||
Ctx__s_push(ctx(), (Expr*)e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprMap(Compiler* self) {
|
||||
Error* err;
|
||||
int line = prev()->line;
|
||||
bool parsing_dict = false; // {...} may be dict or set
|
||||
int count = 0;
|
||||
do {
|
||||
check_newlines_repl();
|
||||
if(curr()->type == TK_RBRACE) break;
|
||||
check(EXPR(self)); // [key]
|
||||
if(curr()->type == TK_COLON) { parsing_dict = true; }
|
||||
if(parsing_dict) {
|
||||
consume(TK_COLON);
|
||||
check(EXPR(self)); // [key, value]
|
||||
}
|
||||
count += 1; // key-value pair count
|
||||
check_newlines_repl();
|
||||
if(count == 1 && match(TK_FOR)) {
|
||||
if(parsing_dict) {
|
||||
check(consume_comp(self, OP_BUILD_DICT, OP_DICT_ADD));
|
||||
} else {
|
||||
check(consume_comp(self, OP_BUILD_SET, OP_SET_ADD));
|
||||
}
|
||||
consume(TK_RBRACE);
|
||||
return NULL;
|
||||
}
|
||||
check_newlines_repl();
|
||||
} while(match(TK_COMMA));
|
||||
consume(TK_RBRACE);
|
||||
|
||||
SequenceExpr* se;
|
||||
if(count == 0 || parsing_dict) {
|
||||
count *= 2; // key + value
|
||||
se = DictExpr__new(line, count);
|
||||
} else {
|
||||
se = SetExpr__new(line, count);
|
||||
}
|
||||
for(int i = count - 1; i >= 0; i--) {
|
||||
c11__setitem(Expr*, &se->items, i, Ctx__s_popx(ctx()));
|
||||
}
|
||||
Ctx__s_push(ctx(), (Expr*)se);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprCall(Compiler* self) {
|
||||
Error* err;
|
||||
CallExpr* e = CallExpr__new(prev()->line, Ctx__s_popx(ctx()));
|
||||
Ctx__s_push(ctx(), (Expr*)e); // push onto the stack in advance
|
||||
do {
|
||||
check_newlines_repl();
|
||||
if(curr()->type == TK_RPAREN) break;
|
||||
if(curr()->type == TK_ID && next()->type == TK_ASSIGN) {
|
||||
consume(TK_ID);
|
||||
StrName key = pk_StrName__map2(Token__sv(prev()));
|
||||
consume(TK_ASSIGN);
|
||||
check(EXPR(self));
|
||||
CallExprKwArg kw = {key, Ctx__s_popx(ctx())};
|
||||
c11_vector__push(CallExprKwArg, &e->kwargs, kw);
|
||||
} else {
|
||||
check(EXPR(self));
|
||||
int star_level = 0;
|
||||
Expr* top = Ctx__s_top(ctx());
|
||||
if(top->vt->is_starred) star_level = ((StarredExpr*)top)->level;
|
||||
if(star_level == 2) {
|
||||
// **kwargs
|
||||
CallExprKwArg kw = {0, Ctx__s_popx(ctx())};
|
||||
c11_vector__push(CallExprKwArg, &e->kwargs, kw);
|
||||
} else {
|
||||
// positional argument
|
||||
if(e->kwargs.count > 0) {
|
||||
return SyntaxError("positional argument follows keyword argument");
|
||||
}
|
||||
c11_vector__push(Expr*, &e->args, Ctx__s_popx(ctx()));
|
||||
}
|
||||
}
|
||||
check_newlines_repl();
|
||||
} while(match(TK_COMMA));
|
||||
consume(TK_RPAREN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprSlice0(Compiler* self) {
|
||||
Error* err;
|
||||
SliceExpr* slice = SliceExpr__new(prev()->line);
|
||||
Ctx__s_push(ctx(), (Expr*)slice); // push onto the stack in advance
|
||||
if(is_expression(self, false)) { // :<stop>
|
||||
check(EXPR(self));
|
||||
slice->stop = Ctx__s_popx(ctx());
|
||||
// try optional step
|
||||
if(match(TK_COLON)) { // :<stop>:<step>
|
||||
check(EXPR(self));
|
||||
slice->step = Ctx__s_popx(ctx());
|
||||
}
|
||||
} else if(match(TK_COLON)) {
|
||||
if(is_expression(self, false)) { // ::<step>
|
||||
check(EXPR(self));
|
||||
slice->step = Ctx__s_popx(ctx());
|
||||
} // else ::
|
||||
} // else :
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprSlice1(Compiler* self) {
|
||||
Error* err;
|
||||
SliceExpr* slice = SliceExpr__new(prev()->line);
|
||||
slice->start = Ctx__s_popx(ctx());
|
||||
Ctx__s_push(ctx(), (Expr*)slice); // push onto the stack in advance
|
||||
if(is_expression(self, false)) { // <start>:<stop>
|
||||
check(EXPR(self));
|
||||
slice->stop = Ctx__s_popx(ctx());
|
||||
// try optional step
|
||||
if(match(TK_COLON)) { // <start>:<stop>:<step>
|
||||
check(EXPR(self));
|
||||
slice->step = Ctx__s_popx(ctx());
|
||||
}
|
||||
} else if(match(TK_COLON)) { // <start>::<step>
|
||||
check(EXPR(self));
|
||||
slice->step = Ctx__s_popx(ctx());
|
||||
} // else <start>:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Error* exprSubscr(Compiler* self) {
|
||||
Error* err;
|
||||
int line = prev()->line;
|
||||
check_newlines_repl();
|
||||
check(EXPR_TUPLE_ALLOW_SLICE(self, true));
|
||||
check_newlines_repl();
|
||||
consume(TK_RBRACKET); // [lhs, rhs]
|
||||
SubscrExpr* e = SubscrExpr__new(line);
|
||||
e->rhs = Ctx__s_popx(ctx()); // [lhs]
|
||||
e->lhs = Ctx__s_popx(ctx()); // []
|
||||
Ctx__s_push(ctx(), (Expr*)e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1710,8 +1887,8 @@ Error* Compiler__compile(Compiler* self, CodeObject* out) {
|
||||
return NULL;
|
||||
}
|
||||
// } else if(mode() == JSON_MODE) {
|
||||
// check(EXPR());
|
||||
// Expr* e = ctx()->s_popx();
|
||||
// check(EXPR(self));
|
||||
// Expr* e = Ctx__s_popx(ctx());
|
||||
// if(!e->is_json_object()){
|
||||
// return SyntaxError("expect a JSON object, literal or array");
|
||||
// }
|
||||
|
Loading…
x
Reference in New Issue
Block a user