include and global works
This commit is contained in:
		
							parent
							
								
									ad2baf22d2
								
							
						
					
					
						commit
						bdf3516455
					
				
							
								
								
									
										81
									
								
								asm/main.c
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								asm/main.c
									
									
									
									
									
								
							| @ -18,6 +18,12 @@ typedef struct { | ||||
|     const char* output_file; | ||||
| } Args; | ||||
| 
 | ||||
| typedef struct { | ||||
|     char* ident; | ||||
|     Loc loc; | ||||
|     uint16_t ip; | ||||
| } GlobalSym; | ||||
| 
 | ||||
| static inline Args parse_args(int argc, char** argv); | ||||
| static inline char* read_text_file(const char* filename); | ||||
| static inline int include_file(IdentResolver* resolver, | ||||
| @ -60,22 +66,37 @@ int main(int argc, char** argv) | ||||
|     PLine** lines = malloc(sizeof(PLine*) * lines_capacity); | ||||
|     size_t lines_size = 0; | ||||
| 
 | ||||
|     size_t global_symbols_capacity = 8; | ||||
|     GlobalSym* global_symbols | ||||
|         = malloc(sizeof(GlobalSym) * global_symbols_capacity); | ||||
|     size_t global_symbols_size = 0; | ||||
| 
 | ||||
|     while (!parser_done(&parser)) { | ||||
|         if (lines_size + 1 > lines_capacity) { | ||||
|             lines_capacity += 2; | ||||
|             lines = realloc(lines, sizeof(PLine*) * lines_capacity); | ||||
|         } | ||||
|         PStmt* stmt = parser_next_stmt(&parser); | ||||
|         if (!stmt) { | ||||
|             continue; | ||||
|         } | ||||
|         switch (stmt->ty) { | ||||
|             case PStmtTy_Line: | ||||
|                 if (lines_size + 1 > lines_capacity) { | ||||
|                     lines_capacity *= 2; | ||||
|                     lines = realloc(lines, sizeof(PLine*) * lines_capacity); | ||||
|                 } | ||||
|                 lines[lines_size++] = stmt->line; | ||||
|                 // NOTE: Shallow free.
 | ||||
|                 free(stmt); | ||||
|                 break; | ||||
|             case PStmtTy_Global: | ||||
|                 if (global_symbols_size + 1 > global_symbols_capacity) { | ||||
|                     global_symbols_capacity *= 2; | ||||
|                     global_symbols = realloc(global_symbols, | ||||
|                         sizeof(GlobalSym) * global_symbols_capacity); | ||||
|                 } | ||||
|                 global_symbols[global_symbols_size++] = (GlobalSym) { | ||||
|                     .ident = asm_strdup(stmt->ident), | ||||
|                     .loc = stmt->loc, | ||||
|                     .ip = 0, | ||||
|                 }; | ||||
|                 pstmt_free(stmt); | ||||
|                 break; | ||||
|             case PStmtTy_Extern: | ||||
| @ -85,8 +106,17 @@ int main(int argc, char** argv) | ||||
|                 const IdentResol* existing | ||||
|                     = ident_resolver_resolve(&resolver, stmt->ident); | ||||
|                 if (existing != NULL) { | ||||
|                     REPORTF_ERROR("redefinition of constant '%s'", stmt->ident); | ||||
|                     REPORTF_ERROR( | ||||
|                         "redefinition of identifier '%s'", stmt->ident); | ||||
|                     reporter_print_loc(&rep, stmt->loc); | ||||
|                     const char* filename = rep.filename; | ||||
|                     if (existing->ty == IdentResolTy_Const) { | ||||
|                         filename = existing->src_filename; | ||||
|                     } | ||||
|                     REPORTF_INFO( | ||||
|                         "previous definition of '%s' here", existing->ident); | ||||
|                     reporter_print_loc(&rep, existing->loc); | ||||
|                     rep.filename = filename; | ||||
|                     errors_occured = true; | ||||
|                     pstmt_free(stmt); | ||||
|                     continue; | ||||
| @ -134,6 +164,24 @@ int main(int argc, char** argv) | ||||
|         ip += size; | ||||
|     } | ||||
| 
 | ||||
|     for (size_t i = 0; i < global_symbols_size; ++i) { | ||||
|         const IdentResol* res | ||||
|             = ident_resolver_resolve(&resolver, global_symbols[i].ident); | ||||
|         if (res == NULL) { | ||||
|             REPORTF_ERROR("undefined global '%s'", global_symbols[i].ident); | ||||
|             REPORTF_INFO("'%s' declared global here", global_symbols[i].ident); | ||||
|             reporter_print_loc(&rep, global_symbols[i].loc); | ||||
|             continue; | ||||
|         } else if (res->ty != IdentResolTy_Label) { | ||||
|             REPORTF_ERROR("'%s' cannot be declared global", res->ident); | ||||
|             reporter_print_loc(&rep, res->loc); | ||||
|             REPORTF_INFO("'%s' declared global here", global_symbols[i].ident); | ||||
|             reporter_print_loc(&rep, global_symbols[i].loc); | ||||
|             continue; | ||||
|         } | ||||
|         global_symbols[i].ip = res->ip; | ||||
|     } | ||||
| 
 | ||||
|     if (errors_occured) { | ||||
|         fprintf(stderr, "nothing written. stopping...\n"); | ||||
|         res = -1; | ||||
| @ -188,6 +236,10 @@ leave_free_chunk: | ||||
|     for (size_t i = 0; i < lines_size; ++i) { | ||||
|         pline_free(lines[i]); | ||||
|     } | ||||
|     for (size_t i = 0; i < global_symbols_size; ++i) { | ||||
|         free(global_symbols[i].ident); | ||||
|     } | ||||
|     free(global_symbols); | ||||
|     free(lines); | ||||
|     free(input_text); | ||||
|     ident_resolver_destroy(&resolver); | ||||
| @ -270,8 +322,23 @@ static inline int include_file(IdentResolver* resolver, | ||||
|                 const IdentResol* existing | ||||
|                     = ident_resolver_resolve(resolver, stmt->ident); | ||||
|                 if (existing != NULL) { | ||||
|                     REPORTF_ERROR("redefinition of constant '%s'", stmt->ident); | ||||
|                     if (existing->ty == IdentResolTy_Const | ||||
|                         && strcmp(existing->src_filename, filepath) == 0) { | ||||
|                         // Same file included multiple times.
 | ||||
|                         pstmt_free(stmt); | ||||
|                         continue; | ||||
|                     } | ||||
|                     REPORTF_ERROR( | ||||
|                         "redefinition of identifier '%s'", stmt->ident); | ||||
|                     reporter_print_loc(&rep, stmt->loc); | ||||
|                     const char* filename = rep.filename; | ||||
|                     if (existing->ty == IdentResolTy_Const) { | ||||
|                         filename = existing->src_filename; | ||||
|                     } | ||||
|                     REPORTF_INFO( | ||||
|                         "previous definition of '%s' here", existing->ident); | ||||
|                     reporter_print_loc(&rep, existing->loc); | ||||
|                     rep.filename = filename; | ||||
|                     errors_occured = true; | ||||
|                     pstmt_free(stmt); | ||||
|                     continue; | ||||
| @ -372,7 +439,7 @@ static inline void use_labels(IdentResolver* resolver, PLabel* label) | ||||
|         return; | ||||
|     use_labels(resolver, label->next); | ||||
|     const IdentResol* existing = ident_resolver_resolve(resolver, label->ident); | ||||
|     if (existing->ty == IdentResolTy_Label) { | ||||
|     if (existing && existing->ty == IdentResolTy_Label) { | ||||
|         resolver->current_parent = existing; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										12
									
								
								asm/report.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								asm/report.c
									
									
									
									
									
								
							| @ -4,6 +4,12 @@ | ||||
| void print_report_loc( | ||||
|     const char* filename, const char* text, size_t text_len, Loc loc) | ||||
| { | ||||
|     const char* displacement_spaces | ||||
|         = "                                                                " | ||||
|           "                                                                " | ||||
|           "                                                                " | ||||
|           "                                                                "; | ||||
| 
 | ||||
|     size_t line_start = loc.idx; | ||||
|     while (line_start > 0 && text[line_start] != '\n') { | ||||
|         line_start -= 1; | ||||
| @ -20,8 +26,8 @@ void print_report_loc( | ||||
| 
 | ||||
|     fprintf(stderr, | ||||
|         "    \x1b[96m--> ./%s:%d:%d\n     " | ||||
|         "\x1b[37m|\n\x1b[96m%5d\x1b[37m|%.*s\n     " | ||||
|         "|%*c\x1b[1;91m^\x1b[0m\n", | ||||
|         "\x1b[37m|\n\x1b[96m%5d\x1b[37m|\x1b[0m%.*s\n     " | ||||
|         "\x1b[37m|%.*s\x1b[1;91m^\x1b[0m\n", | ||||
|         filename, | ||||
|         loc.line, | ||||
|         loc.col, | ||||
| @ -29,7 +35,7 @@ void print_report_loc( | ||||
|         line_len, | ||||
|         line, | ||||
|         loc.col - 1, | ||||
|         ' '); | ||||
|         displacement_spaces); | ||||
| } | ||||
| 
 | ||||
| void reporter_print_loc(Reporter* rep, Loc loc) | ||||
|  | ||||
| @ -1,6 +1,10 @@ | ||||
| 
 | ||||
| include "arch.asm" | ||||
| 
 | ||||
| 
 | ||||
| global start | ||||
| extern other | ||||
| 
 | ||||
| start: | ||||
|     ; rsp points *at* the top element | ||||
|     mov rbp, 2048 | ||||
| @ -15,6 +19,8 @@ start: | ||||
|     mov r1, 1 | ||||
|     int Int_DiskRead | ||||
| 
 | ||||
|     jmp other | ||||
| 
 | ||||
| main_loop: | ||||
|     hlt | ||||
|     jmp main_loop | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user