diff options
Diffstat (limited to '05')
-rw-r--r-- | 05/constants.b | 6 | ||||
-rw-r--r-- | 05/main.b | 17 | ||||
-rw-r--r-- | 05/main.c | 9 | ||||
-rw-r--r-- | 05/preprocess.b | 63 |
4 files changed, 88 insertions, 7 deletions
diff --git a/05/constants.b b/05/constants.b index 850be2d..aaf5c06 100644 --- a/05/constants.b +++ b/05/constants.b @@ -118,6 +118,12 @@ :str_undef string undef byte 0 +:str_pragma + string pragma + byte 0 +:str_line + string line + byte 0 :str_include string include byte 0 @@ -26,12 +26,29 @@ function compile_error fputs(2, message) fputc(2, 10) exit(1) + +function compile_warning + argument file + argument line + argument message + fputs(2, file) + fputc(2, ':) + fputn(2, line) + fputs(2, .str_warning_prefix) + fputs(2, message) + fputc(2, 10) + return :str_error_prefix string : Error: byte 32 byte 0 +:str_warning_prefix + string : Warning: + byte 32 + byte 0 + #include util.b #include constants.b #include preprocess.b @@ -11,13 +11,10 @@ JOIN(X, X) STRINGIFY(X) - #define E 5 -#define D E -#define C D -#define B C -#define A B +#line 6 - int x = E; +#line 7 "some_file.c" +#pragma whatever main(void) { } diff --git a/05/preprocess.b b/05/preprocess.b index 93c7c63..76df9aa 100644 --- a/05/preprocess.b +++ b/05/preprocess.b @@ -452,6 +452,18 @@ function pptoken_skip_spaces *8p_in = in return +function pptoken_skip_to_newline + argument p_in + local in + in = *8p_in + :pptoken_skip_to_newline_loop + if *1in == 10 goto pptoken_skip_to_newline_end + pptoken_skip(&in) + goto pptoken_skip_to_newline_loop + :pptoken_skip_to_newline_end + *8p_in = in + return + ; phase 4: ; Preprocessing directives are executed and macro invocations are expanded. ; A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. @@ -506,6 +518,10 @@ function translation_phase_4 if b != 0 goto pp_directive_define b = str_equals(in, .str_undef) if b != 0 goto pp_directive_undef + b = str_equals(in, .str_pragma) + if b != 0 goto pp_directive_pragma + b = str_equals(in, .str_line) + if b != 0 goto pp_directive_line goto unrecognized_directive :pp_directive_error fputs(2, filename) @@ -513,6 +529,39 @@ function translation_phase_4 fputn(2, line_number) fputs(2, .str_directive_error) exit(1) + :pp_directive_line + ; at this stage, we just turn #line directives into a nicer format: + ; {$line_number filename} e.g. {$77 main.c} + local new_line_number + pptoken_skip(&in) + pptoken_skip_spaces(&in) + new_line_number = stoi(in) + new_line_number -= 1 ; #line directive applies to the following line + *1out = '$ + out += 1 + ; copy line number + p = itos(new_line_number) + out = strcpy(out, p) + *1out = 32 + out += 1 + pptoken_skip(&in) + pptoken_skip_spaces(&in) + if *1in == 10 goto ppdirective_line_no_filename + if *1in != '" goto bad_line_directive + ; copy filename + in += 1 + filename = out + out = memccpy(out, in, '") + *1out = 0 + out += 1 + goto ppdirective_line_cont + :ppdirective_line_no_filename + out = strcpy(out, filename) + out += 1 + :ppdirective_line_cont + pptoken_skip_to_newline(&in) + line_number = new_line_number + goto process_pptoken :pp_directive_undef pptoken_skip(&in) pptoken_skip_spaces(&in) @@ -622,7 +671,14 @@ function translation_phase_4 function_macros_size = p - function_macros free(param_names) goto phase4_next_line - + :pp_directive_pragma + ; we don't have any pragmas + compile_warning(filename, line_number, .str_unrecognized_pragma) + pptoken_skip_to_newline(&in) + goto process_pptoken + :str_unrecognized_pragma + string Unrecognized #pragma. + byte 0 :str_directive_error string : #error byte 10 @@ -654,6 +710,11 @@ function translation_phase_4 :str_bad_undef string Bad #undef. byte 0 + :bad_line_directive + compile_error(filename, line_number, .str_bad_line_directive) + :str_bad_line_directive + string Bad #line. + byte 0 ; returns a pointer to the replacement pptokens, or 0 if this macro is not defined function look_up_macro |