blueloveTH 1 year ago
parent
commit
a03a3bdbf8

+ 0 - 141
include/pocketpy/compiler/compiler.hpp

@@ -1,141 +0,0 @@
-#pragma once
-
-#include "pocketpy/compiler/expr.hpp"
-#include "pocketpy/objects/error.hpp"
-
-namespace pkpy {
-
-struct Compiler;
-typedef Error* (Compiler::*PrattCallback)() noexcept;
-
-struct PrattRule {
-    PrattCallback prefix;
-    PrattCallback infix;
-    Precedence precedence;
-};
-
-struct Compiler {
-    PK_ALWAYS_PASS_BY_POINTER(Compiler)
-
-    static PrattRule rules[TK__COUNT__];
-
-    Lexer lexer;
-    vector<CodeEmitContext> contexts;
-    VM* vm;
-    bool unknown_global_scope;  // for eval/exec() call
-    // for parsing token stream
-    int __i = 0;
-
-    const Token& tk(int i) const noexcept{ return lexer.nexts[i]; }
-    const Token& prev() const noexcept{ return tk(__i - 1); }
-    const Token& curr() const noexcept{ return tk(__i); }
-    const Token& next() const noexcept{ return tk(__i + 1); }
-
-    const Token& err() const noexcept{
-        if(__i >= lexer.nexts.size()) return prev();
-        return curr();
-    }
-
-    void advance(int delta = 1) noexcept{
-        __i += delta;
-#if PK_DEBUG_COMPILER
-        if(__i>=0 && __i<lexer.nexts.size()){
-            printf("%s:%d %s %s\n",
-                lexer.src.filename().c_str(),
-                curr().line,
-                pk_TokenSymbols(curr().type),
-                curr().str().escape().c_str()
-            );
-        }
-#endif
-    }
-
-    CodeEmitContext* ctx() noexcept{ return &contexts.back(); }
-    CompileMode mode() const noexcept{ return lexer.src->mode; }
-
-    NameScope name_scope() const noexcept;
-    CodeObject* push_global_context() noexcept;
-    FuncDecl_ push_f_context(c11_string name, int* out_index) noexcept;
-
-    static void init_pratt_rules() noexcept;
-
-    bool match(TokenIndex expected) noexcept;
-    bool match_end_stmt() noexcept;
-    bool match_newlines(bool* need_more_lines = NULL) noexcept;
-    /*************************************************/
-    [[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`
-
-    template <typename T, typename... Args>
-    T* make_expr(Args&&... args) noexcept{
-        static_assert(sizeof(T) <= kPoolExprBlockSize);
-        static_assert(std::is_base_of_v<Expr, T>);
-        void* p = PoolExpr_alloc();
-        T* expr = new (p) T(std::forward<Args>(args)...);
-        expr->line = prev().line;
-        return expr;
-    }
-
-    [[nodiscard]] Error* consume_comp(Opcode op0, Opcode op1) noexcept;
-    [[nodiscard]] Error* pop_context() noexcept;
-
-    Error* exprLiteral() noexcept;
-    Error* exprLong() noexcept;
-    Error* exprImag() noexcept;
-    Error* exprBytes() noexcept;
-    Error* exprFString() noexcept;
-    Error* exprLambda() noexcept;
-    Error* exprOr() noexcept;
-    Error* exprAnd() noexcept;
-    Error* exprTernary() noexcept;
-    Error* exprBinaryOp() noexcept;
-    Error* exprNot() noexcept;
-    Error* exprUnaryOp() noexcept;
-    Error* exprGroup() noexcept;
-    Error* exprList() noexcept;
-    Error* exprMap() noexcept;
-    Error* exprCall() noexcept;
-    Error* exprName() noexcept;
-    Error* exprAttrib() noexcept;
-    Error* exprSlice0() noexcept;
-    Error* exprSlice1() noexcept;
-    Error* exprSubscr() noexcept;
-    Error* exprLiteral0() noexcept;
-
-    bool is_expression(bool allow_slice = false) noexcept;
-
-    [[nodiscard]] Error* compile_block_body(PrattCallback callback = NULL) noexcept;
-    [[nodiscard]] Error* compile_normal_import() noexcept;
-    [[nodiscard]] Error* compile_from_import() noexcept;
-    [[nodiscard]] Error* parse_expression(int precedence, bool allow_slice = false) noexcept;
-    [[nodiscard]] Error* compile_if_stmt() noexcept;
-    [[nodiscard]] Error* compile_while_loop() noexcept;
-    [[nodiscard]] Error* compile_for_loop() noexcept;
-    [[nodiscard]] Error* compile_try_except() noexcept;
-    [[nodiscard]] Error* compile_decorated() noexcept;
-
-    [[nodiscard]] Error* try_compile_assignment(bool* is_assign) noexcept;
-    [[nodiscard]] Error* compile_stmt() noexcept;
-    [[nodiscard]] Error* consume_type_hints() noexcept;
-    [[nodiscard]] Error* _compile_f_args(FuncDecl* decl, bool enable_type_hints) noexcept;
-    [[nodiscard]] Error* compile_function(int decorators = 0) noexcept;
-    [[nodiscard]] Error* compile_class(int decorators = 0) noexcept;
-
-    PyVar to_object(const TokenValue& value) noexcept;
-
-    [[nodiscard]] Error* read_literal(PyVar* out) noexcept;
-
-    [[nodiscard]] Error* SyntaxError(const char* msg = "invalid syntax", ...) noexcept;
-    [[nodiscard]] Error* IndentationError(const char* msg) noexcept{ return lexer._error(false, "IndentationError", msg, {}); }
-    [[nodiscard]] Error* NeedMoreLines() noexcept{
-        return lexer._error(false, "NeedMoreLines", "", {}, (i64)ctx()->is_compiling_class);
-    }
-
-public:
-    Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope = false) noexcept;
-    [[nodiscard]] Error* compile(CodeObject** out) noexcept;
-    ~Compiler();
-};
-
-}  // namespace pkpy

+ 0 - 17
include/pocketpy/compiler/expr.h

@@ -1,17 +0,0 @@
-#pragma once
-
-#include <stdbool.h>
-#include "pocketpy/common/memorypool.h"
-#include "pocketpy/compiler/lexer.h"
-#include "pocketpy/common/strname.h"
-#include "pocketpy/objects/codeobject.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 464
include/pocketpy/compiler/expr.hpp

@@ -1,464 +0,0 @@
-#pragma once
-
-#include "pocketpy/objects/codeobject.hpp"
-#include "pocketpy/compiler/lexer.hpp"
-
-namespace pkpy {
-
-struct CodeEmitContext;
-struct Expr;
-
-typedef small_vector<Expr*, 4> Expr_vector;
-
-struct Expr {
-    int line = 0;
-    virtual ~Expr() = default;
-    virtual void emit_(CodeEmitContext* ctx) = 0;
-
-    Expr() = default;
-    Expr(const Expr&) = delete;
-    Expr(Expr&&) = delete;
-    Expr& operator=(const Expr&) = delete;
-    Expr& operator=(Expr&&) = delete;
-
-    virtual bool is_literal() const { return false; }
-    virtual bool is_json_object() const { return false; }
-    virtual bool is_attrib() const { return false; }
-    virtual bool is_subscr() const { return false; }
-    virtual bool is_compare() const { return false; }
-    virtual int star_level() const { return 0; }
-    virtual bool is_tuple() const { return false; }
-    virtual bool is_name() const { return false; }
-    bool is_starred() const { return star_level() > 0; }
-
-    // for OP_DELETE_XXX
-    [[nodiscard]] virtual bool emit_del(CodeEmitContext* ctx) { return false; }
-    // for OP_STORE_XXX
-    [[nodiscard]] virtual bool emit_store(CodeEmitContext* ctx) { return false; }
-    virtual void emit_inplace(CodeEmitContext* ctx) { emit_(ctx); }
-    [[nodiscard]] virtual bool emit_store_inplace(CodeEmitContext* ctx) { return emit_store(ctx); }
-};
-
-inline void delete_expr(Expr* p) noexcept{
-    if(!p) return;
-    p->~Expr();
-    PoolExpr_dealloc(p);
-}
-
-struct CodeEmitContext{
-    VM* vm;
-    FuncDecl* func;  // optional, weakref
-    CodeObject* co;  // 1 CodeEmitContext <=> 1 CodeObject*
-    vector<Expr*> _s_expr;
-    int level;
-    vector<StrName> global_names;
-
-    int curr_iblock = 0;
-    bool is_compiling_class = false;
-
-    c11_smallmap_s2n _co_consts_string_dedup_map;
-
-    CodeEmitContext(VM* vm, CodeObject* co, int level) : vm(vm), co(co), level(level) {
-        func = NULL;
-        c11_smallmap_s2n__ctor(&_co_consts_string_dedup_map);
-    }
-
-    int get_loop() const noexcept;
-    CodeBlock* enter_block(CodeBlockType type) noexcept;
-    void exit_block() noexcept;
-    int emit_(Opcode opcode, uint16_t arg, int line, bool is_virtual = false) noexcept;
-    void revert_last_emit_() noexcept;
-    int emit_int(i64 value, int line) noexcept;
-    void patch_jump(int index) noexcept;
-    bool add_label(StrName name) noexcept;
-    int add_varname(StrName name) noexcept;
-    int add_const(PyVar) noexcept;
-    int add_const_string(std::string_view) noexcept;
-    void emit_store_name(NameScope scope, StrName name, int line) noexcept;
-    void try_merge_for_iter_store(int) noexcept;
-    // emit top -> pop -> delete
-    void s_emit_top() noexcept{
-        s_debug_info("s_emit_top");
-        Expr* e = _s_expr.popx_back();
-        e->emit_(this);
-        delete_expr(e);
-    }
-    // push
-    void s_push(Expr* expr) noexcept{
-        s_debug_info("s_push");
-        _s_expr.push_back(expr);
-    }
-    // top
-    Expr* s_top() noexcept{
-        return _s_expr.back();
-    }
-    // size
-    int s_size() const noexcept{
-        return _s_expr.size();
-    }
-    // pop -> delete
-    void s_pop() noexcept{
-        s_debug_info("s_pop");
-        Expr* e = _s_expr.popx_back();
-        delete_expr(e);
-    }
-    // pop move
-    Expr* s_popx() noexcept{
-        s_debug_info("s_popx");
-        return _s_expr.popx_back();
-    }
-    // clean
-    void s_clean() noexcept{
-        s_debug_info("s_clean");
-        c11_smallmap_s2n__dtor(&_co_consts_string_dedup_map);
-        for(Expr* e: _s_expr) delete_expr(e);
-        _s_expr.clear();
-    }
-    // emit decorators
-    void s_emit_decorators(int count) noexcept;
-    // debug stack
-#if PK_DEBUG_COMPILER
-    void s_debug_info(const char* op) noexcept{
-        SStream ss;
-        for(int i=0; i<s_size(); i++) {
-            Expr* e = _s_expr[i];
-            ss << typeid(*e).name();
-            if(i != s_size() - 1) ss << ", ";
-        }
-        printf("[%s] %s\n", ss.str().c_str(), op);
-    }
-#else
-    void s_debug_info(const char*) noexcept{}
-#endif
-};
-
-struct NameExpr : Expr {
-    StrName name;
-    NameScope scope;
-
-    NameExpr(StrName name, NameScope scope) : name(name), scope(scope) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-    bool emit_del(CodeEmitContext* ctx) override;
-    bool emit_store(CodeEmitContext* ctx) override;
-
-    bool is_name() const override { return true; }
-};
-
-struct _UnaryExpr : Expr {
-    Expr* child;
-    _UnaryExpr(Expr* child) : child(child) {}
-    _UnaryExpr() : child(nullptr) {}
-    ~_UnaryExpr() { delete_expr(child); }
-};
-
-struct _BinaryExpr : Expr {
-    Expr* lhs;
-    Expr* rhs;
-    _BinaryExpr(Expr* lhs, Expr* rhs) : lhs(lhs), rhs(rhs) {}
-    _BinaryExpr() : lhs(nullptr), rhs(nullptr) {}
-    ~_BinaryExpr() {
-        delete_expr(lhs);
-        delete_expr(rhs);
-    }
-};
-
-struct InvertExpr : _UnaryExpr {
-    using _UnaryExpr::_UnaryExpr;
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct StarredExpr : _UnaryExpr {
-    int level;
-
-    StarredExpr(Expr* child, int level) : _UnaryExpr(child), level(level) {}
-
-    int star_level() const override { return level; }
-
-    void emit_(CodeEmitContext* ctx) override;
-    bool emit_store(CodeEmitContext* ctx) override;
-};
-
-struct NotExpr : _UnaryExpr {
-    using _UnaryExpr::_UnaryExpr;
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct AndExpr : _BinaryExpr {
-    using _BinaryExpr::_BinaryExpr;
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct OrExpr : _BinaryExpr {
-    using _BinaryExpr::_BinaryExpr;
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-// [None, True, False, ...]
-struct Literal0Expr : Expr {
-    TokenIndex token;
-
-    Literal0Expr(TokenIndex token) : token(token) {}
-
-    bool is_json_object() const override { return true; }
-
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct LongExpr : Expr {
-    Str s;
-
-    LongExpr(const Str& s) : s(s) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct BytesExpr : Expr {
-    Str s;
-
-    BytesExpr(const Str& s) : s(s) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct ImagExpr : Expr {
-    f64 value;
-
-    ImagExpr(f64 value) : value(value) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-// @num, @str which needs to invoke OP_LOAD_CONST
-struct LiteralExpr : Expr {
-    TokenValue value;
-
-    LiteralExpr(TokenValue value) : value(value) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-
-    bool is_literal() const override { return true; }
-
-    bool is_json_object() const override { return true; }
-};
-
-struct NegatedExpr : _UnaryExpr {
-    using _UnaryExpr::_UnaryExpr;
-    void emit_(CodeEmitContext* ctx) override;
-    bool is_json_object() const override { return child->is_literal(); }
-};
-
-struct SliceExpr : Expr {
-    Expr* start = nullptr;
-    Expr* stop = nullptr;
-    Expr* step = nullptr;
-
-    void emit_(CodeEmitContext* ctx) override;
-
-    ~SliceExpr() {
-        delete_expr(start);
-        delete_expr(stop);
-        delete_expr(step);
-    }
-};
-
-struct DictItemExpr : Expr {
-    Expr* key;  // maybe nullptr if it is **kwargs
-    Expr* value;
-
-    DictItemExpr(): key(nullptr), value(nullptr) {}
-
-    int star_level() const override { return value->star_level(); }
-
-    void emit_(CodeEmitContext* ctx) override;
-
-    ~DictItemExpr() {
-        delete_expr(key);
-        delete_expr(value);
-    }
-};
-
-struct SequenceExpr : Expr {
-    array<Expr*> items;
-
-    SequenceExpr(int count) : items(count) {}
-
-    virtual Opcode opcode() const = 0;
-
-    void emit_(CodeEmitContext* ctx) override {
-        for(auto& item: items) item->emit_(ctx);
-        ctx->emit_(opcode(), items.size(), line);
-    }
-
-    ~SequenceExpr() {
-        for(Expr* item: items) delete_expr(item);
-    }
-};
-
-struct ListExpr : SequenceExpr {
-    using SequenceExpr::SequenceExpr;
-
-    Opcode opcode() const override {
-        for(auto& e: items)
-            if(e->is_starred()) return OP_BUILD_LIST_UNPACK;
-        return OP_BUILD_LIST;
-    }
-
-    bool is_json_object() const override { return true; }
-};
-
-struct DictExpr : SequenceExpr {
-    using SequenceExpr::SequenceExpr;
-
-    Opcode opcode() const override {
-        for(auto& e: items)
-            if(e->is_starred()) return OP_BUILD_DICT_UNPACK;
-        return OP_BUILD_DICT;
-    }
-
-    bool is_json_object() const override { return true; }
-};
-
-struct SetExpr : SequenceExpr {
-    using SequenceExpr::SequenceExpr;
-
-    Opcode opcode() const override {
-        for(auto& e: items)
-            if(e->is_starred()) return OP_BUILD_SET_UNPACK;
-        return OP_BUILD_SET;
-    }
-};
-
-struct TupleExpr : SequenceExpr {
-    using SequenceExpr::SequenceExpr;
-
-    bool is_tuple() const override { return true; }
-
-    Opcode opcode() const override {
-        for(auto& e: items)
-            if(e->is_starred()) return OP_BUILD_TUPLE_UNPACK;
-        return OP_BUILD_TUPLE;
-    }
-
-    bool emit_store(CodeEmitContext* ctx) override;
-    bool emit_del(CodeEmitContext* ctx) override;
-};
-
-struct CompExpr : Expr {
-    Expr* expr = nullptr;  // loop expr
-    Expr* vars = nullptr;  // loop vars
-    Expr* iter = nullptr;  // loop iter
-    Expr* cond = nullptr;  // optional if condition
-
-    Opcode op0;
-    Opcode op1;
-
-    CompExpr(Opcode op0, Opcode op1) : op0(op0), op1(op1) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-
-    ~CompExpr() {
-        delete_expr(expr);
-        delete_expr(vars);
-        delete_expr(iter);
-        delete_expr(cond);
-    }
-};
-
-struct LambdaExpr : Expr {
-    int index;
-
-    LambdaExpr(int index) : index(index) {}
-
-    void emit_(CodeEmitContext* ctx) override {
-        ctx->emit_(OP_LOAD_FUNCTION, index, line);
-    }
-};
-
-struct FStringExpr : Expr {
-    Str src;
-
-    FStringExpr(const Str& src) : src(src) {}
-
-    void _load_simple_expr(CodeEmitContext* ctx, Str expr);
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct SubscrExpr : _BinaryExpr {
-    using _BinaryExpr::_BinaryExpr;
-    bool is_subscr() const override { return true; }
-
-    void emit_(CodeEmitContext* ctx) override;
-    bool emit_del(CodeEmitContext* ctx) override;
-    bool emit_store(CodeEmitContext* ctx) override;
-
-    void emit_inplace(CodeEmitContext* ctx) override;
-    bool emit_store_inplace(CodeEmitContext* ctx) override;
-};
-
-struct AttribExpr : _UnaryExpr {
-    StrName name;
-
-    AttribExpr(Expr* child, StrName name) : _UnaryExpr(child), name(name) {}
-
-    void emit_(CodeEmitContext* ctx) override;
-    bool emit_del(CodeEmitContext* ctx) override;
-    bool emit_store(CodeEmitContext* ctx) override;
-    void emit_method(CodeEmitContext* ctx);
-
-    bool is_attrib() const override { return true; }
-
-    void emit_inplace(CodeEmitContext* ctx) override;
-    bool emit_store_inplace(CodeEmitContext* ctx) override;
-};
-
-struct CallExpr : Expr {
-    Expr* callable;
-    Expr_vector args;
-    // **a will be interpreted as a special keyword argument: {"**": a}
-    vector<pair<StrName, Expr*>> kwargs;
-    void emit_(CodeEmitContext* ctx) override;
-
-    ~CallExpr() {
-        delete_expr(callable);
-        for(Expr* arg: args) delete_expr(arg);
-        for(auto [_, arg]: kwargs) delete_expr(arg);
-    }
-};
-
-struct GroupedExpr : _UnaryExpr {
-    using _UnaryExpr::_UnaryExpr;
-    void emit_(CodeEmitContext* ctx) override { child->emit_(ctx); }
-
-    bool emit_del(CodeEmitContext* ctx) override { return child->emit_del(ctx); }
-
-    bool emit_store(CodeEmitContext* ctx) override { return child->emit_store(ctx); }
-};
-
-struct BinaryExpr : _BinaryExpr {
-    TokenIndex op;
-    bool inplace;
-
-    BinaryExpr(TokenIndex op, bool inplace = false)
-        : _BinaryExpr(), op(op), inplace(inplace) {}
-
-    bool is_compare() const override;
-    void _emit_compare(CodeEmitContext*, small_vector_2<int, 8>&);
-    void emit_(CodeEmitContext* ctx) override;
-};
-
-struct TernaryExpr : Expr {
-    Expr* cond = nullptr;
-    Expr* true_expr = nullptr;
-    Expr* false_expr = nullptr;
-
-    void emit_(CodeEmitContext* ctx) override;
-
-    ~TernaryExpr() {
-        delete_expr(cond);
-        delete_expr(true_expr);
-        delete_expr(false_expr);
-    }
-};
-
-}  // namespace pkpy

+ 176 - 222
src/compiler/compiler.c

@@ -1,6 +1,8 @@
 #include "pocketpy/compiler/compiler.h"
-#include "pocketpy/compiler/expr.h"
 #include "pocketpy/compiler/lexer.h"
+#include "pocketpy/objects/sourcedata.h"
+#include "pocketpy/common/strname.h"
+#include "pocketpy/common/memorypool.h"
 #include <ctype.h>
 
 /* expr.h */
@@ -18,23 +20,25 @@ typedef struct ExprVt {
     /* reflections */
     bool is_literal;
     bool is_json_object;
-    bool is_name;       // NameExpr
-    bool is_tuple;      // TupleExpr
-    bool is_attrib;     // AttribExpr
-    bool is_subscr;     // SubscrExpr
-    bool is_starred;    // StarredExpr
-    bool is_binary;     // BinaryExpr
+    bool is_name;     // NameExpr
+    bool is_tuple;    // TupleExpr
+    bool is_attrib;   // AttribExpr
+    bool is_subscr;   // SubscrExpr
+    bool is_starred;  // StarredExpr
+    bool is_binary;   // BinaryExpr
     void (*dtor)(Expr*);
 } ExprVt;
 
 #define static_assert_expr_size(T) static_assert(sizeof(T) <= kPoolExprBlockSize, "")
 
-#define vtcall(f, self, ctx)        ((self)->vt->f((self), (ctx)))
-#define vtemit_(self, ctx)          vtcall(emit_, (self), (ctx))
-#define vtemit_del(self, ctx)       ((self)->vt->emit_del ? vtcall(emit_del, self, ctx) : false)
-#define vtemit_store(self, ctx)     ((self)->vt->emit_store ? vtcall(emit_store, self, ctx) : false)
-#define vtemit_inplace(self, ctx)   ((self)->vt->emit_inplace ? vtcall(emit_inplace, self, ctx) : vtemit_(self, ctx))
-#define vtemit_istore(self, ctx)    ((self)->vt->emit_istore ? vtcall(emit_istore, self, ctx) : vtemit_store(self, ctx))
+#define vtcall(f, self, ctx) ((self)->vt->f((self), (ctx)))
+#define vtemit_(self, ctx) vtcall(emit_, (self), (ctx))
+#define vtemit_del(self, ctx) ((self)->vt->emit_del ? vtcall(emit_del, self, ctx) : false)
+#define vtemit_store(self, ctx) ((self)->vt->emit_store ? vtcall(emit_store, self, ctx) : false)
+#define vtemit_inplace(self, ctx)                                                                  \
+    ((self)->vt->emit_inplace ? vtcall(emit_inplace, self, ctx) : vtemit_(self, ctx))
+#define vtemit_istore(self, ctx)                                                                   \
+    ((self)->vt->emit_istore ? vtcall(emit_istore, self, ctx) : vtemit_store(self, ctx))
 
 #define COMMON_HEADER                                                                              \
     const ExprVt* vt;                                                                              \
@@ -44,7 +48,7 @@ typedef struct Expr {
     COMMON_HEADER
 } Expr;
 
-static void Expr__delete(Expr* self){
+static void Expr__delete(Expr* self) {
     if(!self) return;
     if(self->vt->dtor) self->vt->dtor(self);
     PoolExpr_dealloc(self);
@@ -149,12 +153,10 @@ bool NameExpr__emit_store(Expr* self_, Ctx* ctx) {
 }
 
 NameExpr* NameExpr__new(StrName name, NameScope scope) {
-    const static ExprVt Vt = {
-        .emit_ = NameExpr__emit_,
-        .emit_del = NameExpr__emit_del,
-        .emit_store = NameExpr__emit_store,
-        .is_name = true
-    };
+    const static ExprVt Vt = {.emit_ = NameExpr__emit_,
+                              .emit_del = NameExpr__emit_del,
+                              .emit_store = NameExpr__emit_store,
+                              .is_name = true};
     static_assert_expr_size(NameExpr);
     NameExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -183,12 +185,10 @@ bool StarredExpr__emit_store(Expr* self_, Ctx* ctx) {
     return vtemit_store(self->child, ctx);
 }
 
-StarredExpr* StarredExpr__new(Expr* child, int level){
-    const static ExprVt Vt = {
-        .emit_ = StarredExpr__emit_,
-        .emit_store = StarredExpr__emit_store,
-        .is_starred = true
-    };
+StarredExpr* StarredExpr__new(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;
@@ -206,7 +206,7 @@ typedef struct UnaryExpr {
     Opcode opcode;
 } UnaryExpr;
 
-void UnaryExpr__dtor(Expr* self_){
+void UnaryExpr__dtor(Expr* self_) {
     UnaryExpr* self = (UnaryExpr*)self_;
     Expr__delete(self->child);
 }
@@ -217,11 +217,8 @@ static void UnaryExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line);
 }
 
-UnaryExpr* UnaryExpr__new(Expr* child, Opcode opcode){
-    const static ExprVt Vt = {
-        .emit_ = UnaryExpr__emit_,
-        .dtor = UnaryExpr__dtor
-    };
+UnaryExpr* UnaryExpr__new(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;
@@ -245,10 +242,8 @@ void RawStringExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line);
 }
 
-RawStringExpr* RawStringExpr__new(c11_string value, Opcode opcode){
-    const static ExprVt Vt = {
-        .emit_ = RawStringExpr__emit_
-    };
+RawStringExpr* RawStringExpr__new(c11_string value, Opcode opcode) {
+    const static ExprVt Vt = {.emit_ = RawStringExpr__emit_};
     static_assert_expr_size(RawStringExpr);
     RawStringExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -272,10 +267,8 @@ void ImagExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__emit_(ctx, OP_BUILD_IMAG, BC_NOARG, self->line);
 }
 
-ImagExpr* ImagExpr__new(double value){
-    const static ExprVt Vt = {
-        .emit_ = ImagExpr__emit_
-    };
+ImagExpr* ImagExpr__new(double value) {
+    const static ExprVt Vt = {.emit_ = ImagExpr__emit_};
     static_assert_expr_size(ImagExpr);
     ImagExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -291,7 +284,7 @@ typedef struct LiteralExpr {
 
 void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
     LiteralExpr* self = (LiteralExpr*)self_;
-    switch(self->value->index){
+    switch(self->value->index) {
         case TokenValue_I64: {
             int64_t val = self->value->_i64;
             Ctx__emit_int(ctx, val, self->line);
@@ -314,12 +307,10 @@ void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
     }
 }
 
-LiteralExpr* LiteralExpr__new(const TokenValue* value){
-    const static ExprVt Vt = {
-        .emit_ = LiteralExpr__emit_,
-        .is_literal = true,
-        .is_json_object = true
-    };
+LiteralExpr* LiteralExpr__new(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;
@@ -335,7 +326,7 @@ typedef struct SliceExpr {
     Expr* step;
 } SliceExpr;
 
-void SliceExpr__dtor(Expr* self_){
+void SliceExpr__dtor(Expr* self_) {
     SliceExpr* self = (SliceExpr*)self_;
     Expr__delete(self->start);
     Expr__delete(self->stop);
@@ -344,20 +335,23 @@ void SliceExpr__dtor(Expr* self_){
 
 void SliceExpr__emit_(Expr* self_, Ctx* ctx) {
     SliceExpr* self = (SliceExpr*)self_;
-    if(self->start) vtemit_(self->start, ctx);
-    else Ctx__emit_(ctx, OP_LOAD_NONE, BC_NOARG, self->line);
-    if(self->stop) vtemit_(self->stop, ctx);
-    else Ctx__emit_(ctx, OP_LOAD_NONE, BC_NOARG, self->line);
-    if(self->step) vtemit_(self->step, ctx);
-    else Ctx__emit_(ctx, OP_LOAD_NONE, BC_NOARG, self->line);
+    if(self->start)
+        vtemit_(self->start, ctx);
+    else
+        Ctx__emit_(ctx, OP_LOAD_NONE, BC_NOARG, self->line);
+    if(self->stop)
+        vtemit_(self->stop, ctx);
+    else
+        Ctx__emit_(ctx, OP_LOAD_NONE, BC_NOARG, self->line);
+    if(self->step)
+        vtemit_(self->step, ctx);
+    else
+        Ctx__emit_(ctx, OP_LOAD_NONE, BC_NOARG, self->line);
     Ctx__emit_(ctx, OP_BUILD_SLICE, BC_NOARG, self->line);
 }
 
-SliceExpr* SliceExpr__new(){
-    const static ExprVt Vt = {
-        .dtor = SliceExpr__dtor,
-        .emit_ = SliceExpr__emit_
-    };
+SliceExpr* SliceExpr__new() {
+    const static ExprVt Vt = {.dtor = SliceExpr__dtor, .emit_ = SliceExpr__emit_};
     static_assert_expr_size(SliceExpr);
     SliceExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -371,20 +365,20 @@ SliceExpr* SliceExpr__new(){
 // ListExpr, DictExpr, SetExpr, TupleExpr
 typedef struct SequenceExpr {
     COMMON_HEADER
-    c11_array/*T=Expr* */ items;
+    c11_array /*T=Expr* */ items;
     Opcode opcode;
 } SequenceExpr;
 
 static void SequenceExpr__emit_(Expr* self_, Ctx* ctx) {
     SequenceExpr* self = (SequenceExpr*)self_;
-    for(int i=0; i<self->items.count; i++){
+    for(int i = 0; i < self->items.count; i++) {
         Expr* item = c11__getitem(Expr*, &self->items, i);
         vtemit_(item, ctx);
     }
     Ctx__emit_(ctx, self->opcode, self->items.count, self->line);
 }
 
-void SequenceExpr__dtor(Expr* self_){
+void SequenceExpr__dtor(Expr* self_) {
     SequenceExpr* self = (SequenceExpr*)self_;
     c11__foreach(Expr*, &self->items, e) Expr__delete(*e);
     c11_array__dtor(&self->items);
@@ -397,10 +391,12 @@ bool TupleExpr__emit_store(Expr* self_, Ctx* ctx) {
     int starred_i = -1;
     for(int i = 0; i < self->items.count; i++) {
         Expr* e = c11__getitem(Expr*, &self->items, i);
-        if(e->vt->is_starred){
-            if(((StarredExpr*)e)->level > 0){
-                if(starred_i == -1) starred_i = i;
-                else return false;  // multiple StarredExpr not allowed
+        if(e->vt->is_starred) {
+            if(((StarredExpr*)e)->level > 0) {
+                if(starred_i == -1)
+                    starred_i = i;
+                else
+                    return false;  // multiple StarredExpr not allowed
             }
         }
     }
@@ -438,14 +434,14 @@ bool TupleExpr__emit_store(Expr* self_, Ctx* ctx) {
 
 bool TupleExpr__emit_del(Expr* self_, Ctx* ctx) {
     SequenceExpr* self = (SequenceExpr*)self_;
-    c11__foreach(Expr*, &self->items, e){
+    c11__foreach(Expr*, &self->items, e) {
         bool ok = vtemit_del(*e, ctx);
         if(!ok) return false;
     }
     return true;
 }
 
-static SequenceExpr* SequenceExpr__new(const ExprVt* vt, int count, Opcode opcode){
+static SequenceExpr* SequenceExpr__new(const ExprVt* vt, int count, Opcode opcode) {
     static_assert_expr_size(SequenceExpr);
     SequenceExpr* self = PoolExpr_alloc();
     self->vt = vt;
@@ -455,25 +451,21 @@ static SequenceExpr* SequenceExpr__new(const ExprVt* vt, int count, Opcode opcod
     return self;
 }
 
-SequenceExpr* ListExpr__new(int count){
-    const static ExprVt ListExprVt = {
-        .dtor = SequenceExpr__dtor,
-        .emit_ = SequenceExpr__emit_,
-        .is_json_object = true
-    };
+SequenceExpr* ListExpr__new(int count) {
+    const static ExprVt ListExprVt = {.dtor = SequenceExpr__dtor,
+                                      .emit_ = SequenceExpr__emit_,
+                                      .is_json_object = true};
     return SequenceExpr__new(&ListExprVt, count, OP_BUILD_LIST);
 }
 
-SequenceExpr* DictExpr__new(int count){
-    const static ExprVt DictExprVt = {
-        .dtor = SequenceExpr__dtor,
-        .emit_ = SequenceExpr__emit_,
-        .is_json_object = true
-    };
+SequenceExpr* DictExpr__new(int count) {
+    const static ExprVt DictExprVt = {.dtor = SequenceExpr__dtor,
+                                      .emit_ = SequenceExpr__emit_,
+                                      .is_json_object = true};
     return SequenceExpr__new(&DictExprVt, count, OP_BUILD_DICT);
 }
 
-SequenceExpr* SetExpr__new(int count){
+SequenceExpr* SetExpr__new(int count) {
     const static ExprVt SetExprVt = {
         .dtor = SequenceExpr__dtor,
         .emit_ = SequenceExpr__emit_,
@@ -481,14 +473,12 @@ SequenceExpr* SetExpr__new(int count){
     return SequenceExpr__new(&SetExprVt, count, OP_BUILD_SET);
 }
 
-SequenceExpr* TupleExpr__new(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
-    };
+SequenceExpr* TupleExpr__new(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);
 }
 
@@ -503,7 +493,7 @@ typedef struct CompExpr {
     Opcode op1;
 } CompExpr;
 
-void CompExpr__dtor(Expr* self_){
+void CompExpr__dtor(Expr* self_) {
     CompExpr* self = (CompExpr*)self_;
     Expr__delete(self->expr);
     Expr__delete(self->vars);
@@ -537,11 +527,8 @@ void CompExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__exit_block(ctx);
 }
 
-CompExpr* CompExpr__new(Opcode op0, Opcode op1){
-    const static ExprVt Vt = {
-        .dtor = CompExpr__dtor,
-        .emit_ = CompExpr__emit_
-    };
+CompExpr* CompExpr__new(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;
@@ -565,10 +552,8 @@ static void LambdaExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__emit_(ctx, OP_LOAD_FUNCTION, self->index, self->line);
 }
 
-LambdaExpr* LambdaExpr__new(int index){
-    const static ExprVt Vt = {
-        .emit_ = LambdaExpr__emit_
-    };
+LambdaExpr* LambdaExpr__new(int index) {
+    const static ExprVt Vt = {.emit_ = LambdaExpr__emit_};
     static_assert_expr_size(LambdaExpr);
     LambdaExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -591,14 +576,14 @@ static bool is_fmt_valid_char(char c) {
         case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
         return true;
         default: return false;
-        // clang-format on
+            // clang-format on
     }
 }
 
 static bool is_identifier(c11_string s) {
     if(s.size == 0) return false;
     if(!isalpha(s.data[0]) && s.data[0] != '_') return false;
-    for(int i=0; i<s.size; i++){
+    for(int i = 0; i < s.size; i++) {
         char c = s.data[i];
         if(!isalnum(c) && c != '_') return false;
     }
@@ -612,11 +597,11 @@ static void _load_simple_expr(Ctx* ctx, c11_string expr, int line) {
         switch(expr_end[-1]) {
             case 'r':
                 repr = true;
-                expr.size -= 2; // expr[:-2]
+                expr.size -= 2;  // expr[:-2]
                 break;
             case 's':
                 repr = false;
-                expr.size -= 2; // expr[:-2]
+                expr.size -= 2;  // expr[:-2]
                 break;
             default: break;  // nothing happens
         }
@@ -625,18 +610,13 @@ static void _load_simple_expr(Ctx* ctx, c11_string expr, int line) {
     bool is_fastpath = false;
     if(is_identifier(expr)) {
         // ctx->emit_(OP_LOAD_NAME, StrName(expr.sv()).index, line);
-        Ctx__emit_(
-            ctx,
-            OP_LOAD_NAME,
-            pk_StrName__map2(expr),
-            line
-        );
+        Ctx__emit_(ctx, OP_LOAD_NAME, pk_StrName__map2(expr), line);
         is_fastpath = true;
     } else {
         int dot = c11_string__index(expr, '.');
         if(dot > 0) {
-            c11_string a = {expr.data, dot};    // expr[:dot]
-            c11_string b = {expr.data+(dot+1), expr.size-(dot+1)};  // expr[dot+1:]
+            c11_string a = {expr.data, dot};                                // expr[:dot]
+            c11_string b = {expr.data + (dot + 1), expr.size - (dot + 1)};  // expr[dot+1:]
             if(is_identifier(a) && is_identifier(b)) {
                 Ctx__emit_(ctx, OP_LOAD_NAME, pk_StrName__map2(a), line);
                 Ctx__emit_(ctx, OP_LOAD_ATTR, pk_StrName__map2(b), line);
@@ -650,9 +630,7 @@ static void _load_simple_expr(Ctx* ctx, c11_string expr, int line) {
         Ctx__emit_(ctx, OP_FSTRING_EVAL, index, line);
     }
 
-    if(repr) {
-        Ctx__emit_(ctx, OP_REPR, BC_NOARG, line);
-    }
+    if(repr) { Ctx__emit_(ctx, OP_REPR, BC_NOARG, line); }
 }
 
 static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
@@ -667,11 +645,12 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
         if(flag) {
             if(src[j] == '}') {
                 // add expression
-                c11_string expr = {src+i, j-i}; // src[i:j]
+                c11_string expr = {src + i, j - i};  // src[i:j]
                 // BUG: ':' is not a format specifier in f"{stack[2:]}"
                 int conon = c11_string__index(expr, ':');
                 if(conon >= 0) {
-                    c11_string spec = {expr.data+(conon+1), expr.size-(conon+1)};  // expr[conon+1:]
+                    c11_string spec = {expr.data + (conon + 1),
+                                       expr.size - (conon + 1)};  // expr[conon+1:]
                     // filter some invalid spec
                     bool ok = true;
                     for(int k = 0; k < spec.size; k++) {
@@ -685,7 +664,10 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
                         expr.size = conon;  // expr[:conon]
                         _load_simple_expr(ctx, expr, self->line);
                         // ctx->emit_(OP_FORMAT_STRING, ctx->add_const_string(spec.sv()), line);
-                        Ctx__emit_(ctx, OP_FORMAT_STRING, Ctx__add_const_string(ctx, spec), self->line);
+                        Ctx__emit_(ctx,
+                                   OP_FORMAT_STRING,
+                                   Ctx__add_const_string(ctx, spec),
+                                   self->line);
                     } else {
                         // ':' is not a spec indicator
                         _load_simple_expr(ctx, expr, self->line);
@@ -702,12 +684,10 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
                 if(j + 1 < self->src.size && src[j + 1] == '{') {
                     // {{ -> {
                     j++;
-                    Ctx__emit_(
-                        ctx,
-                        OP_LOAD_CONST,
-                        Ctx__add_const_string(ctx, (c11_string){"{", 1}),
-                        self->line
-                    );
+                    Ctx__emit_(ctx,
+                               OP_LOAD_CONST,
+                               Ctx__add_const_string(ctx, (c11_string){"{", 1}),
+                               self->line);
                     count++;
                 } else {
                     // { -> }
@@ -719,12 +699,10 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
                 if(j + 1 < self->src.size && src[j + 1] == '}') {
                     // }} -> }
                     j++;
-                    Ctx__emit_(
-                        ctx,
-                        OP_LOAD_CONST,
-                        Ctx__add_const_string(ctx, (c11_string){"}", 1}),
-                        self->line
-                    );
+                    Ctx__emit_(ctx,
+                               OP_LOAD_CONST,
+                               Ctx__add_const_string(ctx, (c11_string){"}", 1}),
+                               self->line);
                     count++;
                 } else {
                     // } -> error
@@ -736,13 +714,8 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
                 i = j;
                 while(j < self->src.size && src[j] != '{' && src[j] != '}')
                     j++;
-                c11_string literal = {src+i, j-i};  // src[i:j]
-                Ctx__emit_(
-                    ctx,
-                    OP_LOAD_CONST,
-                    Ctx__add_const_string(ctx, literal),
-                    self->line
-                );
+                c11_string literal = {src + i, j - i};  // src[i:j]
+                Ctx__emit_(ctx, OP_LOAD_CONST, Ctx__add_const_string(ctx, literal), self->line);
                 count++;
                 continue;  // skip j++
             }
@@ -752,17 +725,15 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
 
     if(flag) {
         // literal
-        c11_string literal = {src+i, self->src.size-i}; // src[i:]
+        c11_string literal = {src + i, self->src.size - i};  // src[i:]
         Ctx__emit_(ctx, OP_LOAD_CONST, Ctx__add_const_string(ctx, literal), self->line);
         count++;
     }
     Ctx__emit_(ctx, OP_BUILD_STRING, count, self->line);
 }
 
-FStringExpr* FStringExpr__new(c11_string src){
-    const static ExprVt Vt = {
-        .emit_ = FStringExpr__emit_
-    };
+FStringExpr* FStringExpr__new(c11_string src) {
+    const static ExprVt Vt = {.emit_ = FStringExpr__emit_};
     static_assert_expr_size(FStringExpr);
     FStringExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -779,7 +750,7 @@ typedef struct LogicBinaryExpr {
     Opcode opcode;
 } LogicBinaryExpr;
 
-void LogicBinaryExpr__dtor(Expr* self_){
+void LogicBinaryExpr__dtor(Expr* self_) {
     LogicBinaryExpr* self = (LogicBinaryExpr*)self_;
     Expr__delete(self->lhs);
     Expr__delete(self->rhs);
@@ -793,11 +764,8 @@ void LogicBinaryExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__patch_jump(ctx, patch);
 }
 
-LogicBinaryExpr* LogicBinaryExpr__new(Expr* lhs, Expr* rhs, Opcode opcode){
-    const static ExprVt Vt = {
-        .emit_ = LogicBinaryExpr__emit_,
-        .dtor = LogicBinaryExpr__dtor
-    };
+LogicBinaryExpr* LogicBinaryExpr__new(Expr* lhs, Expr* rhs, Opcode opcode) {
+    const static ExprVt Vt = {.emit_ = LogicBinaryExpr__emit_, .dtor = LogicBinaryExpr__dtor};
     static_assert_expr_size(LogicBinaryExpr);
     LogicBinaryExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -813,7 +781,7 @@ typedef struct GroupedExpr {
     Expr* child;
 } GroupedExpr;
 
-void GroupedExpr__dtor(Expr* self_){
+void GroupedExpr__dtor(Expr* self_) {
     GroupedExpr* self = (GroupedExpr*)self_;
     Expr__delete(self->child);
 }
@@ -833,13 +801,11 @@ bool GroupedExpr__emit_store(Expr* self_, Ctx* ctx) {
     return vtemit_store(self->child, ctx);
 }
 
-GroupedExpr* GroupedExpr__new(Expr* child){
-    const static ExprVt Vt = {
-        .dtor = GroupedExpr__dtor,
-        .emit_ = GroupedExpr__emit_,
-        .emit_del = GroupedExpr__emit_del,
-        .emit_store = GroupedExpr__emit_store
-    };
+GroupedExpr* GroupedExpr__new(Expr* child) {
+    const static ExprVt Vt = {.dtor = GroupedExpr__dtor,
+                              .emit_ = GroupedExpr__emit_,
+                              .emit_del = GroupedExpr__emit_del,
+                              .emit_store = GroupedExpr__emit_store};
     static_assert_expr_size(GroupedExpr);
     GroupedExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -856,13 +822,13 @@ typedef struct BinaryExpr {
     bool inplace;
 } BinaryExpr;
 
-static void BinaryExpr__dtor(Expr* self_){
+static void BinaryExpr__dtor(Expr* self_) {
     BinaryExpr* self = (BinaryExpr*)self_;
     Expr__delete(self->lhs);
     Expr__delete(self->rhs);
 }
 
-static Opcode cmp_token2op(TokenIndex token){
+static Opcode cmp_token2op(TokenIndex token) {
     switch(token) {
         case TK_LT: return OP_COMPARE_LT; break;
         case TK_LE: return OP_COMPARE_LE; break;
@@ -870,21 +836,21 @@ static Opcode cmp_token2op(TokenIndex token){
         case TK_NE: return OP_COMPARE_NE; break;
         case TK_GT: return OP_COMPARE_GT; break;
         case TK_GE: return OP_COMPARE_GE; break;
-        default: return OP_NO_OP;   // 0
+        default: return OP_NO_OP;  // 0
     }
 }
 
-#define is_compare_expr(e)  ((e)->vt->is_binary && cmp_token2op(((BinaryExpr*)(e))->op))
+#define is_compare_expr(e) ((e)->vt->is_binary && cmp_token2op(((BinaryExpr*)(e))->op))
 
 static void _emit_compare(BinaryExpr* self, Ctx* ctx, c11_vector* jmps) {
     if(is_compare_expr(self->lhs)) {
         _emit_compare((BinaryExpr*)self->lhs, ctx, jmps);
     } else {
-        vtemit_(self->lhs, ctx);        // [a]
-    }                               
-    vtemit_(self->rhs, ctx);            // [a, b]
-    Ctx__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line);       // [a, b, b]
-    Ctx__emit_(ctx, OP_ROT_THREE, BC_NOARG, self->line);     // [b, a, b]
+        vtemit_(self->lhs, ctx);  // [a]
+    }
+    vtemit_(self->rhs, ctx);                              // [a, b]
+    Ctx__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line);    // [a, b, b]
+    Ctx__emit_(ctx, OP_ROT_THREE, BC_NOARG, self->line);  // [b, a, b]
     Opcode opcode = cmp_token2op(self->op);
     Ctx__emit_(ctx, opcode, BC_NOARG, self->line);
     // [b, RES]
@@ -894,7 +860,7 @@ static void _emit_compare(BinaryExpr* self, Ctx* ctx, c11_vector* jmps) {
 
 static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
     BinaryExpr* self = (BinaryExpr*)self_;
-    c11_vector/*T=int*/ jmps;
+    c11_vector /*T=int*/ jmps;
     c11_vector__ctor(&jmps, sizeof(int));
     if(cmp_token2op(self->op) && is_compare_expr(self->lhs)) {
         // (a < b) < c
@@ -945,9 +911,7 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
 
     Ctx__emit_(ctx, opcode, BC_NOARG, self->line);
 
-    c11__foreach(int, &jmps, i) {
-        Ctx__patch_jump(ctx, *i);
-    }
+    c11__foreach(int, &jmps, i) { Ctx__patch_jump(ctx, *i); }
 }
 
 typedef struct TernaryExpr {
@@ -957,7 +921,7 @@ typedef struct TernaryExpr {
     Expr* false_expr;
 } TernaryExpr;
 
-void TernaryExpr__dtor(Expr* self_){
+void TernaryExpr__dtor(Expr* self_) {
     TernaryExpr* self = (TernaryExpr*)self_;
     Expr__delete(self->cond);
     Expr__delete(self->true_expr);
@@ -975,11 +939,8 @@ void TernaryExpr__emit_(Expr* self_, Ctx* ctx) {
     Ctx__patch_jump(ctx, patch_2);
 }
 
-TernaryExpr* TernaryExpr__new(){
-    const static ExprVt Vt = {
-        .dtor = TernaryExpr__dtor,
-        .emit_ = TernaryExpr__emit_
-    };
+TernaryExpr* TernaryExpr__new() {
+    const static ExprVt Vt = {.dtor = TernaryExpr__dtor, .emit_ = TernaryExpr__emit_};
     static_assert_expr_size(TernaryExpr);
     TernaryExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -996,7 +957,7 @@ typedef struct SubscrExpr {
     Expr* rhs;
 } SubscrExpr;
 
-void SubscrExpr__dtor(Expr* self_){
+void SubscrExpr__dtor(Expr* self_) {
     SubscrExpr* self = (SubscrExpr*)self_;
     Expr__delete(self->lhs);
     Expr__delete(self->rhs);
@@ -1053,7 +1014,7 @@ bool SubscrExpr__emit_del(Expr* self_, Ctx* ctx) {
     return true;
 }
 
-SubscrExpr* SubscrExpr__new(Expr* lhs, Expr* rhs){
+SubscrExpr* SubscrExpr__new(Expr* lhs, Expr* rhs) {
     const static ExprVt Vt = {
         .dtor = SubscrExpr__dtor,
         .emit_ = SubscrExpr__emit_,
@@ -1113,15 +1074,13 @@ bool AttribExpr__emit_istore(Expr* self_, Ctx* ctx) {
     return true;
 }
 
-AttribExpr* AttribExpr__new(Expr* child, StrName name){
-    const static ExprVt Vt = {
-        .emit_ = AttribExpr__emit_,
-        .emit_del = AttribExpr__emit_del,
-        .emit_store = AttribExpr__emit_store,
-        .emit_inplace = AttribExpr__emit_inplace,
-        .emit_istore = AttribExpr__emit_istore,
-        .is_attrib = true
-    };
+AttribExpr* AttribExpr__new(Expr* child, StrName name) {
+    const static ExprVt Vt = {.emit_ = AttribExpr__emit_,
+                              .emit_del = AttribExpr__emit_del,
+                              .emit_store = AttribExpr__emit_store,
+                              .emit_inplace = AttribExpr__emit_inplace,
+                              .emit_istore = AttribExpr__emit_istore,
+                              .is_attrib = true};
     static_assert_expr_size(AttribExpr);
     AttribExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -1131,7 +1090,7 @@ AttribExpr* AttribExpr__new(Expr* child, StrName name){
     return self;
 }
 
-typedef struct CallExprKwArg{
+typedef struct CallExprKwArg {
     StrName key;
     Expr* val;
 } CallExprKwArg;
@@ -1139,12 +1098,12 @@ typedef struct CallExprKwArg{
 typedef struct CallExpr {
     COMMON_HEADER
     Expr* callable;
-    c11_vector/*T=Expr* */ args;
+    c11_vector /*T=Expr* */ args;
     // **a will be interpreted as a special keyword argument: {"**": a}
-    c11_vector/*T=CallExprKwArg */ kwargs;
+    c11_vector /*T=CallExprKwArg */ kwargs;
 } CallExpr;
 
-void CallExpr__dtor(Expr* self_){
+void CallExpr__dtor(Expr* self_) {
     CallExpr* self = (CallExpr*)self_;
     Expr__delete(self->callable);
     c11__foreach(Expr*, &self->args, e) Expr__delete(*e);
@@ -1158,14 +1117,15 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
 
     bool vargs = false;
     bool vkwargs = false;
-    c11__foreach(Expr*, &self->args, e){
+    c11__foreach(Expr*, &self->args, e) {
         if((*e)->vt->is_starred) vargs = true;
     }
-    c11__foreach(CallExprKwArg, &self->kwargs, e){
+    c11__foreach(CallExprKwArg, &self->kwargs, e) {
         if(e->val->vt->is_starred) vkwargs = true;
     }
 
-    // if callable is a AttrExpr, we should try to use `fast_call` instead of use `boundmethod` proxy
+    // if callable is a AttrExpr, we should try to use `fast_call` instead of use `boundmethod`
+    // proxy
     if(self->callable->vt->is_attrib) {
         AttribExpr* p = (AttribExpr*)self->callable;
         vtemit_(p->child, ctx);
@@ -1175,15 +1135,13 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
         Ctx__emit_(ctx, OP_LOAD_NULL, BC_NOARG, BC_KEEPLINE);
     }
 
-    c11__foreach(Expr*, &self->args, e){
-        vtemit_(*e, ctx);
-    }
+    c11__foreach(Expr*, &self->args, e) { vtemit_(*e, ctx); }
 
     if(vargs || vkwargs) {
         Ctx__emit_(ctx, OP_BUILD_TUPLE_UNPACK, (uint16_t)self->args.count, self->line);
 
         if(self->kwargs.count != 0) {
-            c11__foreach(CallExprKwArg, &self->kwargs, e){
+            c11__foreach(CallExprKwArg, &self->kwargs, e) {
                 if(e->val->vt->is_starred) {
                     // **kwargs
                     StarredExpr* se = (StarredExpr*)e->val;
@@ -1204,7 +1162,7 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
         }
     } else {
         // vectorcall protocol
-        c11__foreach(CallExprKwArg, &self->kwargs, e){
+        c11__foreach(CallExprKwArg, &self->kwargs, e) {
             Ctx__emit_int(ctx, e->key, self->line);
             vtemit_(e->val, ctx);
         }
@@ -1214,11 +1172,8 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
     }
 }
 
-CallExpr* CallExpr__new(Expr* callable){
-    const static ExprVt Vt = {
-        .dtor = CallExpr__dtor,
-        .emit_ = CallExpr__emit_
-    };
+CallExpr* CallExpr__new(Expr* callable) {
+    const static ExprVt Vt = {.dtor = CallExpr__dtor, .emit_ = CallExpr__emit_};
     static_assert_expr_size(CallExpr);
     CallExpr* self = PoolExpr_alloc();
     self->vt = &Vt;
@@ -1230,7 +1185,7 @@ CallExpr* CallExpr__new(Expr* callable){
 }
 
 /* context.c */
-void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level){
+void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level) {
     self->co = co;
     self->func = func;
     self->level = level;
@@ -1241,7 +1196,7 @@ void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level){
     c11_smallmap_s2n__ctor(&self->co_consts_string_dedup_map);
 }
 
-void Ctx__dtor(Ctx* self){
+void Ctx__dtor(Ctx* self) {
     c11_vector__dtor(&self->s_expr);
     c11_vector__dtor(&self->global_names);
     c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map);
@@ -1254,40 +1209,39 @@ void Ctx__s_emit_top(Ctx* self) {
     c11_vector__pop(&self->s_expr);
     Expr__delete(top);
 }
+
 // push
-void Ctx__s_push(Ctx* self, Expr* expr) {
-    c11_vector__push(Expr*, &self->s_expr, expr);
-}
+void Ctx__s_push(Ctx* self, Expr* expr) { c11_vector__push(Expr*, &self->s_expr, expr); }
+
 // top
-Expr* Ctx__s_top(Ctx* self){
-    return c11_vector__back(Expr*, &self->s_expr);
-}
+Expr* Ctx__s_top(Ctx* self) { return c11_vector__back(Expr*, &self->s_expr); }
+
 // size
-int Ctx__s_size(Ctx* self) {
-    return self->s_expr.count;
-}
+int Ctx__s_size(Ctx* self) { return self->s_expr.count; }
+
 // pop -> delete
-void Ctx__s_pop(Ctx* self){
+void Ctx__s_pop(Ctx* self) {
     Expr__delete(c11_vector__back(Expr*, &self->s_expr));
     c11_vector__pop(&self->s_expr);
 }
+
 // pop move
-Expr* Ctx__s_popx(Ctx* self){
+Expr* Ctx__s_popx(Ctx* self) {
     Expr* e = c11_vector__back(Expr*, &self->s_expr);
     c11_vector__pop(&self->s_expr);
     return e;
 }
+
 // clean
-void Ctx__s_clean(Ctx* self){
+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++){
+    for(int i = 0; i < self->s_expr.count; i++) {
         Expr__delete(c11__getitem(Expr*, &self->s_expr, i));
     }
     c11_vector__clear(&self->s_expr);
 }
 
 /* compiler.c */
-
 typedef struct Compiler Compiler;
 typedef Error* (*PrattCallback)(Compiler* self);
 
@@ -1323,7 +1277,7 @@ static void Compiler__dtor(Compiler* self) {
 #define prev() tk(self->i - 1)
 #define curr() tk(self->i)
 #define next() tk(self->i + 1)
-#define err() (self->i == self->tokens.count ? prev() : curr())
+// #define err() (self->i == self->tokens.count ? prev() : curr())
 
 #define advance() self->i++
 #define mode() self->src->mode
@@ -1513,7 +1467,7 @@ Error* Compiler__compile(Compiler* self, CodeObject* out) {
     return NULL;
 }
 
-Error* compile(pk_SourceData_ src, CodeObject* out) {
+Error* pk_compile(pk_SourceData_ src, CodeObject* out) {
     pk_TokenArray tokens;
     Error* err = pk_Lexer__process(src, &tokens);
     if(err) return err;
@@ -1524,7 +1478,7 @@ Error* compile(pk_SourceData_ src, CodeObject* out) {
     //     Token* t = data + i;
     //     py_Str tmp;
     //     py_Str__ctor2(&tmp, t->start, t->length);
-    //     printf("[%d] %s: %s\n", t->line, TokenSymbols[t->type], py_Str__data(&tmp));
+    //     printf("[%d] %s: %s\n", t->line, pk_TokenSymbols[t->type], py_Str__data(&tmp));
     //     py_Str__dtor(&tmp);
     // }
 
@@ -1532,7 +1486,7 @@ Error* 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);
-    CodeObject__dtor(out);
+    if(err) CodeObject__dtor(out);
     Compiler__dtor(&compiler);
     return err;
 }

+ 35 - 35
src/compiler/lexer.c

@@ -21,18 +21,18 @@ typedef struct pk_Lexer{
     c11_vector/*T=int*/ indents;
 } pk_Lexer;
 
-typedef struct pk_TokenDeserializer {
+typedef struct TokenDeserializer {
     const char* curr;
     const char* source;
-} pk_TokenDeserializer;
+} TokenDeserializer;
 
-void pk_TokenDeserializer__ctor(pk_TokenDeserializer* self, const char* source);
-bool pk_TokenDeserializer__match_char(pk_TokenDeserializer* self, char c);
-c11_string pk_TokenDeserializer__read_string(pk_TokenDeserializer* self, char c);
-py_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, char c);
-int pk_TokenDeserializer__read_count(pk_TokenDeserializer* self);
-int64_t pk_TokenDeserializer__read_uint(pk_TokenDeserializer* self, char c);
-double pk_TokenDeserializer__read_float(pk_TokenDeserializer* self, char c);
+void TokenDeserializer__ctor(TokenDeserializer* self, const char* source);
+bool TokenDeserializer__match_char(TokenDeserializer* self, char c);
+c11_string TokenDeserializer__read_string(TokenDeserializer* self, char c);
+py_Str TokenDeserializer__read_string_from_hex(TokenDeserializer* self, char c);
+int TokenDeserializer__read_count(TokenDeserializer* self);
+int64_t TokenDeserializer__read_uint(TokenDeserializer* self, char c);
+double TokenDeserializer__read_float(TokenDeserializer* self, char c);
 
 
 const static TokenValue EmptyTokenValue;
@@ -553,34 +553,34 @@ static Error* lex_one_token(pk_Lexer* self, bool* eof){
 }
 
 static Error* from_precompiled(pk_Lexer* self) {
-    pk_TokenDeserializer deserializer;
-    pk_TokenDeserializer__ctor(&deserializer, py_Str__data(&self->src->source));
+    TokenDeserializer deserializer;
+    TokenDeserializer__ctor(&deserializer, py_Str__data(&self->src->source));
 
     deserializer.curr += 5;  // skip "pkpy:"
-    c11_string version = pk_TokenDeserializer__read_string(&deserializer, '\n');
+    c11_string version = TokenDeserializer__read_string(&deserializer, '\n');
 
     if(c11_string__cmp3(version, PK_VERSION) != 0) {
         return SyntaxError("precompiled version mismatch");
     }
-    if(pk_TokenDeserializer__read_uint(&deserializer, '\n') != (int64_t)self->src->mode){
+    if(TokenDeserializer__read_uint(&deserializer, '\n') != (int64_t)self->src->mode){
         return SyntaxError("precompiled mode mismatch");
     }
 
-    int count = pk_TokenDeserializer__read_count(&deserializer);
+    int count = TokenDeserializer__read_count(&deserializer);
     c11_vector* precompiled_tokens = &self->src->_precompiled_tokens;
     for(int i = 0; i < count; i++) {
-        c11_string item = pk_TokenDeserializer__read_string(&deserializer, '\n');
+        c11_string item = TokenDeserializer__read_string(&deserializer, '\n');
         py_Str copied_item;
         py_Str__ctor2(&copied_item, item.data, item.size);
         c11_vector__push(py_Str, precompiled_tokens, copied_item);
     }
 
-    count = pk_TokenDeserializer__read_count(&deserializer);
+    count = TokenDeserializer__read_count(&deserializer);
     for(int i = 0; i < count; i++) {
         Token t;
-        t.type = (TokenIndex)pk_TokenDeserializer__read_uint(&deserializer, ',');
+        t.type = (TokenIndex)TokenDeserializer__read_uint(&deserializer, ',');
         if(is_raw_string_used(t.type)) {
-            int64_t index = pk_TokenDeserializer__read_uint(&deserializer, ',');
+            int64_t index = TokenDeserializer__read_uint(&deserializer, ',');
             py_Str* p = c11__at(py_Str, precompiled_tokens, index);
             t.start = py_Str__data(p);
             t.length = c11__getitem(py_Str, precompiled_tokens, index).size;
@@ -589,30 +589,30 @@ static Error* from_precompiled(pk_Lexer* self) {
             t.length = 0;
         }
 
-        if(pk_TokenDeserializer__match_char(&deserializer, ',')) {
+        if(TokenDeserializer__match_char(&deserializer, ',')) {
             t.line = c11_vector__back(Token, &self->nexts).line;
         } else {
-            t.line = (int)pk_TokenDeserializer__read_uint(&deserializer, ',');
+            t.line = (int)TokenDeserializer__read_uint(&deserializer, ',');
         }
 
-        if(pk_TokenDeserializer__match_char(&deserializer, ',')) {
+        if(TokenDeserializer__match_char(&deserializer, ',')) {
             t.brackets_level = c11_vector__back(Token, &self->nexts).brackets_level;
         } else {
-            t.brackets_level = (int)pk_TokenDeserializer__read_uint(&deserializer, ',');
+            t.brackets_level = (int)TokenDeserializer__read_uint(&deserializer, ',');
         }
 
         char type = (*deserializer.curr++);      // read_char
         switch(type) {
             case 'I': {
-                int64_t res = pk_TokenDeserializer__read_uint(&deserializer, '\n');
+                int64_t res = TokenDeserializer__read_uint(&deserializer, '\n');
                 t.value = (TokenValue){TokenValue_I64, ._i64 = res};
             } break;
             case 'F': {
-                double res = pk_TokenDeserializer__read_float(&deserializer, '\n');
+                double res = TokenDeserializer__read_float(&deserializer, '\n');
                 t.value = (TokenValue){TokenValue_F64, ._f64 = res};
             } break;
             case 'S': {
-                py_Str res = pk_TokenDeserializer__read_string_from_hex(&deserializer, '\n');
+                py_Str res = TokenDeserializer__read_string_from_hex(&deserializer, '\n');
                 t.value = (TokenValue){TokenValue_STR, ._str = res};
             } break;
             default:
@@ -875,12 +875,12 @@ const char* pk_TokenSymbols[] = {
     "try", "while", "with", "yield",
 };
 
-void pk_TokenDeserializer__ctor(pk_TokenDeserializer* self, const char* source){
+void TokenDeserializer__ctor(TokenDeserializer* self, const char* source){
     self->curr = source;
     self->source = source;
 }
 
-bool pk_TokenDeserializer__match_char(pk_TokenDeserializer* self, char c){
+bool TokenDeserializer__match_char(TokenDeserializer* self, char c){
     if(*self->curr == c) {
         self->curr++;
         return true;
@@ -888,7 +888,7 @@ bool pk_TokenDeserializer__match_char(pk_TokenDeserializer* self, char c){
     return false;
 }
 
-c11_string pk_TokenDeserializer__read_string(pk_TokenDeserializer* self, char c){
+c11_string TokenDeserializer__read_string(TokenDeserializer* self, char c){
     const char* start = self->curr;
     while(*self->curr != c)
         self->curr++;
@@ -897,8 +897,8 @@ c11_string pk_TokenDeserializer__read_string(pk_TokenDeserializer* self, char c)
     return retval;
 }
 
-py_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, char c){
-    c11_string sv = pk_TokenDeserializer__read_string(self, c);
+py_Str TokenDeserializer__read_string_from_hex(TokenDeserializer* self, char c){
+    c11_string sv = TokenDeserializer__read_string(self, c);
     const char* s = sv.data;
     char* buffer = (char*)malloc(sv.size / 2 + 1);
     for(int i = 0; i < sv.size; i += 2) {
@@ -927,13 +927,13 @@ py_Str pk_TokenDeserializer__read_string_from_hex(pk_TokenDeserializer* self, ch
     };
 }
 
-int pk_TokenDeserializer__read_count(pk_TokenDeserializer* self){
+int TokenDeserializer__read_count(TokenDeserializer* self){
     assert(*self->curr == '=');
     self->curr++;
-    return pk_TokenDeserializer__read_uint(self, '\n');
+    return TokenDeserializer__read_uint(self, '\n');
 }
 
-int64_t pk_TokenDeserializer__read_uint(pk_TokenDeserializer* self, char c){
+int64_t TokenDeserializer__read_uint(TokenDeserializer* self, char c){
     int64_t out = 0;
     while(*self->curr != c) {
         out = out * 10 + (*self->curr - '0');
@@ -943,8 +943,8 @@ int64_t pk_TokenDeserializer__read_uint(pk_TokenDeserializer* self, char c){
     return out;
 }
 
-double pk_TokenDeserializer__read_float(pk_TokenDeserializer* self, char c){
-    c11_string sv = pk_TokenDeserializer__read_string(self, c);
+double TokenDeserializer__read_float(TokenDeserializer* self, char c){
+    c11_string sv = TokenDeserializer__read_string(self, c);
     py_Str nullterm;
     py_Str__ctor2(&nullterm, sv.data, sv.size);
     char* end;