@@ -29,8 +29,7 @@ typedef struct Parser {
2929
3030 struct ErrorVec errors ;
3131
32- struct Scope * global_scope ;
33- HashMap functions ;
32+ SymbolTable * symbol_table ;
3433} Parser ;
3534
3635#pragma region source range operations
@@ -175,24 +174,24 @@ static Expr* parse_identifier_expr(Parser* parser, Scope* scope)
175174
176175 MCC_ASSERT (token .tag == TOKEN_IDENTIFIER );
177176
178- const StringView identifier = str_from_token (parser -> src , token );
177+ const StringView name = str_from_token (parser -> src , token );
179178
180179 // TODO: handle typedef
181180 Expr * result = ARENA_ALLOC_OBJECT (parser -> permanent_arena , Expr );
182181
183182 // If local variable does not exist
184- const IdentifierInfo * variable = lookup_identifier (scope , identifier );
185- if (!variable ) {
183+ const IdentifierInfo * variable_identifier = lookup_identifier (scope , name );
184+ if (!variable_identifier ) {
186185 const StringView error_msg = allocate_printf (
187186 parser -> permanent_arena , "use of undeclared identifier '%.*s'" ,
188- (int )identifier .size , identifier .start );
187+ (int )name .size , name .start );
189188 parse_error_at (parser , error_msg , token_source_range (token ));
190189 }
191190
192191 // TODO: handle the case wher variable == nullptr
193192 * result = (Expr ){.tag = EXPR_VARIABLE ,
194193 .source_range = token_source_range (token ),
195- .variable = variable };
194+ .variable = variable_identifier };
196195 return result ;
197196}
198197
@@ -215,19 +214,18 @@ typedef enum Precedence {
215214 PREC_PRIMARY
216215} Precedence ;
217216
218- static Expr * parse_expr (Parser * parser , struct Scope * scope );
219- static Expr * parse_group (Parser * parser , struct Scope * scope );
220- static Expr * parse_unary_op (Parser * parser , struct Scope * scope );
217+ static Expr * parse_expr (Parser * parser , Scope * scope );
218+ static Expr * parse_group (Parser * parser , Scope * scope );
219+ static Expr * parse_unary_op (Parser * parser , Scope * scope );
221220static Expr * parse_binop_left (Parser * parser , Expr * lhs_expr ,
222- struct Scope * scope ); // left associative
221+ Scope * scope ); // left associative
223222static Expr * parse_assignment (Parser * parser , Expr * lhs_expr ,
224- struct Scope * scope ); // right associative
223+ Scope * scope ); // right associative
225224static Expr * parse_ternary (Parser * parser , Expr * cond , struct Scope * scope );
226- static Expr * parse_function_call (Parser * parser , Expr * function ,
227- struct Scope * scope );
225+ static Expr * parse_function_call (Parser * parser , Expr * function , Scope * scope );
228226
229- typedef Expr * (* PrefixParseFn )(Parser * , struct Scope * scope );
230- typedef Expr * (* InfixParseFn )(Parser * , Expr * , struct Scope * scope );
227+ typedef Expr * (* PrefixParseFn )(Parser * , Scope * scope );
228+ typedef Expr * (* InfixParseFn )(Parser * , Expr * , Scope * scope );
231229
232230typedef struct ParseRule {
233231 PrefixParseFn prefix ;
@@ -619,21 +617,34 @@ static DeclSpecifier parse_decl_specifiers(Parser* parser)
619617
620618static FunctionDecl * parse_function_decl (Parser * parser ,
621619 DeclSpecifier decl_specifier ,
622- Token name_token , struct Scope * scope );
620+ Token name_token , Scope * scope );
623621
624622static VariableDecl parse_variable_decl (Parser * parser ,
625623 DeclSpecifier decl_specifier ,
626- Token name_token , struct Scope * scope )
624+ Token name_token , Scope * scope )
627625{
628626 const StringView name = str_from_token (parser -> src , name_token );
629- // TODO: handle different linkages
630- IdentifierInfo * variable = add_identifier (
631- scope , name , IDENT_OBJECT , LINKAGE_NONE , parser -> permanent_arena );
627+
628+ const bool is_global_variable = scope == parser -> symbol_table -> global_scope ;
629+
630+ // TODO: properly handle linkage
631+ Linkage linkage = LINKAGE_NONE ;
632+ if (is_global_variable ) { linkage = LINKAGE_EXTERNAL ; }
633+
634+ IdentifierInfo * variable =
635+ add_identifier (parser -> symbol_table , scope , name , IDENT_OBJECT , linkage ,
636+ parser -> permanent_arena );
632637 if (!variable ) {
633- const StringView error_msg =
634- allocate_printf (parser -> permanent_arena , "redefinition of '%.*s'" ,
635- (int )name .size , name .start );
636- parse_error_at (parser , error_msg , token_source_range (name_token ));
638+ if (linkage != LINKAGE_NONE ) {
639+ variable = lookup_identifier (scope , name );
640+ MCC_ASSERT (variable != nullptr );
641+
642+ } else {
643+ const StringView error_msg =
644+ allocate_printf (parser -> permanent_arena , "redefinition of '%.*s'" ,
645+ (int )name .size , name .start );
646+ parse_error_at (parser , error_msg , token_source_range (name_token ));
647+ }
637648 }
638649
639650 Expr * initializer = nullptr ;
@@ -646,11 +657,11 @@ static VariableDecl parse_variable_decl(Parser* parser,
646657 // TODO: handle the case where variable == nullptr
647658 return (VariableDecl ){.type = decl_specifier .type ,
648659 .storage_class = decl_specifier .storage_class ,
649- .name = variable ,
660+ .identifier = variable ,
650661 .initializer = initializer };
651662}
652663
653- static Decl parse_decl (Parser * parser , struct Scope * scope )
664+ static Decl parse_decl (Parser * parser , Scope * scope )
654665{
655666 const DeclSpecifier decl_specifier = parse_decl_specifiers (parser );
656667 const Token name_token = parse_identifier (parser );
@@ -937,8 +948,9 @@ static IdentifierInfo* parse_parameter(Parser* parser, Scope* scope)
937948 parse_advance (parser );
938949 }
939950
940- IdentifierInfo * name = add_identifier (
941- scope , identifier , IDENT_OBJECT , LINKAGE_NONE , parser -> permanent_arena );
951+ IdentifierInfo * name =
952+ add_identifier (parser -> symbol_table , scope , identifier , IDENT_OBJECT ,
953+ LINKAGE_NONE , parser -> permanent_arena );
942954 // TODO: error handling
943955 MCC_ASSERT (name != nullptr );
944956 return name ;
@@ -1006,8 +1018,9 @@ static FunctionDecl* parse_function_decl(Parser* parser,
10061018 Token name_token , Scope * scope )
10071019{
10081020 StringView name = str_from_token (parser -> src , name_token );
1009- IdentifierInfo * function_ident = add_identifier (
1010- scope , name , IDENT_FUNCTION , LINKAGE_EXTERNAL , parser -> permanent_arena );
1021+ IdentifierInfo * function_ident =
1022+ add_identifier (parser -> symbol_table , scope , name , IDENT_FUNCTION ,
1023+ LINKAGE_EXTERNAL , parser -> permanent_arena );
10111024
10121025 if (!function_ident ) {
10131026 function_ident = lookup_identifier (scope , name );
@@ -1021,11 +1034,8 @@ static FunctionDecl* parse_function_decl(Parser* parser,
10211034 }
10221035 }
10231036
1024- hashmap_try_insert (& parser -> functions , name , function_ident ,
1025- parser -> permanent_arena );
1026-
10271037 Scope * function_scope =
1028- new_scope (parser -> global_scope , parser -> permanent_arena );
1038+ new_scope (parser -> symbol_table -> global_scope , parser -> permanent_arena );
10291039 const Parameters parameters = parse_parameter_list (parser , function_scope );
10301040
10311041 Block * body = NULL ;
@@ -1065,7 +1075,7 @@ static TranslationUnit* parse_translation_unit(Parser* parser)
10651075 struct DeclVec decl_vec = {};
10661076
10671077 while (parser_current_token (parser ).tag != TOKEN_EOF ) {
1068- Decl decl = parse_decl (parser , parser -> global_scope );
1078+ Decl decl = parse_decl (parser , parser -> symbol_table -> global_scope );
10691079 DYNARRAY_PUSH_BACK (& decl_vec , Decl , & parser -> scratch_arena , decl );
10701080 }
10711081
@@ -1077,12 +1087,9 @@ static TranslationUnit* parse_translation_unit(Parser* parser)
10771087
10781088 TranslationUnit * tu =
10791089 ARENA_ALLOC_OBJECT (parser -> permanent_arena , TranslationUnit );
1080- * tu = (TranslationUnit ){
1081- .decl_count = decl_count ,
1082- .decls = decls ,
1083- .global_scope = parser -> global_scope ,
1084- .functions = parser -> functions ,
1085- };
1090+ * tu = (TranslationUnit ){.decl_count = decl_count ,
1091+ .decls = decls ,
1092+ .symbol_table = parser -> symbol_table };
10861093 parse_consume (parser , TOKEN_EOF , "Expect end of the file" );
10871094
10881095 return tu ;
@@ -1091,12 +1098,17 @@ static TranslationUnit* parse_translation_unit(Parser* parser)
10911098ParseResult parse (const char * src , Tokens tokens , Arena * permanent_arena ,
10921099 Arena scratch_arena )
10931100{
1101+ SymbolTable * symbol_table = ARENA_ALLOC_OBJECT (permanent_arena , SymbolTable );
1102+ * symbol_table = (SymbolTable ){
1103+ .global_symbols = (HashMap ){},
1104+ .global_scope = new_scope (nullptr , permanent_arena ),
1105+ };
1106+
10941107 Parser parser = {.src = src ,
10951108 .tokens = tokens ,
10961109 .permanent_arena = permanent_arena ,
10971110 .scratch_arena = scratch_arena ,
1098- .global_scope = new_scope (nullptr , permanent_arena ),
1099- .functions = (HashMap ){}};
1111+ .symbol_table = symbol_table };
11001112
11011113 TranslationUnit * tu = parse_translation_unit (& parser );
11021114
0 commit comments