summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/preprocess.b34
-rw-r--r--05/util.b8
2 files changed, 33 insertions, 9 deletions
diff --git a/05/preprocess.b b/05/preprocess.b
index d46311f..0a60e35 100644
--- a/05/preprocess.b
+++ b/05/preprocess.b
@@ -61,6 +61,8 @@ function split_into_preprocessing_tokens
:backslashnewline_loop_end
*1out = 0
+ ; @NONSTANDARD: this is where trigraphs would go
+
; split file into preprocessing tokens, remove comments (phase 3)
; we're still doing the trick with newlines, this time for ones inside comments
; this is needed because the following is legal C:
@@ -693,7 +695,11 @@ function macro_replacement
if *1in == ') goto empty_fmacro_invocation
local arguments
+ local fmacro_out
+ local fmacro_out_start
arguments = malloc(4000)
+ fmacro_out_start = malloc(8000) ; direct fmacro output. this will need to be re-scanned for macros
+ fmacro_out = fmacro_out_start
; store the arguments (separated by 255-characters)
p = arguments
@@ -719,16 +725,28 @@ function macro_replacement
:freplace_loop
if *1p == 255 goto freplace_loop_end
if *1p < 32 goto fmacro_argument
- macro_replacement(filename, line_number, &p, &out)
+ if *1p == '# goto freplace_hash_operator
+ pptoken_copy_and_advance(&p, &fmacro_out)
goto freplace_loop
+ :freplace_hash_operator
+ ; don't output # / ## tokens
+ pptoken_skip(&p)
+ goto freplace_loop
:freplace_loop_end
+
+ fmacro_out = fmacro_out_start
+ :frescan_loop
+ if *1fmacro_out == 0 goto frescan_loop_end
+ macro_replacement(filename, line_number, &fmacro_out, &out)
+ goto frescan_loop
+ :frescan_loop_end
+
free(arguments)
+ free(fmacro_out_start)
goto done_replacement
:fmacro_argument
- ; @TODO: stringify (#), paste (##) operators
-
- ; write argument to *out
+ ; write argument to *fmacro_out
local arg_idx
arg_idx = *1p
q = arguments
@@ -741,11 +759,9 @@ function macro_replacement
goto fmacro_argfind_loop
:fmacro_arg_found
; q = argument
- :fmacro_argreplace_loop
- if *1q == 255 goto fmacro_argreplaced
- macro_replacement(filename, line_number, &q, &out)
- goto fmacro_argreplace_loop
- :fmacro_argreplaced
+
+ fmacro_out = memccpy(fmacro_out, q, 255)
+ *1fmacro_out = 0
p += 2 ; skip arg idx & null separator
goto freplace_loop
diff --git a/05/util.b b/05/util.b
index f8c520e..495e890 100644
--- a/05/util.b
+++ b/05/util.b
@@ -112,6 +112,14 @@ function memccpy_advance
*8p_dest = dest
return
+; copy from src to dest until terminator is reached, returning pointer to terminator in dest.
+function memccpy
+ argument dest
+ argument src
+ argument terminator
+ memccpy_advance(&dest, &src, terminator)
+ return dest
+
; just like C
function memcpy
argument dest