#ifndef AMALGAM_AST_H #define AMALGAM_AST_H #include "defs.h" #include "std/buffer_view.h" #include "std/buffer.h" #include "std/misc.h" #include "std/scoped_allocator.h" #include "std/hash_map.h" #include "binop_type.h" #include "ssa/ssa.h" #include /* General error */ #define AST_ERR -1 #define AST_ERR_DEF_DUP -20 typedef struct FunctionDecl FunctionDecl; typedef struct FunctionCall FunctionCall; typedef struct LhsExpr LhsExpr; typedef struct Import Import; typedef struct String String; typedef struct Variable Variable; typedef struct Number Number; typedef struct Binop Binop; typedef union { void *data; FunctionDecl *func_decl; FunctionCall *func_call; LhsExpr *lhs_expr; Import *import; String *string; Number *number; Variable *variable; Binop *binop; } AstValue; typedef enum { AST_NONE, AST_FUNCTION_DECL, AST_FUNCTION_CALL, AST_LHS, AST_IMPORT, AST_STRING, AST_NUMBER, AST_VARIABLE, AST_BINOP } AstType; typedef enum { AST_NOT_RESOLVED, AST_RESOLVING, AST_RESOLVED } AstResolveStatus; typedef struct { AstValue value; AstType type; AstResolveStatus resolve_status; } Ast; struct Scope { Buffer ast_objects; HashMap/*(key=BufferView, value=Ast)*/ named_objects; Scope *parent; }; struct Variable { BufferView name; Ast resolved_variable; }; struct FunctionDecl { Scope body; SsaFuncIndex ssa_func_index; }; struct FunctionCall { Variable func; Buffer/*Ast*/ args; }; struct LhsExpr { int is_const; BufferView type_name; BufferView var_name; Ast rhs_expr; }; struct Import { BufferView path; }; struct String { BufferView str; }; struct Number { union { i64 integer; f64 floating; } value; bool is_integer; }; struct Binop { Ast lhs; Ast rhs; BinopType type; /* Is the binop already ordered - no need to reorder it */ bool grouped; }; typedef struct { jmp_buf env; Parser *parser; Scope *scope; } AstCompilerContext; Ast ast_none(); void ast_init(Ast *self, void *value, AstType type); BufferView ast_get_name(Ast *self); CHECK_RESULT int funcdecl_init(FunctionDecl *self, Scope *parent, ScopedAllocator *allocator); CHECK_RESULT int funccall_init(FunctionCall *self, BufferView name, ScopedAllocator *allocator); void lhsexpr_init(LhsExpr *self, int isConst, BufferView var_name); void import_init(Import *self, BufferView path); CHECK_RESULT int string_init(String *self, BufferView str); void number_init(Number *self, i64 value, bool is_integer); void variable_init(Variable *self, BufferView name); void binop_init(Binop *self); CHECK_RESULT int scope_init(Scope *self, Scope *parent, ScopedAllocator *allocator); CHECK_RESULT int scope_add_child(Scope *self, Ast *child); /* longjump to compiler env on failure */ void scope_resolve(Scope *self, AstCompilerContext *context); #endif