typedef struct OS_Memory OS_Memory; struct OS_Memory{ void *data; SizeU commit; SizeU reserve; }; typedef struct Arena Arena; struct Arena{ union{ OS_Memory memory; struct { void *data; SizeU commit; SizeU reserve; }; } U64 len; U64 alignment; }; typedef struct String String; struct String{ U8 *str; S64 len; }; typedef String Intern_String; typedef enum Token_Kind{ TK_End, TK_Mul, TK_Div, TK_Add, TK_Sub, TK_Mod, TK_BitAnd, TK_BitOr, TK_BitXor, TK_Neg, TK_Not, TK_OpenParen, TK_CloseParen, TK_OpenBrace, TK_CloseBrace, TK_OpenBracket, TK_CloseBracket, TK_Comma, TK_Pound, TK_Question, TK_ThreeDots, TK_Semicolon, TK_Dot, TK_LesserThen, TK_GreaterThen, TK_Colon, TK_Assign, TK_DivAssign, TK_MulAssign, TK_ModAssign, TK_SubAssign, TK_AddAssign, TK_AndAssign, TK_OrAssign, TK_XorAssign, TK_LeftShiftAssign, TK_RightShiftAssign, TK_DoubleColon, TK_At, TK_Decrement, TK_Increment, TK_PostDecrement, TK_PostIncrement, TK_LesserThenOrEqual, TK_GreaterThenOrEqual, TK_Equals, TK_And, TK_Or, TK_NotEquals, TK_LeftShift, TK_RightShift, TK_Arrow, TK_ExprSizeof, TK_DocComment, TK_Comment, TK_Identifier, TK_StringLit, TK_U8Lit, TK_Character, TK_Error, TK_Float, TK_Int, TK_Keyword, }Token_Kind; typedef struct Token Token; struct Token{ Token_Kind kind; union{ String string; struct { U8 *str; S64 len; }; } union { S64 int_val; String error_val; Intern_String intern_val; }; String file; S64 line; U8 *line_begin; }; typedef struct Tokens Tokens; struct Tokens{ Token *tokens; S64 len; S64 cap; S64 iter; }; typedef struct Lex_Stream Lex_Stream; struct Lex_Stream{ U8 *stream; U8 *line_begin; String filename; S64 line; }; typedef enum Expr_Kind{ EK_None, EK_Atom, EK_Unary, EK_Binary, EK_Ternary, EK_Cast, EK_List, EK_Call, EK_Index, }Expr_Kind; typedef enum AST_Kind{ AK_None, AK_BaseType, AK_Typedef, AK_Enum, AK_Struct, AK_Union, AK_Note, AK_List, AK_Pointer, AK_Array, AK_Function, AK_Variable, AK_EnumChild, }AST_Kind; typedef struct AST_Node AST_Node; struct AST_Node{ AST_Kind kind; Token *pos; Intern_String name; AST_Node *next; AST_Node *next_scope; AST_Node *first_note; AST_Node *last_note; AST_Node *first_child; AST_Node *last_child; union { SizeU base_type_size; AST_Node *pointer; AST_Node *typedef_type; AST_Node *variable_type; AST_Node *func_return_type; }; }; typedef struct Parser_Error Parser_Error; struct Parser_Error{ Parser_Error *next; String message; Token *token; }; typedef struct Scope Scope; struct Scope{ Scope *next; AST_Node *first; AST_Node *last; }; typedef struct Parser Parser; struct Parser{ Arena main_arena; Arena intern_table_arena; Arena symbol_table_arena; Scope *scope_free_list; Scope *scope_stack; Scope *global_scope; S64 symbols_inserted; S64 symbols_count; AST_Node *symbols; Intern_String *interns; S64 interns_in_bytes; S64 interns_inserted; S64 interns_count; U8 *first_keyword; U8 *last_keyword; Parser_Error *first_default; Parser_Error *last_default; Parser_Error *first_error; Parser_Error *last_error; union{ Tokens token_array; struct { Token *tokens; S64 len; S64 cap; S64 iter; }; } }; global String Token_Kind_metadata[] = { [TK_End] = lit("End of stream"), [TK_Mul] = lit("*"), [TK_Div] = lit("/"), [TK_Add] = lit("+"), [TK_Sub] = lit("-"), [TK_Mod] = lit("%"), [TK_BitAnd] = lit("&"), [TK_BitOr] = lit("|"), [TK_BitXor] = lit("^"), [TK_Neg] = lit("~"), [TK_Not] = lit("!"), [TK_OpenParen] = lit("("), [TK_CloseParen] = lit(" "), [TK_OpenBrace] = lit("{"), [TK_CloseBrace] = lit("}"), [TK_OpenBracket] = lit("["), [TK_CloseBracket] = lit("]"), [TK_Comma] = lit(","), [TK_Pound] = lit("#"), [TK_Question] = lit("?"), [TK_ThreeDots] = lit("..."), [TK_Semicolon] = lit(";"), [TK_Dot] = lit("."), [TK_LesserThen] = lit("<"), [TK_GreaterThen] = lit(">"), [TK_Colon] = lit(":"), [TK_Assign] = lit("="), [TK_DivAssign] = lit("/="), [TK_MulAssign] = lit("*="), [TK_ModAssign] = lit("%="), [TK_SubAssign] = lit("-="), [TK_AddAssign] = lit("+="), [TK_AndAssign] = lit("&="), [TK_OrAssign] = lit("|="), [TK_XorAssign] = lit("^="), [TK_LeftShiftAssign] = lit("<<="), [TK_RightShiftAssign] = lit(">>="), [TK_DoubleColon] = lit("::"), [TK_At] = lit("@"), [TK_Decrement] = lit("--"), [TK_Increment] = lit("++"), [TK_PostDecrement] = lit("--"), [TK_PostIncrement] = lit("++"), [TK_LesserThenOrEqual] = lit("<="), [TK_GreaterThenOrEqual] = lit(">="), [TK_Equals] = lit("=="), [TK_And] = lit("&&"), [TK_Or] = lit("||"), [TK_NotEquals] = lit("!="), [TK_LeftShift] = lit("<<"), [TK_RightShift] = lit(">>"), [TK_Arrow] = lit("->"), [TK_ExprSizeof] = lit("sizeof"), [TK_DocComment] = lit("DocComment"), [TK_Comment] = lit("Comment"), [TK_Identifier] = lit("Identifier"), [TK_StringLit] = lit("StringLit"), [TK_U8Lit] = lit("U8Lit"), [TK_Character] = lit("Character"), [TK_Error] = lit("Error"), [TK_Float] = lit("Float"), [TK_Int] = lit("Int"), [TK_Keyword] = lit("Keyword"), }; function Token*Tokens_array_push_empty(Tokens*a){ if(a->cap==0){ a->cap=1024; a->tokens=malloc(sizeof(Token)*a->cap); } else if(a->len+1>a->cap){ a->cap*=2; a->tokens=realloc(a->tokens,sizeof(Token)*a->cap); } Token*result=a->tokens+a->len++; memory_zero(result,sizeof(*result)); return result; } global String Expr_Kind_metadata[] = { [EK_None] = lit("None"), [EK_Atom] = lit("Atom"), [EK_Unary] = lit("Unary"), [EK_Binary] = lit("Binary"), [EK_Ternary] = lit("Ternary"), [EK_Cast] = lit("Cast"), [EK_List] = lit("List"), [EK_Call] = lit("Call"), [EK_Index] = lit("Index"), }; global String AST_Kind_metadata[] = { [AK_None] = lit("None"), [AK_BaseType] = lit("BaseType"), [AK_Typedef] = lit("Typedef"), [AK_Enum] = lit("Enum"), [AK_Struct] = lit("Struct"), [AK_Union] = lit("Union"), [AK_Note] = lit("Note"), [AK_List] = lit("List"), [AK_Pointer] = lit("Pointer"), [AK_Array] = lit("Array"), [AK_Function] = lit("Function"), [AK_Variable] = lit("Variable"), [AK_EnumChild] = lit("EnumChild"), }; function void parser_default_push(Parser*parent,Parser_Error*child){ if(parent->first==0){ parent->first=parent->last=child; } else{ parent->last=parent->last->next=child; } } function Parser_Error*parser_default_pop_first(Parser*parent){ if(parent->first==parent->last){ Parser_Error*node=parent->first; parent->first=parent->last=0; return node; } else if(parent->first){ Parser_Error*node=parent->first; parent->first=parent->first->next; } return 0; } function void parser_error_push(Parser*parent,Parser_Error*child){ if(parent->first_error==0){ parent->first_error=parent->last_error=child; } else{ parent->last_error=parent->last_error->next_error=child; } } function Parser_Error*parser_error_pop_first(Parser*parent){ if(parent->first_error==parent->last_error){ Parser_Error*node=parent->first_error; parent->first_error=parent->last_error=0; return node; } else if(parent->first_error){ Parser_Error*node=parent->first_error; parent->first_error=parent->first_error->next_error; } return 0; } function Token*Parser_array_push_empty(Parser*a){ if(a->cap==0){ a->cap=1024; a->tokens=malloc(sizeof(Token)*a->cap); } else if(a->len+1>a->cap){ a->cap*=2; a->tokens=realloc(a->tokens,sizeof(Token)*a->cap); } Token*result=a->tokens+a->len++; memory_zero(result,sizeof(*result)); return result; }