388 lines
9.7 KiB
C++
388 lines
9.7 KiB
C++
|
|
|
|
#define AST_NEW(T,ikind,ipos,iflags) \
|
|
Ast_##T *result = allocate_struct(pctx->perm, Ast_##T); \
|
|
result->flags = iflags; \
|
|
result->kind = AST_##ikind; \
|
|
result->parent_scope = pctx->currently_parsed_scope; \
|
|
result->pos = ipos; \
|
|
result->di = ++pctx->unique_ids
|
|
|
|
#define ast_new(T,kind,pos,flags) (T *)_ast_new(sizeof(T), kind, pos, flags)
|
|
CORE_Static Ast *
|
|
_ast_new(size_t size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0){
|
|
Ast *result = (Ast *)allocate_size(pctx->perm, size);
|
|
result->flags = flags;
|
|
result->kind = kind;
|
|
result->parent_scope = pctx->currently_parsed_scope;
|
|
result->pos = pos;
|
|
result->di = ++pctx->unique_ids;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Atom *
|
|
ast_str(Token *pos, Intern_String string){
|
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
|
result->type = pctx->untyped_string;
|
|
result->intern_val = string;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Atom *
|
|
ast_ident(Token *pos, Intern_String string){
|
|
AST_NEW(Atom, IDENT, pos, AST_EXPR | AST_ATOM);
|
|
result->intern_val = string;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Atom *
|
|
ast_bool(Token *pos, B32 bool_val){
|
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
|
result->bool_val = bool_val;
|
|
result->type = pctx->untyped_bool;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Atom *
|
|
ast_float(Token *pos, F64 value){
|
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
|
result->type = pctx->untyped_float;
|
|
result->f64_val = value;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Atom *
|
|
ast_int(Token *pos, BigInt val){
|
|
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
|
result->type = pctx->untyped_int;
|
|
result->big_int_val = bigint_copy(pctx->perm, &val);
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Atom *
|
|
ast_int(Token *pos, U64 value){
|
|
return ast_int(pos, bigint_u64(value));
|
|
}
|
|
|
|
CORE_Static Ast_Expr *
|
|
ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
|
|
AST_NEW(Binary, BINARY, op, AST_EXPR);
|
|
result->op = op->kind;
|
|
result->left = left;
|
|
result->right = right;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Call *
|
|
ast_call(Token *pos, Ast_Expr *name, Array<Ast_Call_Item *> exprs){
|
|
// name here specifies also typespec for compound expressions !
|
|
AST_NEW(Call, CALL, pos, AST_EXPR);
|
|
result->name = name;
|
|
result->exprs = exprs.tight_copy(pctx->perm);
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Call_Item *
|
|
ast_call_item(Token *pos, Ast_Atom *name, Ast_Expr *index, Ast_Expr *item){
|
|
AST_NEW(Call_Item, CALL_ITEM, pos, AST_EXPR);
|
|
result->name = name;
|
|
result->item = item;
|
|
result->index = index;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Expr *
|
|
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
|
|
AST_NEW(Unary, UNARY, pos, AST_EXPR);
|
|
result->flags = AST_EXPR;
|
|
result->expr = expr;
|
|
result->op = op;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Expr *
|
|
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
|
|
AST_NEW(Index, INDEX, pos, AST_EXPR);
|
|
result->flags = AST_EXPR;
|
|
result->expr = expr;
|
|
result->index = index;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Lambda *
|
|
ast_lambda(Token *pos, Array<Ast_Decl *> params, Array<Ast_Expr *> ret, Ast_Scope *scope){
|
|
AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR);
|
|
result->flags = AST_EXPR;
|
|
result->args = params.tight_copy(pctx->perm);
|
|
result->ret = ret.tight_copy(pctx->perm);
|
|
result->scope = scope;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_If *
|
|
ast_if(Token *pos, Array<Ast_If_Node *> ifs){
|
|
AST_NEW(If, IF, pos, AST_STMT);
|
|
result->ifs = ifs.tight_copy(pctx->perm);
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_For *
|
|
ast_for(Token *pos, Ast_Expr *init, Ast_Expr *cond, Ast_Expr *iter, Ast_Scope *scope){
|
|
AST_NEW(For, FOR, pos, AST_STMT);
|
|
result->init = init;
|
|
result->cond = cond;
|
|
result->iter = iter;
|
|
result->scope = scope;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Pass *
|
|
ast_pass(Token *pos){
|
|
AST_NEW(Pass, PASS, pos, AST_STMT);
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Break *
|
|
ast_break(Token *pos){
|
|
AST_NEW(Break, BREAK, pos, AST_STMT);
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Return *
|
|
ast_return(Token *pos, Array<Ast_Expr *> expr){
|
|
AST_NEW(Return, RETURN, pos, AST_STMT);
|
|
if(expr.len){
|
|
For(expr) assert(is_flag_set(it->flags, AST_EXPR));
|
|
result->expr = expr.tight_copy(pctx->perm);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_If_Node *
|
|
ast_if_node(Token *pos, Ast_Expr *init, Ast_Expr *expr, Ast_Scope *scope){
|
|
AST_NEW(If_Node, IF_NODE, pos, AST_STMT);
|
|
result->scope = scope;
|
|
result->expr = expr;
|
|
result->init = (Ast_Binary *)init;
|
|
if(result->init) {
|
|
assert(init->kind == AST_VAR);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Array *
|
|
ast_array(Token *pos, Ast_Expr *expr){
|
|
AST_NEW(Array, ARRAY, pos, AST_EXPR);
|
|
result->expr = expr;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Scope *
|
|
begin_decl_scope(Allocator *scratch, Token *pos){
|
|
AST_NEW(Scope, SCOPE, pos, AST_DECL);
|
|
result->file = pctx->currently_parsed_file;
|
|
result->module = pctx->currently_parsed_file->module;
|
|
result->scope_id = pctx->scope_ids++;
|
|
result->debug_name = pos->string;
|
|
assert(result->file);
|
|
pctx->currently_parsed_scope = result;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static void
|
|
finalize_decl_scope(Ast_Scope *scope){
|
|
pctx->currently_parsed_scope = scope->parent_scope;
|
|
}
|
|
|
|
CORE_Static Ast_Scope *
|
|
begin_stmt_scope(Allocator *scratch, Token *pos){
|
|
AST_NEW(Scope, SCOPE, pos, AST_STMT);
|
|
result->stmts = {scratch};
|
|
result->file = pctx->currently_parsed_file;
|
|
result->module = pctx->currently_parsed_file->module;
|
|
result->scope_id = pctx->scope_ids++;
|
|
result->debug_name = pos->string;
|
|
assert(result->file);
|
|
pctx->currently_parsed_scope = result;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static void
|
|
finalize_stmt_scope(Ast_Scope *scope){
|
|
scope->stmts = scope->stmts.tight_copy(pctx->perm);
|
|
pctx->currently_parsed_scope = scope->parent_scope;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_struct(Token *pos, Ast_Scope *scope){
|
|
AST_NEW(Decl, STRUCT, pos, AST_DECL | AST_AGGREGATE);
|
|
result->scope = scope;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_enum(Token *pos, Ast_Expr *typespec, Ast_Scope *scope){
|
|
AST_NEW(Decl, ENUM, pos, AST_DECL | AST_AGGREGATE);
|
|
result->scope = scope;
|
|
result->typespec = typespec;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
|
|
AST_NEW(Decl, VAR, pos, AST_DECL);
|
|
result->name = name;
|
|
result->typespec = typespec;
|
|
result->expr = expr;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_const(Token *pos, Intern_String name, Value value){
|
|
AST_NEW(Decl, CONST, pos, AST_DECL);
|
|
result->value = value;
|
|
result->name = name;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
|
|
AST_NEW(Decl, CONST, pos, AST_DECL);
|
|
result->expr = expr;
|
|
result->name = name;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_type(Token *pos, Intern_String name, Ast_Type *type){
|
|
AST_NEW(Decl, TYPE, pos, AST_DECL);
|
|
result->type = pctx->type_type;
|
|
result->type_val = type;
|
|
result->name = name;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Scope *
|
|
ast_decl_scope(Token *pos, Allocator *allocator, Ast_File *file){
|
|
AST_NEW(Scope, SCOPE, pos, AST_DECL);
|
|
result->file = file;
|
|
|
|
result->scope_id = pctx->scope_ids++;
|
|
assert(result->file);
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Decl *
|
|
ast_namespace(Token *pos, Ast_Scope *module, Intern_String name){
|
|
AST_NEW(Decl, NAMESPACE, pos, AST_DECL);
|
|
result->scope = module;
|
|
result->name = name;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Builtin *
|
|
ast_runtime_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
|
AST_NEW(Builtin, RUNTIME_ASSERT, pos, AST_EXPR);
|
|
result->expr = expr;
|
|
result->assert_message = message;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Builtin *
|
|
ast_constant_assert(Token *pos, Ast_Expr *expr, Intern_String message){
|
|
AST_NEW(Builtin, CONSTANT_ASSERT, pos, AST_EXPR);
|
|
result->expr = expr;
|
|
result->assert_message = message;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Builtin *
|
|
ast_sizeof(Token *pos, Ast_Expr *expr){
|
|
AST_NEW(Builtin, SIZE_OF, pos, AST_EXPR);
|
|
result->expr = expr;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Builtin *
|
|
ast_len(Token *pos, Ast_Expr *expr){
|
|
AST_NEW(Builtin, LENGTH_OF, pos, AST_EXPR);
|
|
result->expr = expr;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Builtin *
|
|
ast_alignof(Token *pos, Ast_Expr *expr){
|
|
AST_NEW(Builtin, ALIGN_OF, pos, AST_EXPR);
|
|
result->expr = expr;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static Ast_Var_Unpack *
|
|
ast_var_unpack(Token *pos, Array<Ast_Decl *> vars, Ast_Expr *expr){
|
|
AST_NEW(Var_Unpack, VAR_UNPACK, pos, AST_STMT);
|
|
result->vars = vars.tight_copy(pctx->perm);
|
|
result->expr = expr;
|
|
return result;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Value
|
|
//-----------------------------------------------------------------------------
|
|
CORE_Static Value
|
|
value_bool(B32 v){
|
|
Value value;
|
|
value.bool_val = v;
|
|
value.type = pctx->untyped_bool;
|
|
return value;
|
|
}
|
|
|
|
CORE_Static Value
|
|
value_int(BigInt b){
|
|
Value value;
|
|
value.big_int_val = b;
|
|
value.type = pctx->untyped_int;
|
|
return value;
|
|
}
|
|
|
|
CORE_Static Value
|
|
value_int(S64 s64){
|
|
Value value;
|
|
value.type = pctx->untyped_int;
|
|
bigint_init_signed(&value.big_int_val, s64);
|
|
return value;
|
|
}
|
|
|
|
CORE_Static Value
|
|
value_float(F64 b){
|
|
Value value;
|
|
value.f64_val = b;
|
|
value.type = pctx->untyped_float;
|
|
return value;
|
|
}
|
|
|
|
CORE_Static Value
|
|
value_float(BigInt a){
|
|
Value value;
|
|
value.f64_val = bigint_as_float(&a);
|
|
value.type = pctx->untyped_float;
|
|
return value;
|
|
}
|
|
|
|
CORE_Static B32
|
|
is_ident(Ast *ast){
|
|
B32 result = ast->kind == AST_IDENT;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static B32
|
|
is_binary(Ast *ast){
|
|
B32 result = ast->kind == AST_BINARY;
|
|
return result;
|
|
}
|
|
|
|
CORE_Static B32
|
|
is_atom(Ast *ast){
|
|
B32 result = is_flag_set(ast->flags, AST_ATOM);
|
|
return result;
|
|
}
|