From 0963929a303feb77fd52f2b466dc54aa6d376aef Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 29 Jun 2024 17:01:09 +0800 Subject: [PATCH] some up --- src/compiler/compiler.c | 205 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 191 insertions(+), 14 deletions(-) diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 268666bd..d1b77009 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -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(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)) { // : + check(EXPR(self)); + slice->stop = Ctx__s_popx(ctx()); + // try optional step + if(match(TK_COLON)) { // :: + check(EXPR(self)); + slice->step = Ctx__s_popx(ctx()); + } + } else if(match(TK_COLON)) { + if(is_expression(self, false)) { // :: + 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)) { // : + check(EXPR(self)); + slice->stop = Ctx__s_popx(ctx()); + // try optional step + if(match(TK_COLON)) { // :: + check(EXPR(self)); + slice->step = Ctx__s_popx(ctx()); + } + } else if(match(TK_COLON)) { // :: + check(EXPR(self)); + slice->step = Ctx__s_popx(ctx()); + } // else : + 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"); // }