From 3a9b748fed961e0d509f1034d01e954d2a51bb73 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 30 Apr 2022 12:28:34 +0200 Subject: [PATCH] New AST --- ast.c | 34 +++++++ ast.h | 51 ++++++++++ decl.c | 70 ------------- decl.h | 128 ------------------------ expr.c | 2 +- expr.h | 2 +- lang.h | 16 ++- main.c | 22 ++--- parse_decl.c | 270 ++++++++++++++------------------------------------- parse_expr.c | 6 +- parser.c | 190 ++++++++++++++++++------------------ parser.h | 41 +++----- print.c | 82 +--------------- type.c | 59 ----------- type.h | 69 ------------- 15 files changed, 296 insertions(+), 746 deletions(-) create mode 100644 ast.c create mode 100644 ast.h delete mode 100644 decl.c delete mode 100644 decl.h delete mode 100644 type.c delete mode 100644 type.h diff --git a/ast.c b/ast.c new file mode 100644 index 0000000..dc54dd4 --- /dev/null +++ b/ast.c @@ -0,0 +1,34 @@ +typedef AST_Node AST_Node_List; + +function B32 +ast_is_named(AST_Node *n){ + B32 result = n && n->name.s.str; + return result; +} + +function AST_Node * +ast_node_new(Parser *p, AST_Kind kind, Token *token, Intern_String name){ + AST_Node *node = arena_push_struct(&p->main_arena, AST_Node); + node->pos = token; + node->name = name; + node->kind = kind; + return node; +} + +function AST_Node * +ast_enum(Parser *p, Token *token, Intern_String name){ + AST_Node *node = ast_node_new(p, AK_Enum, token, name); + return node; +} + +function AST_Node * +ast_enum_child(Parser *p, Token *token, Intern_String name, Expr *expr){ + AST_Node *node = ast_node_new(p, AK_EnumChild, token, name); + node->expr = expr; + return node; +} + +function void +ast_node_push_child(AST_Node *node, AST_Node *child){ + SLLQueuePush(node->first_child, node->last_child, child); +} diff --git a/ast.h b/ast.h new file mode 100644 index 0000000..0d61fb0 --- /dev/null +++ b/ast.h @@ -0,0 +1,51 @@ +typedef struct AST_Node AST_Node; +typedef struct Expr Expr; + +typedef enum AST_Kind{ + AK_None, + AK_Undefined, + + 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; + +struct AST_Node{ + AST_Kind kind; + Token *pos; + Expr *expr; + Intern_String name; + + AST_Node *next; + AST_Node *scope_next; + + AST_Node *first_note; + AST_Node *last_note; + + AST_Node *first_child; + AST_Node *last_child; + union{ + AST_Node *pointer; + SizeU base_type_size; + AST_Node *typedef_type; + AST_Node *func_return_type; + }; +}; + +function B32 +ast_is_type(AST_Node *n){ + B32 result = n->kind >= AK_BaseType && n->kind <= AK_Union; + return result; +} diff --git a/decl.c b/decl.c deleted file mode 100644 index b8814cc..0000000 --- a/decl.c +++ /dev/null @@ -1,70 +0,0 @@ - -function Decl * -decl_new(Parser *p, Decl_Kind kind, Token *token, Intern_String name){ - Decl *result = arena_push_struct(&p->main_arena, Decl); - - result->token = token; - result->kind = kind; - result->name = name; - return result; -} - -function Decl_Enum_Child * -decl_enum_child(Parser *p, Token *token, Expr *expr){ - Decl_Enum_Child *result = arena_push_struct(&p->main_arena, Decl_Enum_Child); - result->expr = expr; - result->token = token; - return result; -} - -function Decl * -decl_variable(Parser *p, Token *token, Type *type, Expr *expr){ - Decl *result = decl_new(p, DK_Variable, token, token->intern_val); - result->var_val.expr = expr; - result->var_val.type = type; - return result; -} - -function Decl * -decl_function(Parser *p, Token *token, Type *return_type){ - Decl *result = decl_new(p, DK_Function, token, token->intern_val); - result->func_val.return_type = return_type; - return result; -} - -function Decl * -decl_type(Parser *p, Token *token, Type *type, Intern_String name){ - Decl *result = decl_new(p, DK_Typedef, token, name); - result->typedef_val.type = type; - return result; -} - -function Decl * -decl_enum(Parser *p, Token *token, Intern_String name){ - Decl *result = decl_new(p, DK_Enum, token, name); - return result; -} - -function Decl * -decl_struct(Parser *p, Token *token, Intern_String name){ - Decl *result = decl_new(p, DK_Struct, token, name); - return result; -} -function Decl * -decl_union(Parser *p, Token *token, Intern_String name){ - Decl *result = decl_new(p, DK_Union, token, name); - return result; -} - -function void -decl_aggregate_push(Decl *a, Decl *b){ - SLLQueuePush(a->aggregate_val.first, a->aggregate_val.last, b); -} -function void -decl_function_push(Decl *a, Decl *b){ - SLLQueuePush(a->func_val.first, a->func_val.last, b); -} -function void -decl_enum_push(Decl *a, Decl_Enum_Child *b){ - SLLQueuePush(a->enum_val.first, a->enum_val.last, b); -} diff --git a/decl.h b/decl.h deleted file mode 100644 index 1fa40b9..0000000 --- a/decl.h +++ /dev/null @@ -1,128 +0,0 @@ -#pragma once -typedef struct Note Note; -typedef struct Decl Decl; -typedef struct Decl_Enum_Child Decl_Enum_Child; - -typedef enum Decl_Kind{ - DK_None, - DK_Variable, - DK_Typedef, - DK_Struct, - DK_Union, - DK_Enum, - DK_Function, -}Decl_Kind; - -struct Note{ - Intern_String string; - Token *token; - Expr *expr; - - Note *next; - Note *first; - Note *last; -}; - -struct Decl_Enum_Child{ - Decl_Enum_Child *next; - Token *token; // name - Expr *expr; -}; - -struct Decl{ - Decl_Kind kind; - Decl *next; - Intern_String name; - Token *token; - - Note *first_note; - Note *last_note; - union{ - struct{ - Decl_Enum_Child *first; - Decl_Enum_Child *last; - } enum_val; - struct{ - Decl *first; - Decl *last; - } aggregate_val; - struct{ - Decl *first; - Decl *last; - Type *return_type; - }func_val; - struct{ - Type *type; - Expr *expr; - }var_val; - struct{ - Type *type; - }typedef_val; - }; -}; - -//----------------------------------------------------------------------------- -// Idea -//----------------------------------------------------------------------------- -typedef struct AST_Node AST_Node; -typedef enum AST_Kind{ - AK_None, - AK_Undefined, - AK_BaseType, - AK_Typedef, - AK_Pointer, - AK_Struct, - AK_Union, - AK_Array, - AK_Function, - AK_Variable, - AK_EnumChild, -}AST_Kind; - -struct AST_Node{ - AST_Kind kind; - Intern_String name; - Expr *expr; - Token *pos; - - AST_Node *next; - AST_Node *first_note; - AST_Node *last_note; - union{ - AST_Node *pointer; - struct{ - SizeU size; - }base_type_val; - struct{ - AST_Node *type; - }typedef_val; - struct{ - AST_Node *return_type; - AST_Node *first; - AST_Node *last; - }func_val; - struct{ - AST_Node *first; - AST_Node *last; - }aggregate; - struct{ - AST_Node *first; - AST_Node *last; - }enum_val; - }; -}; - -// Then I can yoink the entire idea of a symbol -// cause AST_Node is THE symbol -typedef struct Scope{ - Scope *next; - AST_Node *first; - AST_Node *last; -}Scope; - -{ - Scope *first; - Scope *last; -} - -scope_pop(Parser *p) diff --git a/expr.c b/expr.c index 9ded132..b4624e7 100644 --- a/expr.c +++ b/expr.c @@ -54,7 +54,7 @@ expr_index(Parser *p, Token *token, Expr *atom, Expr *index){ } function Expr * -expr_cast(Parser *p, Token *token, Type *type, Expr *exp){ +expr_cast(Parser *p, Token *token, AST_Node *type, Expr *exp){ Expr *expr = expr_new(p, EK_Cast, token); expr->cast.type = type; expr->cast.expr = exp; diff --git a/expr.h b/expr.h index adc0dbf..12d12a3 100644 --- a/expr.h +++ b/expr.h @@ -19,7 +19,7 @@ struct Expr { Expr *next; union { struct { - Type *type; + AST_Node *type; Expr* expr; } cast; struct { diff --git a/lang.h b/lang.h index f3955e6..34f6f4a 100644 --- a/lang.h +++ b/lang.h @@ -48,4 +48,18 @@ if((f)==0){\ else{\ (l)=(l)->next=(n);\ } \ -}while(0) \ No newline at end of file +}while(0) + + +#define SLLStackPush(l,n) do{\ +(n)->next = (l);\ +(l) = (n);\ +}while(0) + +#define SLLStackPop(l,n) do{\ +if(l){\ +(n) = (l);\ +(l) = (l)->next;\ +(n)->next = 0;\ +}\ +}while(0) diff --git a/main.c b/main.c index 549feb5..af9e539 100644 --- a/main.c +++ b/main.c @@ -5,11 +5,11 @@ #include "lang.h" #include "os.h" #include "memory.h" + #include "lex.h" +#include "ast.h" #include "parser.h" -#include "type.h" #include "expr.h" -#include "decl.h" global FILE *global_output_file; #define lex_print(...) fprintf(global_output_file, __VA_ARGS__) @@ -19,10 +19,10 @@ global FILE *global_output_file; #include "memory.c" #include "parser.c" #include "os_win32.c" + #include "lex.c" #include "expr.c" -#include "decl.c" -#include "type.c" +#include "ast.c" #include "parse_expr.c" #include "parse_decl.c" #include "print.c" @@ -98,21 +98,15 @@ parser_test(){ expr_print(expr); lex_print("\n"); } - type_test(&p); - lex_new_line(); String decls[] = { - lit("enum Thing{ Thing_1, Thing_2 = 2}"), - lit("global S64 *variable[10] = 10"), - lit("global S64 (*variable)(S64 thing) = 10"), - lit("struct Thing{ S64 a; U64 *b; union A{ S64 thing; }; }"), + lit("enum Thing{ Thing_1 = 10, Thing_2 = 20<<1 };"), }; for(S64 i = 0; i < buff_cap(decls); i++){ parser_lex_stream(&p, decls[i], lit("File")); - Decl *decl = parse_decl_global(&p); - assert(decl); - decl_print(decl); - lex_new_line(); + AST_Node *node = parse(&p); + assert(node); + } } diff --git a/parse_decl.c b/parse_decl.c index ca84f06..db70ff8 100644 --- a/parse_decl.c +++ b/parse_decl.c @@ -1,218 +1,90 @@ -function Decl *parse_decl_variable(Parser *p); +global Intern_String intern_empty; -function B32 -intern_empty(Intern_String a){ - B32 result = (a.s.str == 0); - return result; -} - -function Decl * -parse_decl_enum(Parser *p){ - Token *token = token_get(p); - Intern_String name = {}; - if(token_match(p, TK_Identifier)){ - name = token->intern_val; - } - - Decl *result = decl_enum(p, token, name); +function AST_Node * +parse_enum(Parser *p){ + AST_Node *result = 0; + Token *name = token_match(p, TK_Identifier); if(token_match(p, TK_OpenBrace)){ - for(;;){ - Token *token = token_get(p); - if(token_match(p, TK_Identifier)){ - Expr *expr = 0; - if(token_match(p, TK_Assign)){ - expr = parse_expr(p); - } - Decl_Enum_Child *child = decl_enum_child(p, token, expr); - const_val_insert(p, token, type_s64, token->intern_val, expr); - decl_enum_push(result, child); - } - else break; + Token *op_close_brace = token_match(p, TK_CloseBrace); + + if(!op_close_brace){ + + result = ast_enum(p, name, name->intern_val); + do{ // Parse enum members + Token *identifier = token_match(p, TK_Identifier); + if(identifier){ + Expr *expr = 0; + if(token_match(p, TK_Assign)){ + expr = parse_expr(p); + } + AST_Node *child = ast_enum_child(p, identifier, identifier->intern_val, expr); + ast_node_push_child(result, child); + { + // Insert into scope + } + } + else { + parser_push_error(p, token_get(p), "invalid syntax of enum member"); + break; + } + } while(token_match(p, TK_Comma)); + token_expect(p, TK_CloseBrace); - if(!token_match(p, TK_Comma)) - break; } - token_expect(p, TK_CloseBrace); - } - else { - if(name.s.str == 0){ - parser_push_error(p, token, "Unnamed enum without body is illegal"); - } - } - - if(!intern_empty(name)){ - Type *type = type_enum(p, result); - type_insert(p, type, name); - } - - return result; -} - -function void -parse_decl_variable_right(Parser *p, Type **type, Token **name){ - while(token_match(p, TK_Mul)){ - *type = type_pointer(p, *type); - }; - *name = token_expect(p, TK_Identifier); - while(token_match(p, TK_OpenBracket)){ - Expr *expr = parse_expr(p); - *type = type_array(p, *type, expr); - token_expect(p, TK_CloseBracket); - } -} - -function void -parse_argument_list(Parser *p, Decl *func){ - if(!token_is(p, TK_CloseParen)){ - do{ - Decl *var = parse_decl_variable(p); - decl_function_push(func, var); - }while(token_match(p, TK_Comma)); - } -} - -function Decl * -parse_decl_variable(Parser *p){ - Decl *result = 0; - Token *name = 0; - Type *type = 0; - Token *token = token_get(p); - if(token_match(p, TK_Identifier) || - token_match(p, TK_Keyword)){ - type = type_get(p, token->intern_val); - if(token_match(p, TK_OpenParen)){ - token_expect(p, TK_Mul); - if((name = token_expect(p, TK_Identifier))){ - token_expect(p, TK_CloseParen); - token_expect(p, TK_OpenParen); - Decl *function_p = decl_function(p, name, type); - parse_argument_list(p, function_p); - token_expect(p, TK_CloseParen); - type = type_function_pointer(p, function_p); - } - } - else { - parse_decl_variable_right(p, &type, &name); + else{ + parser_push_error(p, op_close_brace, "enum without body"); } } else{ - parser_push_error(p, token, "Expected type when parsing global variable"); + if(name == 0){ + parser_push_error(p, token_get(p), "enum without name or body is illegal"); + } } - Expr *expr = 0; - if(token_match(p, TK_Assign)){ - expr = parse_expr(p); - } - - if(name){ - result = decl_variable(p, name, type, expr); + if(ast_is_named(result)){ + // Insert into scope } return result; } -function Decl * -parse_decl_and_register_variable(Parser *p){ - Decl *result = parse_decl_variable(p); - if(result){ - variable_insert(p, result); - } - return result; -} - -function Decl * -parse_struct(Parser *p, Decl_Kind kind){ - Token *token = token_get(p); - Token *name = token_match(p, TK_Identifier); - Decl *result = decl_struct(p, token, name->intern_val); - result->kind = kind; +function AST_Node_List * +parse(Parser *p){ + AST_Node_List *result = ast_node_new(p, AK_List, token_get(p), intern_empty); - if(token_expect(p, TK_OpenBrace)){ - do{ - if(token_match_keyword(p, keyword_struct)){ - Decl *val = parse_struct(p, DK_Struct); - decl_aggregate_push(result, val); - } - else if(token_match_keyword(p, keyword_union)){ - Decl *val = parse_struct(p, DK_Union); - decl_aggregate_push(result, val); - } - else if(token_is(p, TK_Keyword) || token_is(p, TK_Identifier)){ - Decl *val = parse_decl_variable(p); - decl_aggregate_push(result, val); - } - else if(token_is(p, TK_CloseBrace)){ - break; - } - else { - parser_push_error(p, token_get(p), "Failed to parse struct, unexpected token"); - break; - } - }while(token_match(p, TK_Semicolon)); + for(;;){ + AST_Node *node = 0; - token_expect(p, TK_CloseBrace); - } - - if(name){ - Type *type = type_struct(p, result); - type_insert(p, type, name->intern_val); - } - - return result; -} - -function Decl * -parse_decl_typedef(Parser *p){ - Decl *result = decl_type(p, token_get(p), 0, (Intern_String){}); - if(token_match_keyword(p, keyword_enum)){ - Decl *e = parse_decl_enum(p); - result->typedef_val.type = type_enum(p, e); - } - else if(token_match_keyword(p, keyword_union)){ - Decl *e = parse_struct(p, DK_Union); - result->typedef_val.type = type_struct(p, e); - } - else if(token_match_keyword(p, keyword_struct)){ - Decl *e = parse_struct(p, DK_Struct); - result->typedef_val.type = type_struct(p, e); - } - else if(token_is(p, TK_Keyword) || token_is(p, TK_Identifier)){ - Token *token = token_next(p); - result->typedef_val.type = type_get(p, token->intern_val); - } - else { - parser_push_error(p, token_get(p), "Failed to parse typedef, unexpected token"); - } - - Token *name = token_expect(p, TK_Identifier); - if(name){ - result->name = name->intern_val; - type_insert(p, type_typedef(p, result), result->name); - } - - return result; -} - -function Decl * -parse_decl_global(Parser *p){ - Decl *result = 0; - if(token_match_keyword(p, keyword_typedef)){ - result = parse_decl_typedef(p); - } - else if(token_match_keyword(p, keyword_enum)){ - result = parse_decl_enum(p); - } - else if(token_match_keyword(p, keyword_union)){ - result = parse_struct(p, DK_Union); - } - else if(token_match_keyword(p, keyword_struct)){ - result = parse_struct(p, DK_Struct); - } - else if(token_match_keyword(p, keyword_global)){ - result = parse_decl_variable(p); - } - else if(token_match_keyword(p, keyword_function)){ + if(token_is(p, TK_End)){ + break; + } + else if(token_is(p, TK_Error)){ + break; + } + else if(token_match_keyword(p, keyword_struct)){ + + } + else if(token_match_keyword(p, keyword_union)){ + + } + else if(token_match_keyword(p, keyword_enum)){ + node = parse_enum(p); + token_expect(p, TK_Semicolon); + } + else if(token_match_keyword(p, keyword_function)){ + + } + else if(token_match_keyword(p, keyword_typedef)){ + + } + else { + token_next(p); + } + if(node){ + ast_node_push_child(result, node); + } } + return result; -} +} \ No newline at end of file diff --git a/parse_expr.c b/parse_expr.c index 4fb649a..874c264 100644 --- a/parse_expr.c +++ b/parse_expr.c @@ -93,8 +93,9 @@ Expr* parse_unary_expr(Parser* p) { else if (token_is(p, TK_OpenParen)) { // cast requires lookahead Token *token = token_peek(p, 1); if (token->kind == TK_Keyword || token->kind == TK_Identifier) { - Type *type = type_get(p, token->intern_val); - if(type != type_undefined){ + + AST_Node *type = symbol_lookup_type(p, token->intern_val); + if(type){ token_next(p); token_next(p); // @Todo(Krzosa): Parse pointer types @@ -105,6 +106,7 @@ Expr* parse_unary_expr(Parser* p) { else { result = parse_postfix_expr(p); } + } else { result = parse_postfix_expr(p); diff --git a/parser.c b/parser.c index 1540476..1a12f7a 100644 --- a/parser.c +++ b/parser.c @@ -11,13 +11,18 @@ global Intern_String keyword_union; global Intern_String keyword_function; global Intern_String keyword_global; +global AST_Node *type_s64; +global AST_Node *type_u64; +global AST_Node *type_void; +global AST_Node *type_sizeu; + function void parser_init(Parser *p){ p->interns_count = 4096; p->interns = arena_push_array(&p->intern_table_arena, Intern_String, p->interns_count); p->symbols_count = 4096; - p->symbols = arena_push_array(&p->intern_table_arena, Intern_String, p->symbols_count); + p->symbols = arena_push_array(&p->symbol_table_arena, AST_Node, p->symbols_count); keyword_s64 = intern_string(p, lit("S64")); keyword_u64 = intern_string(p, lit("U64")); @@ -33,10 +38,12 @@ parser_init(Parser *p){ p->first_keyword = keyword_s64.s.str; p->last_keyword = keyword_global.s.str; - type_insert(p, type_s64, keyword_s64); - type_insert(p, type_u64, keyword_u64); - type_insert(p, type_sizeu, keyword_sizeu); - type_insert(p, type_void, keyword_void); + parser_push_scope(p); // Global scope + type_s64 = symbol_register_basic_type(p, keyword_s64, sizeof(S64)); + type_u64 = symbol_register_basic_type(p, keyword_u64, sizeof(U64)); + type_sizeu = symbol_register_basic_type(p, keyword_sizeu, sizeof(SizeU)); + type_void = symbol_register_basic_type(p, keyword_void, sizeof(void)); + } function B32 @@ -46,6 +53,19 @@ intern_is_keyword(Parser *p, Intern_String intern){ return false; } +function void +intern_tokens(Parser *p){ + for(S64 i = 0; i < p->tokens.len; i++){ + Token *t = p->tokens.tokens + i; + if(t->kind == TK_Identifier){ + t->intern_val = intern_string(p, t->string); + if(intern_is_keyword(p, t->intern_val)){ + t->kind = TK_Keyword; + } + } + } +} + function void parser_push_error(Parser *p, Token *token, char *str, ...){ @@ -130,122 +150,100 @@ intern_string(Parser *p, String string){ return result; } -function void -intern_tokens(Parser *p){ - for(S64 i = 0; i < p->tokens.len; i++){ - Token *t = p->tokens.tokens + i; - if(t->kind == TK_Identifier){ - t->intern_val = intern_string(p, t->string); - if(intern_is_keyword(p, t->intern_val)){ - t->kind = TK_Keyword; - } - } - } -} - -function Symbol * -symbol_get_slot(Parser *p, Intern_String intern){ - String string = intern.s; - Table_Index index = table_index_from_string(string, p->symbols_count); - +//----------------------------------------------------------------------------- +// Symbols +//----------------------------------------------------------------------------- +function AST_Node * +symbol_alloc_slot(Parser *p, Intern_String string, B32 is_global){ + Table_Index index = table_index_from_string(string.s, p->symbols_count); for(;;){ - Symbol *slot = p->symbols + index.iter; - if(slot->string.s.str == 0){ - slot->string = intern; + AST_Node *symbol = p->symbols + index.iter; + + if(symbol->name.s.str == 0){ + /* @Note(Krzosa): Push on scope */ { + if(is_global){ + SLLQueuePush(p->scope_stack->first, p->scope_stack->last, symbol); + } + else{ + SLLQueuePush(p->global_scope->first, p->global_scope->last, symbol); + } + } + symbol->name = string; p->symbols_inserted++; - return slot; + + return symbol; } - else if(slot->string.s.str == string.str){ - return slot; + else if(intern_compare(symbol->name, string)){ + return symbol; } if (table_index_advance(&index)) break; - } - parser_push_error(p, token_get(p), "Failed to find a spot for symbol"); return 0; } -function Symbol * -symbol_get(Parser *p, Intern_String string){ +function AST_Node * +symbol_lookup(Parser *p, Intern_String string){ Table_Index index = table_index_from_string(string.s, p->symbols_count); for(;;){ - Symbol *slot = p->symbols + index.iter; - if(slot->string.s.str == string.s.str){ - return slot; + AST_Node *symbol = p->symbols + index.iter; + + if(symbol->name.s.str == 0){ + return 0; + } + else if(intern_compare(symbol->name, string)){ + return symbol; } - if (table_index_advance(&index)) - break; - + if (table_index_advance(&index)) + return 0; + } +} + +function AST_Node * +symbol_register_basic_type(Parser *p, Intern_String string, SizeU size){ + AST_Node *node = symbol_alloc_slot(p, string, true); + node->kind = AK_BaseType; + node->base_type_size = size; + return node; +} + +function AST_Node * +symbol_lookup_type(Parser *p, Intern_String string){ + AST_Node *node = symbol_lookup(p, string); + if(node){ + if(ast_is_type(node)){ + return node; + } } return 0; } -function B32 -symbol_require_empty(Parser *p, Symbol *symbol){ - assert(symbol); - B32 result = symbol->kind == SK_None; - if(!result){ - // @Todo(Krzosa): Should send symbol name not token - parser_push_error(p, token_get(p), "This symbol name is already registered"); - } - return result; -} - function void -const_val_insert(Parser *p, Token *token, Type *type, Intern_String string, Expr *expr){ - Symbol *symbol = symbol_get_slot(p, string); - if(symbol_require_empty(p, symbol)){ - symbol->kind = SK_Const; - symbol->token = token; - symbol->const_val.type = type; - symbol->const_val.expr = expr; +parser_push_scope(Parser *p){ + Scope *scope = 0; + SLLStackPop(p->scope_free_list, scope); + if(!scope){ + scope = arena_push_struct(&p->main_arena, Scope); + } + SLLStackPush(p->scope_stack, scope); + if(p->global_scope == 0){ + p->global_scope = scope; } } function void -variable_insert(Parser *p, Decl *decl){ - Symbol *symbol = symbol_get_slot(p, decl->name); - if(symbol_require_empty(p, symbol)){ - symbol->kind = SK_Decl; - symbol->decl = decl; - symbol->string = decl->name; - symbol->token = decl->token; - } -} - -function void -type_insert(Parser *p, Type *type, Intern_String string){ - Symbol *symbol = symbol_get_slot(p, string); - if(symbol_require_empty(p, symbol)){ - symbol->kind = SK_Type; - symbol->type = type; - symbol->string = string; - } -} - -function Type * -type_get(Parser *p, Intern_String string){ - Type *result = 0; - Symbol *symbol = symbol_get(p, string); - if(symbol){ - if(symbol->kind == SK_Type){ - result = symbol->type; - } - else { - parser_push_error(p, token_get(p), "Symbol is not a type"); - } - } - else{ - parser_push_error(p, token_get(p), "Undefined type"); - } +parser_pop_scope(Parser *p){ + Scope *scope = 0; + SLLStackPop(p->scope_stack, scope); + assert(scope); - if(!result){ - result = type_undefined; + for(AST_Node *s = scope->first; s; s=s->scope_next){ + memory_zero(s, sizeof(AST_Node)); + p->symbols_inserted--; } - - return result; + memory_zero(scope, sizeof(Scope)); + SLLStackPush(p->scope_free_list, scope); } diff --git a/parser.h b/parser.h index 83eacc8..50fbb8f 100644 --- a/parser.h +++ b/parser.h @@ -1,43 +1,32 @@ #pragma once -typedef struct Type Type; typedef struct Expr Expr; -typedef struct Decl Decl; +typedef struct Scope Scope; +typedef struct AST_Node AST_Node; typedef struct Parser_Error Parser_Error; -typedef enum Symbol_Kind{ - SK_None, - SK_Type, - SK_Const, - SK_Decl, -}Symbol_Kind; - -typedef struct Symbol{ - Symbol_Kind kind; - Intern_String string; - Token *token; - struct{ - Type *type; - struct{ - Type *type; - Expr *expr; - } const_val; - Decl *decl; - }; -}Symbol; - struct Parser_Error{ Parser_Error *next; String message; Token *token; }; +struct Scope{ + Scope *next; + AST_Node *first; + AST_Node *last; +}; + typedef 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; - Symbol *symbols; + AST_Node *symbols; S64 symbols_count; S64 interns_in_bytes; @@ -55,5 +44,7 @@ typedef struct Parser{ }Parser; function Intern_String intern_string(Parser *p, String string); -function void type_insert(Parser *p, Type *type, Intern_String string); function Token *token_get(Parser *p); +function B32 intern_compare(Intern_String a, Intern_String b); +function void parser_push_scope(Parser *p); +function AST_Node *symbol_register_basic_type(Parser *p, Intern_String string, SizeU size); diff --git a/print.c b/print.c index 79a593d..33efe50 100644 --- a/print.c +++ b/print.c @@ -12,45 +12,6 @@ token_print(Token *token){ lex_print("%.*s", (S32)token->len, token->str); } -function Type *type_pointer(Parser *p, Type *base); -function void expr_print(Expr *expr); - -function void -type_print(Type *type){ - switch(type->kind) { - case TK_S64: case TK_U64: - case TK_SizeU: case TK_Void: { - lex_print("%s", type_kind_string[type->kind].str); - } break; - case TK_Pointer:{ - type_print(type->pointer); - lex_print("*"); - } break; - case TK_Function:{ - type_print(type->decl->func_val.return_type); - lex_print("("); - for(Decl *n = type->decl->func_val.first; n; n=n->next){ - token_print(n->token); // @Todo(Krzosa): - } - lex_print(")"); - } break; - case TK_Array:{ - type_print(type->array.pointer); - lex_print("["); - expr_print(type->array.size); - lex_print("]"); - } break; - default: {invalid_codepath;} break; - } -} - -function void -type_test(Parser *p){ - Type *t = type_pointer(p, type_s64); - t = type_pointer(p, t); - type_print(t); -} - function void expr_print(Expr *expr){ switch(expr->kind) { @@ -93,7 +54,7 @@ expr_print(Expr *expr){ case EK_Cast:{ lex_print("("); lex_print("("); - type_print(expr->cast.type); + //type_print(expr->cast.type); lex_print(")"); expr_print(expr->cast.expr); lex_print(")"); @@ -113,44 +74,3 @@ expr_print(Expr *expr){ default: {invalid_codepath;} break; } } - -function void -decl_print(Decl *decl){ - switch(decl->kind) { - - case DK_Union: lex_print("union"); - case DK_Struct:{ - lex_print("struct %s{\n", decl->name.s.str); - for(Decl *n = decl->aggregate_val.first; n; n=n->next){ - decl_print(n); - lex_print(";\n"); - } - lex_print("}\n"); - } break; - - case DK_Variable:{ - type_print(decl->var_val.type); - lex_print(" %s", decl->name.s.str); - if(decl->var_val.expr){ - lex_print(" = "); - expr_print(decl->var_val.expr); - } - } break; - - case DK_Enum: { - lex_print("enum %s{\n", decl->name.s.str); - for(Decl_Enum_Child *n = decl->enum_val.first; n; n=n->next){ - lex_print(" "); - token_print(n->token); - if(n->expr){ - lex_print(" = "); - expr_print(n->expr); - } - lex_print(","); - lex_new_line(); - } - lex_print("};\n"); - } break; - default: {invalid_codepath;} break; - } -} \ No newline at end of file diff --git a/type.c b/type.c deleted file mode 100644 index dd7c64f..0000000 --- a/type.c +++ /dev/null @@ -1,59 +0,0 @@ - -function Type * -type_new(Parser *p, Type_Kind kind){ - Type *result = arena_push_struct(&p->main_arena, Type); - result->kind = kind; - return result; -} - -function Type * -type_pointer(Parser *p, Type *base){ - Type *result = type_new(p, TK_Pointer); - result->size = sizeof(SizeU); - result->pointer = base; - return result; -} - -function Type * -type_array(Parser *p, Type *base, Expr *index){ - Type *result = type_new(p, TK_Array); - result->array.pointer = base; - result->array.size = index; - return result; -} - -function Type * -type_enum(Parser *p, Decl *enum_val){ - Type *result = type_new(p, TK_Enum); - result->decl = enum_val; - return result; -} - -function Type * -type_struct(Parser *p, Decl *struct_val){ - Type *result = type_new(p, TK_Struct); - result->decl = struct_val; - return result; -} - -function Type * -type_union(Parser *p, Decl *union_val){ - Type *result = type_new(p, TK_Union); - result->decl = union_val; - return result; -} - -function Type * -type_function_pointer(Parser *p, Decl *func_val){ - Type *result = type_new(p, TK_Function); - result->decl = func_val; - result = type_pointer(p, result); - return result; -} - -function Type * -type_typedef(Parser *p, Decl *typedef_val){ - Type *result = type_new(p, TK_Typedef); - result->decl = typedef_val; - return result; -} \ No newline at end of file diff --git a/type.h b/type.h deleted file mode 100644 index 3b123b8..0000000 --- a/type.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -typedef struct Type Type; -typedef struct Expr Expr; -typedef struct Decl Decl; - -typedef enum Type_Kind{ - TK_None, - TK_Void, - TK_S64, - TK_U64, - TK_SizeU, - - TK_Undefined, - TK_Typedef, - TK_Function, - TK_Pointer, - TK_Enum, - TK_Array, - TK_Struct, - TK_Union, -} Type_Kind; - -struct Type{ - Type_Kind kind; - SizeU size; - union{ - Type *pointer; - Decl *decl; - struct{ - Type *pointer; - Expr *size; - } array; - }; -}; - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -global String type_kind_string[] = { - [TK_None] = lit("None"), - [TK_Void] = lit("void"), - [TK_S64] = lit("S64"), - [TK_U64] = lit("U64"), - [TK_SizeU] = lit("SizeU"), - [TK_Undefined] = lit("Undefined"), - [TK_Pointer] = lit("Pointer"), - [TK_Array] = lit("Array"), - [TK_Struct] = lit("Struct"), - [TK_Union] = lit("Union"), -}; - -global Type type_table[] = { - [TK_None] = {0}, - [TK_Void] = {TK_Void}, - [TK_S64] = {TK_S64, sizeof(S64)}, - [TK_U64] = {TK_U64, sizeof(U64)}, - [TK_SizeU] = {TK_SizeU, sizeof(SizeU)}, - [TK_Undefined] = {TK_Undefined}, - [TK_Pointer] = {TK_Pointer,sizeof(SizeU)}, - [TK_Array] = {TK_Array,sizeof(SizeU)}, - [TK_Struct] = {TK_Struct}, - [TK_Union] = {TK_Union}, -}; - -global Type *type_void = type_table + 1; -global Type *type_s64 = type_table + 2; -global Type *type_u64 = type_table + 3; -global Type *type_sizeu = type_table + 4; -global Type *type_undefined = type_table + 5;