|
1 | 1 | #include "directives.h" |
| 2 | +#include "assembler.h" |
2 | 3 | #include "errors.h" |
3 | 4 | #include "functions.h" |
4 | 5 | #include "expression.h" |
|
22 | 23 | *(int*)stack_peek(state->line_number_stack), \ |
23 | 24 | state->line, COLUMN, stack_peek(state->file_name_stack) , ##__VA_ARGS__); |
24 | 25 |
|
| 26 | +#define WARN(WARN_CODE, COLUMN, ...) add_warning(state->warnings, WARN_CODE, \ |
| 27 | + *(int*)stack_peek(state->line_number_stack), \ |
| 28 | + state->line, COLUMN, stack_peek(state->file_name_stack) , ##__VA_ARGS__); |
| 29 | + |
25 | 30 | #define MAP_SOURCE(LENGTH) if (!state->expanding_macro && state->auto_source_maps) { \ |
26 | 31 | add_source_map((source_map_t *)stack_peek(state->source_map_stack), \ |
27 | 32 | *(int*)stack_peek(state->line_number_stack), state->line, \ |
@@ -226,7 +231,27 @@ int handle_db(struct assembler_state *state, char **argv, int argc) { |
226 | 231 | } |
227 | 232 |
|
228 | 233 | if (error == EXPRESSION_BAD_SYMBOL) { |
229 | | - /* TODO: Throw error if using explicit import */ |
| 234 | + |
| 235 | + if (scas_runtime.options.explicit_import) { |
| 236 | + tokenized_expression_t *changed_expression = malloc(sizeof(tokenized_expression_t)); |
| 237 | + memcpy(changed_expression, expression, sizeof(tokenized_expression_t)); |
| 238 | + int ignored_error; |
| 239 | + char *fixed_symbol; |
| 240 | + transform_local_labels(changed_expression, state->last_global_label); |
| 241 | + evaluate_expression(expression, state->equates, &ignored_error, &fixed_symbol); |
| 242 | + unresolved_symbol_t *unresolved_sym = malloc(sizeof(unresolved_symbol_t)); |
| 243 | + unresolved_sym->name = malloc(strlen(fixed_symbol) + 1); |
| 244 | + strcpy(unresolved_sym->name, fixed_symbol); |
| 245 | + unresolved_sym->column = state->column; |
| 246 | + unresolved_sym->line_number = *(int*)stack_peek(state->line_number_stack); |
| 247 | + unresolved_sym->line = malloc(strlen(state->line) + 1); |
| 248 | + strcpy(unresolved_sym->line, state->line); |
| 249 | + const char *file_name=stack_peek(state->file_name_stack); |
| 250 | + unresolved_sym->file_name = malloc(sizeof(file_name) + 1); |
| 251 | + strcpy(unresolved_sym->file_name, file_name); |
| 252 | + list_add(state->object->unresolved, unresolved_sym); |
| 253 | + } |
| 254 | + |
230 | 255 | scas_log(L_DEBUG, "Postponing evaluation of '%s' to linker", argv[i]); |
231 | 256 | late_immediate_t *late_imm = malloc(sizeof(late_immediate_t)); |
232 | 257 | late_imm->address = state->current_area->data_length; |
@@ -408,7 +433,26 @@ int handle_dw(struct assembler_state *state, char **argv, int argc) { |
408 | 433 | } |
409 | 434 |
|
410 | 435 | if (error == EXPRESSION_BAD_SYMBOL) { |
411 | | - /* TODO: Throw error if using explicit import */ |
| 436 | + if (scas_runtime.options.explicit_import) { |
| 437 | + tokenized_expression_t *changed_expression = malloc(sizeof(tokenized_expression_t)); |
| 438 | + memcpy(changed_expression, expression, sizeof(tokenized_expression_t)); |
| 439 | + int ignored_error; |
| 440 | + char *fixed_symbol; |
| 441 | + transform_local_labels(changed_expression, state->last_global_label); |
| 442 | + evaluate_expression(expression, state->equates, &ignored_error, &fixed_symbol); |
| 443 | + unresolved_symbol_t *unresolved_sym = malloc(sizeof(unresolved_symbol_t)); |
| 444 | + unresolved_sym->name = malloc(strlen(fixed_symbol) + 1); |
| 445 | + strcpy(unresolved_sym->name,fixed_symbol); |
| 446 | + unresolved_sym->column = state->column; |
| 447 | + unresolved_sym->line_number = *(int*)stack_peek(state->line_number_stack); |
| 448 | + unresolved_sym->line = malloc(strlen(state->line) + 1); |
| 449 | + strcpy(unresolved_sym->line, state->line); |
| 450 | + const char *file_name = stack_peek(state->file_name_stack); |
| 451 | + unresolved_sym->file_name = malloc(sizeof(file_name) + 1); |
| 452 | + strcpy(unresolved_sym->file_name, file_name); |
| 453 | + list_add(state->object->unresolved, unresolved_sym); |
| 454 | + } |
| 455 | + |
412 | 456 | scas_log(L_DEBUG, "Postponing evaluation of '%s' to linker", argv[i]); |
413 | 457 | late_immediate_t *late_imm = malloc(sizeof(late_immediate_t)); |
414 | 458 | late_imm->address = state->current_area->data_length; |
@@ -750,6 +794,22 @@ int handle_export(struct assembler_state *state, char **argv, int argc) { |
750 | 794 | return 1; |
751 | 795 | } |
752 | 796 |
|
| 797 | +int handle_import(struct assembler_state *state, char **argv, int argc) { |
| 798 | + if (!scas_runtime.options.explicit_import) { |
| 799 | + WARN(WARNING_NO_EFFECT, state->column, |
| 800 | + ".import", "explicit_import is not enabled"); |
| 801 | + } |
| 802 | + else { |
| 803 | + for (int i = 0; i < argc; ++i) { |
| 804 | + scas_log(L_DEBUG, "Importing '%s'",argv[i]); |
| 805 | + char *imported = malloc(strlen(argv[i]) + 1); |
| 806 | + strcpy(imported, argv[i]); |
| 807 | + list_add(state->object->imports, imported); |
| 808 | + } |
| 809 | + } |
| 810 | + return 1; |
| 811 | +} |
| 812 | + |
753 | 813 | int handle_if(struct assembler_state *state, char **argv, int argc) { |
754 | 814 | if (state->if_stack->length != 0 && !*(int *)stack_peek(state->if_stack)) { |
755 | 815 | /* Push up another falsy if if we're already in a falsy if */ |
@@ -971,7 +1031,10 @@ int handle_list(struct assembler_state *state, char **argv, int argc) { |
971 | 1031 | int handle_map(struct assembler_state *state, char **argv, int argc) { |
972 | 1032 | // .map filename, lineno, code |
973 | 1033 | free(((source_map_t *)stack_peek(state->source_map_stack))->file_name); |
974 | | - ((source_map_t*)stack_peek(state->source_map_stack))->file_name = strdup(argv[0]); |
| 1034 | + ((source_map_t*)stack_peek(state->source_map_stack))->file_name = |
| 1035 | + malloc(strlen(argv[0]) + 1); |
| 1036 | + strcpy(((source_map_t*)stack_peek(state->source_map_stack))->file_name, |
| 1037 | + argv[0]); |
975 | 1038 | add_source_map((source_map_t *)stack_peek(state->source_map_stack), |
976 | 1039 | atoi(argv[1]), argv[2], state->PC, 1); // TODO: figure out actual length |
977 | 1040 | return 1; |
@@ -1123,7 +1186,7 @@ struct directive directives[] = { |
1123 | 1186 | { "if", handle_if, 0 }, |
1124 | 1187 | { "ifdef", handle_ifdef, 0 }, |
1125 | 1188 | { "ifndef", handle_ifndef, 0 }, |
1126 | | - { "import", handle_nop, DELIM_COMMAS | DELIM_WHITESPACE }, /* TODO */ |
| 1189 | + { "import", handle_import, DELIM_COMMAS | DELIM_WHITESPACE }, |
1127 | 1190 | { "incbin", handle_incbin, DELIM_COMMAS | DELIM_WHITESPACE }, |
1128 | 1191 | { "include", handle_include, DELIM_COMMAS | DELIM_WHITESPACE }, |
1129 | 1192 | { "lclequ", handle_equ, DELIM_COMMAS | DELIM_WHITESPACE }, |
|
0 commit comments