From 23b523b78888f7c18eaa5a435fbef8f3d82d93ec Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 29 Jun 2024 16:36:30 +0800 Subject: [PATCH] some fix --- include/pocketpy/compiler/lexer.h | 2 + src/common/memorypool.c | 4 +- src/compiler/compiler.c | 536 ++++++++++++++++++++++-------- src2/main.c | 35 +- 4 files changed, 432 insertions(+), 145 deletions(-) diff --git a/include/pocketpy/compiler/lexer.h b/include/pocketpy/compiler/lexer.h index d4d6c9d8..28ad0712 100644 --- a/include/pocketpy/compiler/lexer.h +++ b/include/pocketpy/compiler/lexer.h @@ -103,6 +103,8 @@ Error* pk_Lexer__process(pk_SourceData_ src, pk_TokenArray* out_tokens); Error* pk_Lexer__process_and_dump(pk_SourceData_ src, py_Str* out_string); void pk_TokenArray__dtor(pk_TokenArray* self); +#define Token__sv(self) (c11_string){(self)->start, (self)->length} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/src/common/memorypool.c b/src/common/memorypool.c index 3a608a40..fd5f4d9d 100644 --- a/src/common/memorypool.c +++ b/src/common/memorypool.c @@ -243,7 +243,7 @@ PK_THREAD_LOCAL FixedMemoryPool PoolFrame; PK_THREAD_LOCAL MemoryPool PoolObject; PK_THREAD_LOCAL bool _Pools_initialized = false; -void Pools_initialize(){ +void pk_MemoryPools__initialize(){ if(_Pools_initialized) return; FixedMemoryPool__ctor(&PoolExpr, kPoolExprBlockSize, 64); FixedMemoryPool__ctor(&PoolFrame, kPoolFrameBlockSize, 128); @@ -251,7 +251,7 @@ void Pools_initialize(){ _Pools_initialized = true; } -void Pools_finalize(){ +void pk_MemoryPools__finalize(){ if(!_Pools_initialized) return; FixedMemoryPool__dtor(&PoolExpr); FixedMemoryPool__dtor(&PoolFrame); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index b988ec3f..268666bd 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -2,6 +2,7 @@ #include "pocketpy/compiler/lexer.h" #include "pocketpy/objects/sourcedata.h" #include "pocketpy/common/strname.h" +#include "pocketpy/common/config.h" #include "pocketpy/common/memorypool.h" #include @@ -70,7 +71,6 @@ typedef struct Expr Expr; void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level); void Ctx__dtor(Ctx* self); - int Ctx__get_loop(Ctx* self); CodeBlock* Ctx__enter_block(Ctx* self, CodeBlockType type); void Ctx__exit_block(Ctx* self); @@ -85,21 +85,12 @@ int Ctx__add_const(Ctx* self, py_Ref); int Ctx__add_const_string(Ctx* self, c11_string); void Ctx__emit_store_name(Ctx* self, NameScope scope, StrName name, int line); void Ctx__try_merge_for_iter_store(Ctx* self, int); -// emit top -> pop -> delete -void Ctx__s_emit_top(Ctx*); -// push -void Ctx__s_push(Ctx*, Expr*); -// top -Expr* Ctx__s_top(Ctx*); -// size -int Ctx__s_size(Ctx*); -// pop -> delete -void Ctx__s_pop(Ctx*); -// pop move -Expr* Ctx__s_popx(Ctx*); -// clean -void Ctx__s_clean(Ctx*); -// emit decorators +void Ctx__s_emit_top(Ctx*); // emit top -> pop -> delete +void Ctx__s_push(Ctx*, Expr*); // push +Expr* Ctx__s_top(Ctx*); // top +int Ctx__s_size(Ctx*); // size +void Ctx__s_pop(Ctx*); // pop -> delete +Expr* Ctx__s_popx(Ctx*); // pop move void Ctx__s_emit_decorators(Ctx*, int count); /* expr.c */ @@ -152,7 +143,7 @@ bool NameExpr__emit_store(Expr* self_, Ctx* ctx) { return true; } -NameExpr* NameExpr__new(StrName name, NameScope scope) { +NameExpr* NameExpr__new(int line, StrName name, NameScope scope) { const static ExprVt Vt = {.emit_ = NameExpr__emit_, .emit_del = NameExpr__emit_del, .emit_store = NameExpr__emit_store, @@ -160,7 +151,7 @@ NameExpr* NameExpr__new(StrName name, NameScope scope) { static_assert_expr_size(NameExpr); NameExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->name = name; self->scope = scope; return self; @@ -185,14 +176,14 @@ bool StarredExpr__emit_store(Expr* self_, Ctx* ctx) { return vtemit_store(self->child, ctx); } -StarredExpr* StarredExpr__new(Expr* child, int level) { +StarredExpr* StarredExpr__new(int line, Expr* child, int level) { const static ExprVt Vt = {.emit_ = StarredExpr__emit_, .emit_store = StarredExpr__emit_store, .is_starred = true}; static_assert_expr_size(StarredExpr); StarredExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->child = child; self->level = level; return self; @@ -217,18 +208,17 @@ static void UnaryExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line); } -UnaryExpr* UnaryExpr__new(Expr* child, Opcode opcode) { +UnaryExpr* UnaryExpr__new(int line, Expr* child, Opcode opcode) { const static ExprVt Vt = {.emit_ = UnaryExpr__emit_, .dtor = UnaryExpr__dtor}; static_assert_expr_size(UnaryExpr); UnaryExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->child = child; self->opcode = opcode; return self; } -// LongExpr, BytesExpr typedef struct RawStringExpr { EXPR_COMMON_HEADER c11_string value; @@ -242,12 +232,12 @@ void RawStringExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line); } -RawStringExpr* RawStringExpr__new(c11_string value, Opcode opcode) { +RawStringExpr* RawStringExpr__new(int line, c11_string value, Opcode opcode) { const static ExprVt Vt = {.emit_ = RawStringExpr__emit_}; static_assert_expr_size(RawStringExpr); RawStringExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->value = value; self->opcode = opcode; return self; @@ -267,12 +257,12 @@ void ImagExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__emit_(ctx, OP_BUILD_IMAG, BC_NOARG, self->line); } -ImagExpr* ImagExpr__new(double value) { +ImagExpr* ImagExpr__new(int line, double value) { const static ExprVt Vt = {.emit_ = ImagExpr__emit_}; static_assert_expr_size(ImagExpr); ImagExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->value = value; return self; } @@ -307,18 +297,48 @@ void LiteralExpr__emit_(Expr* self_, Ctx* ctx) { } } -LiteralExpr* LiteralExpr__new(const TokenValue* value) { +LiteralExpr* LiteralExpr__new(int line, const TokenValue* value) { const static ExprVt Vt = {.emit_ = LiteralExpr__emit_, .is_literal = true, .is_json_object = true}; static_assert_expr_size(LiteralExpr); LiteralExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->value = value; return self; } +typedef struct Literal0Expr { + EXPR_COMMON_HEADER + TokenIndex token; +} Literal0Expr; + +void Literal0Expr__emit_(Expr* self_, Ctx* ctx) { + Literal0Expr* self = (Literal0Expr*)self_; + Opcode opcode; + switch(self->token) { + case TK_NONE: opcode = OP_LOAD_NONE; break; + case TK_TRUE: opcode = OP_LOAD_TRUE; break; + case TK_FALSE: opcode = OP_LOAD_FALSE; break; + case TK_DOTDOTDOT: opcode = OP_LOAD_ELLIPSIS; break; + default: assert(false); + } + Ctx__emit_(ctx, opcode, BC_NOARG, self->line); +} + +Literal0Expr* Literal0Expr__new(int line, TokenIndex token) { + const static ExprVt Vt = {.emit_ = Literal0Expr__emit_, + .is_literal = true, + .is_json_object = true}; + static_assert_expr_size(Literal0Expr); + Literal0Expr* self = PoolExpr_alloc(); + self->vt = &Vt; + self->line = line; + self->token = token; + return self; +} + typedef struct SliceExpr { EXPR_COMMON_HEADER Expr* start; @@ -350,12 +370,12 @@ void SliceExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__emit_(ctx, OP_BUILD_SLICE, BC_NOARG, self->line); } -SliceExpr* SliceExpr__new() { +SliceExpr* SliceExpr__new(int line) { const static ExprVt Vt = {.dtor = SliceExpr__dtor, .emit_ = SliceExpr__emit_}; static_assert_expr_size(SliceExpr); SliceExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->start = NULL; self->stop = NULL; self->step = NULL; @@ -441,45 +461,45 @@ bool TupleExpr__emit_del(Expr* self_, Ctx* ctx) { return true; } -static SequenceExpr* SequenceExpr__new(const ExprVt* vt, int count, Opcode opcode) { +static SequenceExpr* SequenceExpr__new(int line, const ExprVt* vt, int count, Opcode opcode) { static_assert_expr_size(SequenceExpr); SequenceExpr* self = PoolExpr_alloc(); self->vt = vt; - self->line = -1; + self->line = line; self->opcode = opcode; c11_array__ctor(&self->items, count, sizeof(Expr*)); return self; } -SequenceExpr* ListExpr__new(int count) { +SequenceExpr* ListExpr__new(int line, int count) { const static ExprVt ListExprVt = {.dtor = SequenceExpr__dtor, .emit_ = SequenceExpr__emit_, .is_json_object = true}; - return SequenceExpr__new(&ListExprVt, count, OP_BUILD_LIST); + return SequenceExpr__new(line, &ListExprVt, count, OP_BUILD_LIST); } -SequenceExpr* DictExpr__new(int count) { +SequenceExpr* DictExpr__new(int line, int count) { const static ExprVt DictExprVt = {.dtor = SequenceExpr__dtor, .emit_ = SequenceExpr__emit_, .is_json_object = true}; - return SequenceExpr__new(&DictExprVt, count, OP_BUILD_DICT); + return SequenceExpr__new(line, &DictExprVt, count, OP_BUILD_DICT); } -SequenceExpr* SetExpr__new(int count) { +SequenceExpr* SetExpr__new(int line, int count) { const static ExprVt SetExprVt = { .dtor = SequenceExpr__dtor, .emit_ = SequenceExpr__emit_, }; - return SequenceExpr__new(&SetExprVt, count, OP_BUILD_SET); + return SequenceExpr__new(line, &SetExprVt, count, OP_BUILD_SET); } -SequenceExpr* TupleExpr__new(int count) { +SequenceExpr* TupleExpr__new(int line, int count) { const static ExprVt TupleExprVt = {.dtor = SequenceExpr__dtor, .emit_ = SequenceExpr__emit_, .is_tuple = true, .emit_store = TupleExpr__emit_store, .emit_del = TupleExpr__emit_del}; - return SequenceExpr__new(&TupleExprVt, count, OP_BUILD_TUPLE); + return SequenceExpr__new(line, &TupleExprVt, count, OP_BUILD_TUPLE); } typedef struct CompExpr { @@ -527,12 +547,12 @@ void CompExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__exit_block(ctx); } -CompExpr* CompExpr__new(Opcode op0, Opcode op1) { +CompExpr* CompExpr__new(int line, Opcode op0, Opcode op1) { const static ExprVt Vt = {.dtor = CompExpr__dtor, .emit_ = CompExpr__emit_}; static_assert_expr_size(CompExpr); CompExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->op0 = op0; self->op1 = op1; self->expr = NULL; @@ -552,12 +572,12 @@ static void LambdaExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__emit_(ctx, OP_LOAD_FUNCTION, self->index, self->line); } -LambdaExpr* LambdaExpr__new(int index) { +LambdaExpr* LambdaExpr__new(int line, int index) { const static ExprVt Vt = {.emit_ = LambdaExpr__emit_}; static_assert_expr_size(LambdaExpr); LambdaExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->index = index; return self; } @@ -732,12 +752,12 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__emit_(ctx, OP_BUILD_STRING, count, self->line); } -FStringExpr* FStringExpr__new(c11_string src) { +FStringExpr* FStringExpr__new(int line, c11_string src) { const static ExprVt Vt = {.emit_ = FStringExpr__emit_}; static_assert_expr_size(FStringExpr); FStringExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->src = src; return self; } @@ -764,14 +784,14 @@ void LogicBinaryExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__patch_jump(ctx, patch); } -LogicBinaryExpr* LogicBinaryExpr__new(Expr* lhs, Expr* rhs, Opcode opcode) { +LogicBinaryExpr* LogicBinaryExpr__new(int line, Opcode opcode) { const static ExprVt Vt = {.emit_ = LogicBinaryExpr__emit_, .dtor = LogicBinaryExpr__dtor}; static_assert_expr_size(LogicBinaryExpr); LogicBinaryExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; - self->lhs = lhs; - self->rhs = rhs; + self->line = line; + self->lhs = NULL; + self->rhs = NULL; self->opcode = opcode; return self; } @@ -801,7 +821,7 @@ bool GroupedExpr__emit_store(Expr* self_, Ctx* ctx) { return vtemit_store(self->child, ctx); } -GroupedExpr* GroupedExpr__new(Expr* child) { +GroupedExpr* GroupedExpr__new(int line, Expr* child) { const static ExprVt Vt = {.dtor = GroupedExpr__dtor, .emit_ = GroupedExpr__emit_, .emit_del = GroupedExpr__emit_del, @@ -809,7 +829,7 @@ GroupedExpr* GroupedExpr__new(Expr* child) { static_assert_expr_size(GroupedExpr); GroupedExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->child = child; return self; } @@ -914,6 +934,19 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) { c11__foreach(int, &jmps, i) { Ctx__patch_jump(ctx, *i); } } +BinaryExpr* BinaryExpr__new(int line, TokenIndex op, bool inplace) { + const static ExprVt Vt = {.emit_ = BinaryExpr__emit_, .dtor = BinaryExpr__dtor}; + static_assert_expr_size(BinaryExpr); + BinaryExpr* self = PoolExpr_alloc(); + self->vt = &Vt; + self->line = line; + self->lhs = NULL; + self->rhs = NULL; + self->op = op; + self->inplace = inplace; + return self; +} + typedef struct TernaryExpr { EXPR_COMMON_HEADER Expr* cond; @@ -939,12 +972,12 @@ void TernaryExpr__emit_(Expr* self_, Ctx* ctx) { Ctx__patch_jump(ctx, patch_2); } -TernaryExpr* TernaryExpr__new() { +TernaryExpr* TernaryExpr__new(int line) { const static ExprVt Vt = {.dtor = TernaryExpr__dtor, .emit_ = TernaryExpr__emit_}; static_assert_expr_size(TernaryExpr); TernaryExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->cond = NULL; self->true_expr = NULL; self->false_expr = NULL; @@ -1014,7 +1047,7 @@ bool SubscrExpr__emit_del(Expr* self_, Ctx* ctx) { return true; } -SubscrExpr* SubscrExpr__new(Expr* lhs, Expr* rhs) { +SubscrExpr* SubscrExpr__new(int line, Expr* lhs, Expr* rhs) { const static ExprVt Vt = { .dtor = SubscrExpr__dtor, .emit_ = SubscrExpr__emit_, @@ -1027,7 +1060,7 @@ SubscrExpr* SubscrExpr__new(Expr* lhs, Expr* rhs) { static_assert_expr_size(SubscrExpr); SubscrExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->lhs = lhs; self->rhs = rhs; return self; @@ -1074,7 +1107,7 @@ bool AttribExpr__emit_istore(Expr* self_, Ctx* ctx) { return true; } -AttribExpr* AttribExpr__new(Expr* child, StrName name) { +AttribExpr* AttribExpr__new(int line, Expr* child, StrName name) { const static ExprVt Vt = {.emit_ = AttribExpr__emit_, .emit_del = AttribExpr__emit_del, .emit_store = AttribExpr__emit_store, @@ -1084,7 +1117,7 @@ AttribExpr* AttribExpr__new(Expr* child, StrName name) { static_assert_expr_size(AttribExpr); AttribExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->child = child; self->name = name; return self; @@ -1172,12 +1205,12 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) { } } -CallExpr* CallExpr__new(Expr* callable) { +CallExpr* CallExpr__new(int line, Expr* callable) { const static ExprVt Vt = {.dtor = CallExpr__dtor, .emit_ = CallExpr__emit_}; static_assert_expr_size(CallExpr); CallExpr* self = PoolExpr_alloc(); self->vt = &Vt; - self->line = -1; + self->line = line; self->callable = callable; c11_vector__ctor(&self->args, sizeof(Expr*)); c11_vector__ctor(&self->kwargs, sizeof(CallExprKwArg)); @@ -1197,6 +1230,11 @@ void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level) { } void Ctx__dtor(Ctx* self) { + // clean the expr stack + for(int i = 0; i < self->s_expr.count; i++) { + vtdelete(c11__getitem(Expr*, &self->s_expr, i)); + } + c11_vector__clear(&self->s_expr); c11_vector__dtor(&self->s_expr); c11_vector__dtor(&self->global_names); c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map); @@ -1232,15 +1270,6 @@ Expr* Ctx__s_popx(Ctx* self) { return e; } -// clean -void Ctx__s_clean(Ctx* self) { - c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map); // ?? - for(int i = 0; i < self->s_expr.count; i++) { - vtdelete(c11__getitem(Expr*, &self->s_expr, i)); - } - c11_vector__clear(&self->s_expr); -} - /* compiler.c */ typedef struct Compiler Compiler; typedef Error* (*PrattCallback)(Compiler* self); @@ -1273,7 +1302,7 @@ static void Compiler__dtor(Compiler* self) { } /**************************************/ -#define tk(i) c11__getitem(Token, &self->tokens, i) +#define tk(i) c11__at(Token, &self->tokens, i) #define prev() tk(self->i - 1) #define curr() tk(self->i) #define next() tk(self->i + 1) @@ -1281,23 +1310,23 @@ static void Compiler__dtor(Compiler* self) { #define advance() self->i++ #define mode() self->src->mode -#define ctx() c11_vector__back(Ctx, &self->contexts) +#define ctx() (&c11_vector__back(Ctx, &self->contexts)) #define match_newlines() match_newlines_repl(self, NULL) #define consume(expected) \ if(!match(expected)) \ return SyntaxError("expected '%s', got '%s'", \ - TokenSymbols[expected], \ - TokenSymbols[curr().type]); + pk_TokenSymbols[expected], \ + pk_TokenSymbols[curr()->type]); #define consume_end_stmt() \ if(!match_end_stmt()) return SyntaxError("expected statement end") #define check_newlines_repl() \ - { \ + do { \ bool __nml; \ match_newlines_repl(self, &__nml); \ if(__nml) return NeedMoreLines(); \ - } + } while(0) #define check(B) \ if((err = B)) return err @@ -1313,20 +1342,20 @@ static Error* NeedMoreLines() { return NULL; } /* Matchers */ static bool is_expression(Compiler* self, bool allow_slice) { - PrattCallback prefix = rules[curr().type].prefix; - return prefix && (allow_slice || curr().type != TK_COLON); + PrattCallback prefix = rules[curr()->type].prefix; + return prefix && (allow_slice || curr()->type != TK_COLON); } -#define match(expected) (curr().type == expected ? (++self->i) : 0) +#define match(expected) (curr()->type == expected ? (++self->i) : 0) static bool match_newlines_repl(Compiler* self, bool* need_more_lines) { bool consumed = false; - if(curr().type == TK_EOL) { - while(curr().type == TK_EOL) + if(curr()->type == TK_EOL) { + while(curr()->type == TK_EOL) advance(); consumed = true; } - if(need_more_lines) { *need_more_lines = (mode() == REPL_MODE && curr().type == TK_EOF); } + if(need_more_lines) { *need_more_lines = (mode() == REPL_MODE && curr()->type == TK_EOF); } return consumed; } @@ -1335,46 +1364,25 @@ static bool match_end_stmt(Compiler* self) { match_newlines(); return true; } - if(match_newlines() || curr().type == TK_EOF) return true; - if(curr().type == TK_DEDENT) return true; + if(match_newlines() || curr()->type == TK_EOF) return true; + if(curr()->type == TK_DEDENT) return true; return false; } -/* Expression Callbacks */ -static Error* exprLiteral(Compiler* self); -static Error* exprLong(Compiler* self); -static Error* exprImag(Compiler* self); -static Error* exprBytes(Compiler* self); -static Error* exprFString(Compiler* self); -static Error* exprLambda(Compiler* self); -static Error* exprOr(Compiler* self); -static Error* exprAnd(Compiler* self); -static Error* exprTernary(Compiler* self); -static Error* exprBinaryOp(Compiler* self); -static Error* exprNot(Compiler* self); -static Error* exprUnaryOp(Compiler* self); -static Error* exprGroup(Compiler* self); -static Error* exprList(Compiler* self); -static Error* exprMap(Compiler* self); -static Error* exprCall(Compiler* self); -static Error* exprName(Compiler* self); -static Error* exprAttrib(Compiler* self); -static Error* exprSlice0(Compiler* self); -static Error* exprSlice1(Compiler* self); -static Error* exprSubscr(Compiler* self); -static Error* exprLiteral0(Compiler* self); - /* Expression */ + +/// Parse an expression and push it onto the stack. static Error* parse_expression(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]); + 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; + 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); @@ -1383,27 +1391,35 @@ static Error* parse_expression(Compiler* self, int precedence, bool allow_slice) return NULL; } -static Error* EXPR(Compiler* self) { return parse_expression(self, PREC_LOWEST + 1, false); } - -static Error* EXPR_TUPLE(Compiler* self, bool allow_slice) { +static Error* EXPR_TUPLE_ALLOW_SLICE(Compiler* self, bool allow_slice) { Error* err; check(parse_expression(self, PREC_LOWEST + 1, allow_slice)); if(!match(TK_COMMA)) return NULL; - // tuple expression + // tuple expression // (a, ) int count = 1; do { - if(curr().brackets_level) check_newlines_repl() if(!is_expression(self, allow_slice)) break; + if(curr()->brackets_level) check_newlines_repl(); + if(!is_expression(self, allow_slice)) break; check(parse_expression(self, PREC_LOWEST + 1, allow_slice)); count += 1; - if(curr().brackets_level) check_newlines_repl(); + if(curr()->brackets_level) check_newlines_repl(); } while(match(TK_COMMA)); - // TupleExpr* e = make_expr(count); - // for(int i=count-1; i>=0; i--) - // e->items[i] = ctx()->s_popx(); - // ctx()->s_push(e); + // pop `count` expressions from the stack and merge them into a TupleExpr + SequenceExpr* e = TupleExpr__new(prev()->line, count); + for(int i = count - 1; i >= 0; i--) { + Expr* item = Ctx__s_popx(ctx()); + c11__setitem(Expr*, &e->items, i, item); + } + Ctx__s_push(ctx(), (Expr*)e); return NULL; } +/// Parse a simple expression. +static Error* EXPR(Compiler* self) { return parse_expression(self, PREC_LOWEST + 1, false); } + +/// Parse a simple expression or a tuple of expressions. +static Error* EXPR_TUPLE(Compiler* self) { return EXPR_TUPLE_ALLOW_SLICE(self, false); } + // special case for `for loop` and `comp` static Error* EXPR_VARS(Compiler* self) { // int count = 0; @@ -1421,31 +1437,278 @@ static Error* EXPR_VARS(Compiler* self) { return NULL; } -static void setup_global_context(Compiler* self, CodeObject* co) { - co->start_line = self->i == 0 ? 1 : prev().line; +/* Misc */ +static void push_global_context(Compiler* self, CodeObject* co) { + co->start_line = self->i == 0 ? 1 : prev()->line; Ctx* ctx = c11_vector__emplace(&self->contexts); Ctx__ctor(ctx, co, NULL, self->contexts.count); } +static Error* pop_context(Compiler* self) { + // add a `return None` in the end as a guard + // previously, we only do this if the last opcode is not a return + // however, this is buggy...since there may be a jump to the end (out of bound) even if the last + // opcode is a return + Ctx__emit_virtual(ctx(), OP_RETURN_VALUE, 1, BC_KEEPLINE); + + CodeObject* co = ctx()->co; + // find the last valid token + int j = self->i - 1; + while(tk(j)->type == TK_EOL || tk(j)->type == TK_DEDENT || tk(j)->type == TK_EOF) + j--; + co->end_line = tk(j)->line; + + // some check here + c11_vector* codes = &co->codes; + if(co->nlocals > PK_MAX_CO_VARNAMES) { + return SyntaxError("maximum number of local variables exceeded"); + } + if(co->consts.count > 65530) { return SyntaxError("maximum number of constants exceeded"); } + // pre-compute LOOP_BREAK and LOOP_CONTINUE + for(int i = 0; i < codes->count; i++) { + Bytecode* bc = c11__at(Bytecode, codes, i); + if(bc->op == OP_LOOP_CONTINUE) { + CodeBlock* block = c11__at(CodeBlock, &ctx()->co->blocks, bc->arg); + Bytecode__set_signed_arg(bc, block->start - i); + } else if(bc->op == OP_LOOP_BREAK) { + CodeBlock* block = c11__at(CodeBlock, &ctx()->co->blocks, bc->arg); + Bytecode__set_signed_arg(bc, (block->end2 != -1 ? block->end2 : block->end) - i); + } + } + // pre-compute func->is_simple + FuncDecl* func = ctx()->func; + if(func) { + // check generator + c11__foreach(Bytecode, &func->code.codes, bc) { + if(bc->op == OP_YIELD_VALUE || bc->op == OP_FOR_ITER_YIELD_VALUE) { + func->type = FuncType_GENERATOR; + c11__foreach(Bytecode, &func->code.codes, bc) { + if(bc->op == OP_RETURN_VALUE && bc->arg == BC_NOARG) { + return SyntaxError("'return' with argument inside generator function"); + } + } + break; + } + } + if(func->type == FuncType_UNSET) { + bool is_simple = true; + if(func->kwargs.count > 0) is_simple = false; + if(func->starred_arg >= 0) is_simple = false; + if(func->starred_kwarg >= 0) is_simple = false; + + if(is_simple) { + func->type = FuncType_SIMPLE; + + bool is_empty = false; + if(func->code.codes.count == 1) { + Bytecode bc = c11__getitem(Bytecode, &func->code.codes, 0); + if(bc.op == OP_RETURN_VALUE && bc.arg == 1) { is_empty = true; } + } + if(is_empty) func->type = FuncType_EMPTY; + } else + func->type = FuncType_NORMAL; + } + + assert(func->type != FuncType_UNSET); + } + Ctx__dtor(ctx()); + c11_vector__pop(&self->contexts); + return NULL; +} + +/* Expression Callbacks */ +static Error* exprLiteral(Compiler* self) { + Ctx__s_push(ctx(), (Expr*)LiteralExpr__new(prev()->line, &prev()->value)); + return NULL; +} + +static Error* exprLong(Compiler* self) { + c11_string sv = Token__sv(prev()); + Ctx__s_push(ctx(), (Expr*)RawStringExpr__new(prev()->line, sv, OP_BUILD_LONG)); + return NULL; +} + +static Error* exprBytes(Compiler* self) { + c11_string sv = py_Str__sv(&prev()->value._str); + Ctx__s_push(ctx(), (Expr*)RawStringExpr__new(prev()->line, sv, OP_BUILD_BYTES)); + return NULL; +} + +static Error* exprFString(Compiler* self) { + c11_string sv = py_Str__sv(&prev()->value._str); + Ctx__s_push(ctx(), (Expr*)FStringExpr__new(prev()->line, sv)); + return NULL; +} + +static Error* exprImag(Compiler* self) { + Ctx__s_push(ctx(), (Expr*)ImagExpr__new(prev()->line, prev()->value._f64)); + return NULL; +} + +static Error* exprLambda(Compiler* self) { + assert(false); + return NULL; + // Error* err; + // int line = prev()->line; + // int decl_index; + // FuncDecl_ decl = push_f_context({"", 8}, &decl_index); + // if(!match(TK_COLON)) { + // check(_compile_f_args(decl, false)); + // consume(TK_COLON); + // } + // // https://github.com/pocketpy/pocketpy/issues/37 + // check(parse_expression(self, PREC_LAMBDA + 1, false)); + // Ctx__s_emit_top(ctx()); + // Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); + // check(pop_context(self)); + // LambdaExpr* e = LambdaExpr__new(line, decl_index); + // Ctx__s_push(ctx(), (Expr*)e); + // return NULL; +} + +static Error* exprOr(Compiler* self) { + Error* err; + int line = prev()->line; + check(parse_expression(self, PREC_LOGICAL_OR + 1, false)); + LogicBinaryExpr* e = LogicBinaryExpr__new(line, OP_JUMP_IF_TRUE_OR_POP); + e->rhs = Ctx__s_popx(ctx()); + e->lhs = Ctx__s_popx(ctx()); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprAnd(Compiler* self) { + Error* err; + int line = prev()->line; + check(parse_expression(self, PREC_LOGICAL_AND + 1, false)); + LogicBinaryExpr* e = LogicBinaryExpr__new(line, OP_JUMP_IF_FALSE_OR_POP); + e->rhs = Ctx__s_popx(ctx()); + e->lhs = Ctx__s_popx(ctx()); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprTernary(Compiler* self) { + // [true_expr] + Error* err; + int line = prev()->line; + check(parse_expression(self, PREC_TERNARY + 1, false)); // [true_expr, cond] + consume(TK_ELSE); + check(parse_expression(self, PREC_TERNARY + 1, false)); // [true_expr, cond, false_expr] + TernaryExpr* e = TernaryExpr__new(line); + e->false_expr = Ctx__s_popx(ctx()); + e->cond = Ctx__s_popx(ctx()); + e->true_expr = Ctx__s_popx(ctx()); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprBinaryOp(Compiler* self) { + Error* err; + int line = prev()->line; + TokenIndex op = prev()->type; + check(parse_expression(self, rules[op].precedence + 1, false)); + BinaryExpr* e = BinaryExpr__new(line, op, false); + e->rhs = Ctx__s_popx(ctx()); + e->lhs = Ctx__s_popx(ctx()); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprNot(Compiler* self) { + Error* err; + int line = prev()->line; + check(parse_expression(self, PREC_LOGICAL_NOT + 1, false)); + UnaryExpr* e = UnaryExpr__new(line, Ctx__s_popx(ctx()), OP_UNARY_NOT); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprUnaryOp(Compiler* self) { + Error* err; + int line = prev()->line; + TokenIndex op = prev()->type; + check(parse_expression(self, PREC_UNARY + 1, false)); + Expr* e = Ctx__s_popx(ctx()); + switch(op) { + case TK_SUB: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_NEGATIVE)); break; + case TK_INVERT: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_INVERT)); break; + case TK_MUL: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 1)); break; + case TK_POW: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 2)); break; + default: assert(false); + } + return NULL; +} + +static Error* exprGroup(Compiler* self) { + Error* err; + int line = prev()->line; + check_newlines_repl(); + check(EXPR_TUPLE(self)); // () is just for change precedence + check_newlines_repl(); + consume(TK_RPAREN); + if(Ctx__s_top(ctx())->vt->is_tuple) return NULL; + GroupedExpr* g = GroupedExpr__new(line, Ctx__s_popx(ctx())); + Ctx__s_push(ctx(), (Expr*)g); + return NULL; +} + +static Error* exprName(Compiler* self) { + StrName name = pk_StrName__map2(Token__sv(prev())); + NameScope scope = name_scope(self); + // promote this name to global scope if needed + c11_vector* global_names = &ctx()->global_names; + c11__foreach(StrName, global_names, it) { + if(*it == name) scope = NAME_GLOBAL; + } + NameExpr* e = NameExpr__new(prev()->line, name, scope); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprAttrib(Compiler* self) { + consume(TK_ID); + StrName name = pk_StrName__map2(Token__sv(prev())); + AttribExpr* e = AttribExpr__new(prev()->line, Ctx__s_popx(ctx()), name); + Ctx__s_push(ctx(), (Expr*)e); + return NULL; +} + +static Error* exprLiteral0(Compiler* self) { + Literal0Expr* e = Literal0Expr__new(prev()->line, prev()->type); + Ctx__s_push(ctx(), (Expr*)e); + 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); + +///////////////////////////////////////////////////////////////// + Error* Compiler__compile(Compiler* self, CodeObject* out) { // make sure it is the first time to compile assert(self->i == 0); // make sure the first token is @sof - assert(tk(0).type == TK_SOF); + assert(tk(0)->type == TK_SOF); - setup_global_context(self, out); + push_global_context(self, out); advance(); // skip @sof, so prev() is always valid match_newlines(); // skip possible leading '\n' Error* err; - // if(mode() == EVAL_MODE) { - // check(EXPR_TUPLE()); - // ctx()->s_emit_top(); - // consume(TK_EOF); - // ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); - // check(pop_context()); - // return NULL; + if(mode() == EVAL_MODE) { + check(EXPR_TUPLE(self)); + Ctx__s_emit_top(ctx()); + consume(TK_EOF); + Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE); + check(pop_context(self)); + return NULL; + } // } else if(mode() == JSON_MODE) { // check(EXPR()); // Expr* e = ctx()->s_popx(); @@ -1486,7 +1749,10 @@ Error* pk_compile(pk_SourceData_ src, CodeObject* out) { Compiler__ctor(&compiler, src, tokens); CodeObject__ctor(out, src, py_Str__sv(&src->filename)); err = Compiler__compile(&compiler, out); - if(err) CodeObject__dtor(out); + if(err) { + // if error occurs, dispose the code object + CodeObject__dtor(out); + } Compiler__dtor(&compiler); return err; } diff --git a/src2/main.c b/src2/main.c index 3cd9d531..ad4867ec 100644 --- a/src2/main.c +++ b/src2/main.c @@ -24,19 +24,38 @@ int main(int argc, char** argv) { SetConsoleOutputCP(CP_UTF8); #endif - if(argc != 2) goto __HELP; - char* source = read_file(argv[1]); py_initialize(); + const char* source = "[1, 'a']"; - if(py_exec(source)){ + if(py_eval(source)){ py_Error* err = py_getlasterror(); py_Error__print(err); + }else{ + // handle the result + py_Ref _0 = py_list__getitem(py_gettop(), 0); + py_Ref _1 = py_list__getitem(py_gettop(), 1); + int _L0 = py_toint(_0); + const char* _L1 = py_tostr(_1); + printf("%d, %s\n", _L0, _L1); + py_pop(); } - - py_finalize(); - free(source); -__HELP: - printf("Usage: pocketpy [filename]\n"); + py_finalize(); return 0; + +// if(argc != 2) goto __HELP; +// char* source = read_file(argv[1]); +// py_initialize(); + +// if(py_exec(source)){ +// py_Error* err = py_getlasterror(); +// py_Error__print(err); +// } + +// py_finalize(); +// free(source); + +// __HELP: +// printf("Usage: pocketpy [filename]\n"); +// return 0; }