// Lexer::interns::map::allocator - array allocator, resizing // Lexer::tokens - array allocator, resizing // // Parser::ast_arena - arena for asts // Lexer::interns::string_allocator - arena for interns // Intern_String keyword_const; Intern_String keyword_struct; Intern_String keyword_union; Intern_String keyword_enum; const U64 Parse_Ctx_ID = 115151; struct Parse_Ctx:Lexer{ Arena ast_arena; Token empty_token; S64 indent; S64 pt[256]; // precedence table void init(){ const S64 addp = 1; const S64 mulp = 2; pt[TK_Add] = addp; pt[TK_Sub] = addp; pt[TK_Div] = mulp; pt[TK_Mul] = mulp; arena_init(&ast_arena, "AST Arena"_s); lex_init(this); keyword_const = intern_string(&interns, "const"_s); keyword_struct= intern_string(&interns, "struct"_s); keyword_union = intern_string(&interns, "union"_s); keyword_enum = intern_string(&interns, "enum"_s); interns.first_keyword = keyword_const.str; interns.last_keyword = keyword_enum.str; } }; //----------------------------------------------------------------------------- // AST //----------------------------------------------------------------------------- enum Ast_Kind{ AK_None, AK_Package, AK_Expr_Str, AK_Expr_Int, AK_Expr_Ident, AK_Expr_Binary, AK_Decl_Func, AK_Decl_Func_Arg, AK_Decl_Const, AK_Decl_Var, AK_Typespec_Ident, AK_Typespec_Pointer, AK_Typespec_Array, AK_Typespec_Func }; struct Ast{ Ast_Kind kind; Token *pos; }; struct Ast_Expr:Ast{ union{ Intern_String intern_val; U64 int_val; struct{ Token_Kind op; Ast_Expr *left; Ast_Expr *right; } binary; }; }; struct Ast_Typespec:Ast{ union{ Ast_Typespec *base; Intern_String name; struct{ Ast_Typespec *base; Ast_Expr *expr; }arr; struct{ Ast_Typespec *ret; Array args; }func; }; }; struct Ast_Decl:Ast{ Intern_String name; union{ struct{ Ast_Typespec *typespec; Intern_String name; Ast_Expr *expr; }var; struct{ Array args; Ast_Typespec *ret; }func; }; }; struct Ast_Package:Ast{ Intern_String name; Array decls; }; //----------------------------------------------------------------------------- // AST Constructors beginning with expressions //----------------------------------------------------------------------------- #define AST_NEW(T,ikind,ipos) \ Get_Ctx(Parse_Ctx); \ Ast_##T *result = exp_alloc_type(&ctx->ast_arena, Ast_##T); \ result->kind = ikind; \ result->pos = ipos function Ast_Expr * ast_expr_string(Token *pos, Intern_String string){ AST_NEW(Expr, AK_Expr_Str, pos); result->intern_val = string; return result; } function Ast_Expr * ast_expr_identifier(Token *pos, Intern_String string){ AST_NEW(Expr, AK_Expr_Ident, pos); result->intern_val = string; return result; } function Ast_Expr * ast_expr_integer(Token *pos, S64 integer){ AST_NEW(Expr, AK_Expr_Int, pos); result->int_val = integer; return result; } function Ast_Expr * ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ AST_NEW(Expr, AK_Expr_Binary, op); result->binary.op = op->kind; result->binary.left = left; result->binary.right = right; return result; } //----------------------------------------------------------------------------- // Typespecs //----------------------------------------------------------------------------- function Ast_Typespec * ast_typespec_name(Token *pos, Intern_String name){ AST_NEW(Typespec, AK_Typespec_Ident, pos); result->name = name; return result; } function Ast_Typespec * ast_typespec_pointer(Token *pos, Ast_Typespec *base){ AST_NEW(Typespec, AK_Typespec_Pointer, pos); result->base = base; return result; } function Ast_Typespec * ast_typespec_array(Token *pos, Ast_Typespec *base, Ast_Expr *expr){ AST_NEW(Typespec, AK_Typespec_Array, pos); result->arr.base = base; result->arr.expr = expr; return result; } //----------------------------------------------------------------------------- // Declarations //----------------------------------------------------------------------------- function Ast_Decl * ast_decl_func(Token *pos, Intern_String name){ AST_NEW(Decl, AK_Decl_Func, pos); result->name = name; return result; } function Ast_Decl * ast_decl_var(Token *pos, Ast_Typespec *typespec, Intern_String name, Ast_Expr *expr){ AST_NEW(Decl, AK_Decl_Var, pos); result->var.expr = expr; result->var.typespec = typespec; result->name = name; return result; } function Ast_Package * ast_package(Token *pos, String name){ AST_NEW(Package, AK_Package, pos); result->name = intern_string(&ctx->interns, name); return result; }