diff options
author | pommicket <pommicket@gmail.com> | 2022-02-07 15:53:44 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-02-07 15:53:44 -0500 |
commit | ef1100ad084b13f9fda0f2b487fc3a764aab8ec4 (patch) | |
tree | d8be02886b41f75851434787d652309778bddfd9 /05 | |
parent | 4b6fe5266a60951a7acde77031541c7b4670c503 (diff) |
defined in #if (forgot about that earlier)
Diffstat (limited to '05')
-rw-r--r-- | 05/constants.b | 3 | ||||
-rw-r--r-- | 05/main.c | 89 | ||||
-rw-r--r-- | 05/preprocess.b | 67 |
3 files changed, 68 insertions, 91 deletions
diff --git a/05/constants.b b/05/constants.b index f8e15ba..7e68bb2 100644 --- a/05/constants.b +++ b/05/constants.b @@ -771,3 +771,6 @@ :str_case string case byte 0 +:str_defined + string defined + byte 0 @@ -1,91 +1,2 @@ -/* static int g; */ - -int G; - -int f(int a, float x[], double y, ...) { -} - -float * g(void); - int main() { - int b[] = {1,2,3}; - int a = f(G, 17, b, 36, 55.0, 22.3f); - float *f = g(17.2, b); - int *y; - y = b; -} - -float *g () { - float j; - return &j; } -/* int f(int x, int y[3]) { */ -/* int z = 17 +x; */ -/* int g[]={1,2,3,4,5}; */ -/* int h; */ -/* funciton(h,g,z); */ -/* return *(g + x + z); */ -/* } */ - -/* typedef int AA[sizeof x]; */ - - -/* typedef struct { */ -/* int i[41]; */ -/* long double d; */ -/* } (*x___)(void); */ -/* */ -/* typedef enum X { */ -/* R,S,T */ -/* } *Foo[sizeof(unsigned long)]; */ -/* typedef int A___[T]; */ -/* */ -/* typedef struct A { */ -/* int x, y; */ -/* long double c; */ -/* unsigned long d; */ -/* char e[3]; */ -/* long f; */ -/* } A; */ -/* */ -/* typedef union B{ */ -/* int x; */ -/* struct { */ -/* int y; */ -/* struct {long z; } c; */ -/* } c; */ -/* }B; */ -/* */ -/* typedef int QQQ[sizeof(A)+sizeof"hello"]; */ -/* typedef int RRR[sizeof(struct B)]; */ -/* */ -/* static unsigned int x={55}; */ -/* static char *s = "hello"; */ -/* static char *t = "goodbye"; */ -/* static char u[8] = "hellothe"; */ -/* static char v[100] = "re my"; */ -/* static char w[] = "friendly"; */ -/* static char x_[] = "hi"; */ -/* typedef int A_[sizeof x_ + sizeof u]; */ -/* */ -/* static int a[5] = {1,2,3}; */ -/* static char b[6][7] = {{'a'},{'b'},{'c'},{'d'},{'e'}}; */ -/* static char __b[][7] = {{'a'},"hello",'r'}; */ -/* static int _u = sizeof __b; */ -/* */ -/* struct { */ -/* int a; */ -/* long b; */ -/* } x1[] = {0x1234567890, 1ul<<60|1ul<<3, 77}; */ -/* int y1 = 0x12345678; */ -/* */ -/* struct { */ -/* int x[2], y; */ -/* } test[] = {3, 5,0x1234,0x4321}; */ -/* typedef int Blah[sizeof((B *)0)->c.y]; */ -/* unsigned marker = 0xdeadbeef; */ -/* */ -/* typedef int (*FUNCTION)(void); */ -/* typedef int AAAA[sizeof*****((FUNCTION)0)]; */ - -/* typedef int X[sizeof(int)+4]; */ diff --git a/05/preprocess.b b/05/preprocess.b index 5b4e6d7..aea390d 100644 --- a/05/preprocess.b +++ b/05/preprocess.b @@ -470,6 +470,8 @@ function translation_phase_4 local in local out local p + local q + local n local c local b local macro_name @@ -836,7 +838,9 @@ function translation_phase_4 :pp_directive_if local if_pptokens local if_tokens + local if_tokens_end local if_expr + local def_name pptoken_skip(&in) pptoken_skip_spaces(&in) @@ -846,7 +850,7 @@ function translation_phase_4 p = if_pptokens macro_replacement_to_terminator(filename, line_number, &in, &p, 10) - tokenize(if_pptokens, if_tokens, filename, line_number) + if_tokens_end = tokenize(if_pptokens, if_tokens, filename, line_number) ; replace all identifiers with 0 p = if_tokens :pp_if_idents0_loop @@ -855,19 +859,78 @@ function translation_phase_4 p += 16 goto pp_if_idents0_loop :pp_if_replace_ident + p += 8 + b = str_equals(*8p, .str_defined) + p -= 8 + if b != 0 goto pp_replace_defined *1p = TOKEN_CONSTANT_INT p += 8 *8p = 0 p += 8 goto pp_if_idents0_loop + :pp_replace_defined + ; handle, e.g. #if defined(SOMETHING) + + ; @NONSTANDARD?? it seems unclear in the standard whether this is legal: + ; #define X defined + ; GCC and clang both accept it without warnings + + p += 16 + if *1p != SYMBOL_LPAREN goto pp_defined_nolparen + p += 16 + if *1p != TOKEN_IDENTIFIER goto pp_bad_defined + p += 8 + def_name = *8p + p += 8 + if *1p != SYMBOL_RPAREN goto pp_bad_defined + q = p + 16 + p -= 32 + n = if_tokens_end - q + memcpy(p, q, n) ; shift everything over because 0 is less tokens than defined(X) + p -= 16 + goto pp_defined_lparen_cont + :pp_defined_nolparen + if *1p != TOKEN_IDENTIFIER goto pp_bad_defined + p += 8 + def_name = *8p + p -= 8 + q = p + 16 + n = if_tokens_end - q + memcpy(p, q, n) ; shift everything over because 0 is less tokens than defined X + p -= 16 + :pp_defined_lparen_cont + + *1p = TOKEN_CONSTANT_INT + p += 8 + b = look_up_object_macro(def_name) + if b != 0 goto pp_defined_1 + b = look_up_function_macro(def_name) + if b != 0 goto pp_defined_1 + ; not defined + *8p = 0 + goto pp_defined_cont + :pp_defined_1 + ; defined + *8p = 1 + :pp_defined_cont + p += 8 + goto pp_if_idents0_loop + :pp_if_idents0_done + ;print_tokens(if_tokens, p) parse_expression(if_tokens, p, if_expr) - evaluate_constant_expression(if_expr, &b) + ;print_expression(if_expr) + evaluate_constant_expression(p, if_expr, &b) if b == 0 goto pp_directive_if0 goto pp_if_done :pp_directive_if0 preprocessor_skip_if(filename, &line_number, &in, &out) goto pp_if_done + :pp_bad_defined + token_error(p, .str_pp_bad_defined) + :str_pp_bad_defined + string Bad use of defined() in macro. + byte 0 :pp_if_done free(if_pptokens) goto process_pptoken |