203 lines
4.8 KiB
C++
203 lines
4.8 KiB
C++
|
|
// 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<Ast_Typespec*> args;
|
|
}func;
|
|
};
|
|
};
|
|
|
|
struct Ast_Decl:Ast{
|
|
Intern_String name;
|
|
union{
|
|
struct{
|
|
Ast_Typespec *typespec;
|
|
Intern_String name;
|
|
Ast_Expr *expr;
|
|
}var;
|
|
struct{
|
|
Array<Ast_Decl*> args;
|
|
Ast_Typespec *ret;
|
|
}func;
|
|
};
|
|
};
|
|
|
|
struct Ast_Package:Ast{
|
|
Intern_String name;
|
|
Array<Ast_Decl *> 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;
|
|
} |