From 6f4617b83dfd739e844eba0096d3ef4bb21f0599 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Fri, 28 Jun 2024 19:32:48 +0800 Subject: [PATCH] Update compiler.c --- src/compiler/compiler.c | 88 +++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index f5c426a8..362d9d2e 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -50,9 +50,7 @@ static void pk_Compiler__dtor(pk_Compiler *self){ #define check_newlines_repl() { bool __nml; match_newlines_repl(self, &__nml); if(__nml) return NeedMoreLines(); } #define check(B) if((err = B)) return err -#define match(expected) (curr().type == expected ? (++self->i) : 0) - -NameScope name_scope(pk_Compiler* self) { +static NameScope name_scope(pk_Compiler* self) { NameScope s = self->contexts.count > 1 ? NAME_LOCAL : NAME_GLOBAL; if(self->src->is_dynamic && s == NAME_GLOBAL) s = NAME_GLOBAL_UNKNOWN; return s; @@ -66,7 +64,15 @@ static Error* NeedMoreLines(){ return NULL; } -bool match_newlines_repl(pk_Compiler* self, bool* need_more_lines){ +/* Matchers */ +static bool is_expression(pk_Compiler* self, bool allow_slice){ + PrattCallback prefix = rules[curr().type].prefix; + return prefix && (allow_slice || curr().type != TK_COLON); +} + +#define match(expected) (curr().type == expected ? (++self->i) : 0) + +static bool match_newlines_repl(pk_Compiler* self, bool* need_more_lines){ bool consumed = false; if(curr().type == TK_EOL) { while(curr().type == TK_EOL) advance(); @@ -78,30 +84,17 @@ bool match_newlines_repl(pk_Compiler* self, bool* need_more_lines){ return consumed; } -bool is_expression(pk_Compiler* self, bool allow_slice){ - PrattCallback prefix = rules[curr().type].prefix; - return prefix && (allow_slice || curr().type != TK_COLON); +static bool match_end_stmt(pk_Compiler* self) { + if(match(TK_SEMICOLON)) { + match_newlines(); + return true; + } + if(match_newlines() || curr().type == TK_EOF) return true; + if(curr().type == TK_DEDENT) return true; + return false; } -Error* parse_expression(pk_Compiler* self, int precedence, bool allow_slice){ - PrattCallback prefix = rules[curr().type].prefix; - if(!prefix || (curr().type == TK_COLON && !allow_slice)) { - return SyntaxError("expected an expression, got %s", pk_TokenSymbols[curr().type]); - } - advance(); - Error* err; - check(prefix(self)); - while(rules[curr().type].precedence >= precedence && (allow_slice || curr().type != TK_COLON)) { - TokenIndex op = curr().type; - advance(); - PrattCallback infix = rules[op].infix; - assert(infix != NULL); - check(infix(self)); - } - return NULL; -} - -// exprs +/* Expression Callbacks */ static Error* exprLiteral(pk_Compiler* self); static Error* exprLong(pk_Compiler* self); static Error* exprImag(pk_Compiler* self); @@ -125,12 +118,30 @@ static Error* exprSlice1(pk_Compiler* self); static Error* exprSubscr(pk_Compiler* self); static Error* exprLiteral0(pk_Compiler* self); +/* Expression */ +static Error* parse_expression(pk_Compiler* self, int precedence, bool allow_slice){ + PrattCallback prefix = rules[curr().type].prefix; + if(!prefix || (curr().type == TK_COLON && !allow_slice)) { + return SyntaxError("expected an expression, got %s", pk_TokenSymbols[curr().type]); + } + advance(); + Error* err; + check(prefix(self)); + while(rules[curr().type].precedence >= precedence && (allow_slice || curr().type != TK_COLON)) { + TokenIndex op = curr().type; + advance(); + PrattCallback infix = rules[op].infix; + assert(infix != NULL); + check(infix(self)); + } + return NULL; +} - // [[nodiscard]] Error* EXPR() noexcept{ return parse_expression(PREC_LOWEST + 1); } - // [[nodiscard]] Error* EXPR_TUPLE(bool allow_slice = false) noexcept; - // [[nodiscard]] Error* EXPR_VARS() noexcept; // special case for `for loop` and `comp` +static Error* EXPR(pk_Compiler* self) { + return parse_expression(self, PREC_LOWEST + 1, false); +} -Error* EXPR_TUPLE(pk_Compiler* self, bool allow_slice){ +static Error* EXPR_TUPLE(pk_Compiler* self, bool allow_slice){ Error* err; check(parse_expression(self, PREC_LOWEST + 1, allow_slice)); if(!match(TK_COMMA)) return NULL; @@ -150,6 +161,23 @@ Error* EXPR_TUPLE(pk_Compiler* self, bool allow_slice){ return NULL; } +// special case for `for loop` and `comp` +static Error* EXPR_VARS(pk_Compiler* self){ + int count = 0; + do { + consume(TK_ID); + ctx()->s_push(make_expr(prev().str(), name_scope())); + count += 1; + } while(match(TK_COMMA)); + if(count > 1){ + TupleExpr* e = make_expr(count); + for(int i=count-1; i>=0; i--) + e->items[i] = ctx()->s_popx(); + ctx()->s_push(e); + } + return NULL; +} + static void setup_global_context(pk_Compiler* self, CodeObject* co){ co->start_line = self->i == 0 ? 1 : prev().line; pk_CodeEmitContext* ctx = c11_vector__emplace(&self->contexts);