object-like macro replacement working?
This commit is contained in:
parent
4d5a5d9d97
commit
807a6aacf9
3 changed files with 76 additions and 27 deletions
|
@ -45,6 +45,8 @@ function main
|
||||||
local output_filename
|
local output_filename
|
||||||
local pptokens
|
local pptokens
|
||||||
|
|
||||||
|
dat_banned_macros = 255
|
||||||
|
|
||||||
object_macros = malloc(4000000)
|
object_macros = malloc(4000000)
|
||||||
function_macros = malloc(4000000)
|
function_macros = malloc(4000000)
|
||||||
|
|
||||||
|
@ -59,7 +61,7 @@ function main
|
||||||
print_pptokens(pptokens)
|
print_pptokens(pptokens)
|
||||||
print_separator()
|
print_separator()
|
||||||
pptokens = translation_phase_4(input_filename, pptokens)
|
pptokens = translation_phase_4(input_filename, pptokens)
|
||||||
;print_pptokens(pptokens)
|
print_pptokens(pptokens)
|
||||||
print_object_macros()
|
print_object_macros()
|
||||||
print_function_macros()
|
print_function_macros()
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
30
05/main.c
30
05/main.c
|
@ -1,22 +1,10 @@
|
||||||
-#include <stdio.h>
|
#define B A C A B A
|
||||||
|
#define A helo what
|
||||||
|
#define C how is it going
|
||||||
|
|
||||||
int test(int, double, ...);\
|
#define D E
|
||||||
/* here is a nice
|
#define E D
|
||||||
comment it is
|
B !
|
||||||
here
|
|
||||||
*/
|
D
|
||||||
#
|
E
|
||||||
#define A(_Hello, there, everyone ) 33 + _Hello - everyone * there
|
|
||||||
#define B(x, y, z) 58
|
|
||||||
#define C(hello) hello * hello + hello / hello
|
|
||||||
#define A 22
|
|
||||||
#define C 33
|
|
||||||
#define _Hello_there5 -76 + sqrt(A)
|
|
||||||
int main(void) {
|
|
||||||
printf("\"Hello, world!%c\n\"", '\'');
|
|
||||||
_X55 = Y4_C_;
|
|
||||||
a.b = c;
|
|
||||||
5 + (.3e+5+6) & 0xff | 93 -~5;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#define _Hello_there 18
|
|
||||||
|
|
|
@ -431,13 +431,18 @@ function translation_phase_4
|
||||||
if c == 10 goto phase4_next_line
|
if c == 10 goto phase4_next_line
|
||||||
b = isdigit(c)
|
b = isdigit(c)
|
||||||
if b != 0 goto phase4_next_pptoken
|
if b != 0 goto phase4_next_pptoken
|
||||||
|
b = isalnum_or_underscore(c)
|
||||||
|
if b != 0 goto phase4_try_replacements
|
||||||
|
; (fallthrough)
|
||||||
:phase4_next_pptoken
|
:phase4_next_pptoken
|
||||||
pptoken_copy_and_advance(&in, &out)
|
pptoken_copy_and_advance(&in, &out)
|
||||||
goto process_pptoken
|
goto process_pptoken
|
||||||
:phase4_next_line
|
:phase4_next_line
|
||||||
pptoken_copy_and_advance(&in, &out)
|
pptoken_copy_and_advance(&in, &out)
|
||||||
goto phase4_line
|
goto phase4_line
|
||||||
|
:phase4_try_replacements
|
||||||
|
macro_replacement(&in, &out)
|
||||||
|
goto phase4_line
|
||||||
:pp_directive
|
:pp_directive
|
||||||
pptoken_skip(&in) ; skip #
|
pptoken_skip(&in) ; skip #
|
||||||
pptoken_skip_spaces(&in)
|
pptoken_skip_spaces(&in)
|
||||||
|
@ -477,8 +482,7 @@ function translation_phase_4
|
||||||
*1p = 255 ; replace newline with special "macro end" character
|
*1p = 255 ; replace newline with special "macro end" character
|
||||||
p += 1
|
p += 1
|
||||||
object_macros_size = p - object_macros
|
object_macros_size = p - object_macros
|
||||||
in += 2 ; skip newline and following null character
|
goto phase4_next_line
|
||||||
goto phase4_line
|
|
||||||
:function_macro_definition
|
:function_macro_definition
|
||||||
; a function-like macro, e.g. #define JOIN(a,b) a##b
|
; a function-like macro, e.g. #define JOIN(a,b) a##b
|
||||||
local param_names
|
local param_names
|
||||||
|
@ -546,8 +550,7 @@ function translation_phase_4
|
||||||
p += 1
|
p += 1
|
||||||
function_macros_size = p - function_macros
|
function_macros_size = p - function_macros
|
||||||
free(param_names)
|
free(param_names)
|
||||||
in += 2 ; skip newline and following null character
|
goto phase4_next_line
|
||||||
goto phase4_line
|
|
||||||
:str_directive_error
|
:str_directive_error
|
||||||
string : #error
|
string : #error
|
||||||
byte 10
|
byte 10
|
||||||
|
@ -605,6 +608,62 @@ function look_up_function_macro
|
||||||
argument name
|
argument name
|
||||||
return look_up_macro(function_macros, name)
|
return look_up_macro(function_macros, name)
|
||||||
|
|
||||||
|
function macro_replacement
|
||||||
|
argument p_in
|
||||||
|
argument p_out
|
||||||
|
global 2000 dat_banned_macros ; 255-terminated array of strings (initialized in main)
|
||||||
|
local old_banned_macros_end
|
||||||
|
local banned_macros
|
||||||
|
local b
|
||||||
|
local p
|
||||||
|
local replacement
|
||||||
|
local in
|
||||||
|
local out
|
||||||
|
|
||||||
|
in = *8p_in
|
||||||
|
out = *8p_out
|
||||||
|
|
||||||
|
; "banned" macros prevent #define x x from being a problem
|
||||||
|
; C89 § 3.8.3.4
|
||||||
|
; "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."
|
||||||
|
|
||||||
|
banned_macros = &dat_banned_macros
|
||||||
|
p = banned_macros
|
||||||
|
|
||||||
|
old_banned_macros_end = memchr(banned_macros, 255)
|
||||||
|
|
||||||
|
:check_banned_macros_loop
|
||||||
|
if *1p == 255 goto check_banned_macros_loop_end
|
||||||
|
b = str_equals(in, p)
|
||||||
|
if b != 0 goto no_replacement
|
||||||
|
p = memchr(p, 0)
|
||||||
|
p += 1
|
||||||
|
goto check_banned_macros_loop
|
||||||
|
:check_banned_macros_loop_end
|
||||||
|
|
||||||
|
p = strcpy(old_banned_macros_end, in)
|
||||||
|
p += 1
|
||||||
|
*1p = 255
|
||||||
|
replacement = look_up_object_macro(in)
|
||||||
|
if replacement == 0 goto no_replacement
|
||||||
|
p = replacement
|
||||||
|
pptoken_skip(&in)
|
||||||
|
:objreplace_loop
|
||||||
|
if *1p == 255 goto objreplace_loop_end
|
||||||
|
macro_replacement(&p, &out)
|
||||||
|
goto objreplace_loop
|
||||||
|
:no_replacement
|
||||||
|
pptoken_copy_and_advance(&in, &out)
|
||||||
|
; (fallthrough)
|
||||||
|
:objreplace_loop_end
|
||||||
|
*8p_in = in
|
||||||
|
*8p_out = out
|
||||||
|
; unban this macro
|
||||||
|
*1old_banned_macros_end = 255
|
||||||
|
return
|
||||||
|
|
||||||
function print_object_macros
|
function print_object_macros
|
||||||
print_macros(object_macros)
|
print_macros(object_macros)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue