summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/constants.b3
-rw-r--r--05/main.c89
-rw-r--r--05/preprocess.b67
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
diff --git a/05/main.c b/05/main.c
index 701a97f..b2f9976 100644
--- a/05/main.c
+++ b/05/main.c
@@ -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