summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-01-09 22:33:33 -0500
committerpommicket <pommicket@gmail.com>2022-01-09 22:33:47 -0500
commit6e75b24b7c4737a3a771b38e0048157ab843921f (patch)
treea068494ac9bf2861f7e20c960c65f83cc79fee52
parent29ea5195fa34edb6e0acd70b202f43befe19c1f2 (diff)
#line, #pragma
-rw-r--r--05/constants.b6
-rw-r--r--05/main.b17
-rw-r--r--05/main.c9
-rw-r--r--05/preprocess.b63
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
diff --git a/05/main.b b/05/main.b
index 67634d1..c941d17 100644
--- a/05/main.b
+++ b/05/main.b
@@ -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
diff --git a/05/main.c b/05/main.c
index f332a64..2261649 100644
--- a/05/main.c
+++ b/05/main.c
@@ -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