start fmacro replacement

This commit is contained in:
pommicket 2022-01-09 12:31:35 -05:00
parent 807a6aacf9
commit f08cdc8e22
3 changed files with 65 additions and 33 deletions

View file

@ -45,7 +45,8 @@ function main
local output_filename local output_filename
local pptokens local pptokens
dat_banned_macros = 255 dat_banned_objmacros = 255
dat_banned_fmacros = 255
object_macros = malloc(4000000) object_macros = malloc(4000000)
function_macros = malloc(4000000) function_macros = malloc(4000000)

View file

@ -1,10 +1,5 @@
#define B A C A B A #define TEST(x) hello
#define A helo what #define TEST heloo 2
#define C how is it going TEST(55)
main(void) {
#define D E }
#define E D
B !
D
E

View file

@ -611,59 +611,95 @@ function look_up_function_macro
function macro_replacement function macro_replacement
argument p_in argument p_in
argument p_out argument p_out
global 2000 dat_banned_macros ; 255-terminated array of strings (initialized in main) ; "banned" macros prevent #define x x from being a problem
local old_banned_macros_end ; C89 § 3.8.3.4
local banned_macros ; "If the name of the macro being replaced is found during this scan
; of the replacement list, it is not replaced. Further, if any nested
; replacements encounter the name of the macro being replaced, it is not replaced."
global 2000 dat_banned_objmacros ; 255-terminated array of strings (initialized in main)
local old_banned_objmacros_end
global 2000 dat_banned_fmacros
local old_banned_fmacros_end
local banned_fmacros
local banned_objmacros
local b local b
local p local p
local q
local replacement local replacement
local in local in
local out local out
in = *8p_in in = *8p_in
out = *8p_out out = *8p_out
banned_objmacros = &dat_banned_objmacros
banned_fmacros = &dat_banned_fmacros
old_banned_objmacros_end = memchr(banned_objmacros, 255)
old_banned_fmacros_end = memchr(banned_fmacros, 255)
; "banned" macros prevent #define x x from being a problem p = in
; C89 § 3.8.3.4 pptoken_skip(&p)
; "If the name of the macro being replaced is found during this scan if *1p == '( goto fmacro_replacement
; of the replacement list, it is not replaced. Further, if any nested
; replacements encounter the name of the macro being replaced, it is not replaced."
banned_macros = &dat_banned_macros p = banned_objmacros
p = banned_macros
old_banned_macros_end = memchr(banned_macros, 255)
:check_banned_macros_loop :check_banned_objmacros_loop
if *1p == 255 goto check_banned_macros_loop_end if *1p == 255 goto check_banned_objmacros_loop_end
b = str_equals(in, p) b = str_equals(in, p)
if b != 0 goto no_replacement if b != 0 goto done_replacement
p = memchr(p, 0) p = memchr(p, 0)
p += 1 p += 1
goto check_banned_macros_loop goto check_banned_objmacros_loop
:check_banned_macros_loop_end :check_banned_objmacros_loop_end
p = strcpy(old_banned_macros_end, in) ; add this to list of banned macros
p = strcpy(old_banned_objmacros_end, in)
p += 1 p += 1
*1p = 255 *1p = 255
replacement = look_up_object_macro(in) replacement = look_up_object_macro(in)
if replacement == 0 goto no_replacement if replacement == 0 goto no_replacement
p = replacement p = replacement
pptoken_skip(&in) pptoken_skip(&in)
:objreplace_loop :objreplace_loop
if *1p == 255 goto objreplace_loop_end if *1p == 255 goto done_replacement
macro_replacement(&p, &out) macro_replacement(&p, &out)
goto objreplace_loop goto objreplace_loop
:fmacro_replacement
p = banned_fmacros
:check_banned_fmacros_loop
if *1p == 255 goto check_banned_fmacros_loop_end
b = str_equals(in, p)
if b != 0 goto no_replacement
p = memchr(p, 0)
p += 1
goto check_banned_fmacros_loop
:check_banned_fmacros_loop_end
; add this to list of banned macros
p = strcpy(old_banned_fmacros_end, in)
p += 1
*1p = 255
replacement = look_up_function_macro(in)
if replacement == 0 goto no_replacement
p = replacement
:freplace_loop
if *1p == 255 goto done_replacement
byte 0xcc
:freplace_loop_end
:no_replacement :no_replacement
pptoken_copy_and_advance(&in, &out) pptoken_copy_and_advance(&in, &out)
; (fallthrough) ; (fallthrough)
:objreplace_loop_end :done_replacement
*8p_in = in *8p_in = in
*8p_out = out *8p_out = out
; unban this macro ; unban any macros we just banned
*1old_banned_macros_end = 255 *1old_banned_objmacros_end = 255
*1old_banned_fmacros_end = 255
return return
function print_object_macros function print_object_macros
print_macros(object_macros) print_macros(object_macros)
return return