summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/main.c3
-rw-r--r--05/parse.b62
2 files changed, 55 insertions, 10 deletions
diff --git a/05/main.c b/05/main.c
index 2e1c1d5..b23d08f 100644
--- a/05/main.c
+++ b/05/main.c
@@ -3,5 +3,4 @@
long double d;
} (*x)(void);
*/
-typedef int *Foo[3+342<<5];
-typedef int A, *B[10];
+typedef int *Foo[sizeof(unsigned short int)];
diff --git a/05/parse.b b/05/parse.b
index 5b47bb8..be59e6b 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -51,7 +51,6 @@ function parse_tokens
base_type_end = type_get_base_end(base_type)
token = base_type_end
- putc('*)
:typedef_loop
prefix = token
@@ -60,7 +59,7 @@ function parse_tokens
ident = prefix_end + 8
ident = *8ident
suffix = prefix_end + 16
- suffix_end = type_get_suffix_end(suffix)
+ suffix_end = type_get_suffix_end(prefix)
putc('B)
putc(':)
@@ -358,12 +357,33 @@ function parse_type_declarators
string Very large or negative array size.
byte 0
:parse_function_type
+ local param_base_type
+ local param_prefix
+ local param_prefix_end
+ local param_suffix
+ local param_suffix_end
+
p = suffix + 16
out = types + types_bytes_used
*1out = TYPE_FUNCTION
types_bytes_used += 1
:function_type_loop
- byte 0xcc ; @TODO
+ param_base_type = p
+ param_prefix = type_get_base_end(param_base_type)
+ param_prefix_end = type_get_prefix_end(param_prefix)
+ param_suffix = param_prefix_end
+ if *1param_suffix != TOKEN_IDENTIFIER goto functype_no_ident
+ param_suffix += 16
+ :functype_no_ident
+ param_suffix_end = type_get_suffix_end(param_prefix)
+ parse_type_declarators(param_prefix, param_prefix_end, param_suffix, param_suffix_end)
+ parse_base_type(param_base_type)
+ p = param_suffix_end
+ if *1p == SYMBOL_RPAREN goto function_type_loop_end
+ if *1p != SYMBOL_COMMA goto parse_typedecls_bad_type
+ p += 16
+ goto function_type_loop
+ :function_type_loop_end
out = types + types_bytes_used
*1out = 0
types_bytes_used += 1
@@ -964,9 +984,23 @@ function parse_expression
byte 10
byte 0
:parse_cast
- p = best + 16
- a = parse_type(&p, &c)
- if c != 0 goto bad_cast ; e.g. (int x)5
+ local cast_base_type
+ local cast_prefix
+ local cast_suffix
+ local cast_suffix_end
+
+ cast_base_type = best + 16
+ cast_prefix = type_get_base_end(cast_base_type)
+ cast_suffix = type_get_prefix_end(cast_prefix)
+ cast_suffix_end = type_get_suffix_end(cast_prefix)
+
+ a = types_bytes_used
+
+ parse_type_declarators(cast_prefix, cast_suffix, cast_suffix, cast_suffix_end)
+ parse_base_type(cast_base_type)
+
+ p = cast_suffix_end
+
if *1p != SYMBOL_RPAREN goto bad_cast ; e.g. (int ,)5
out += 4
*4out = a
@@ -1013,6 +1047,11 @@ function parse_expression
byte 0
:parse_sizeof
+ local sizeof_base_type
+ local sizeof_prefix
+ local sizeof_suffix
+ local sizeof_suffix_end
+
*1out = EXPRESSION_CONSTANT_INT
out += 4
*1out = TYPE_UNSIGNED_LONG
@@ -1023,8 +1062,15 @@ function parse_expression
b = token_is_type(p)
if b == 0 goto parse_sizeof_expr
; it's a type, e.g. sizeof(int)
- a = parse_type(&p, &c)
- if c != 0 goto bad_expression ; e.g. sizeof(int x)
+ sizeof_base_type = p
+ sizeof_prefix = type_get_base_end(sizeof_base_type)
+ sizeof_suffix = type_get_prefix_end(sizeof_prefix)
+ sizeof_suffix_end = type_get_suffix_end(sizeof_prefix)
+ p = sizeof_suffix_end
+ a = types_bytes_used
+ parse_type_declarators(sizeof_prefix, sizeof_suffix, sizeof_suffix, sizeof_suffix_end)
+ parse_base_type(sizeof_base_type)
+ if *1p != SYMBOL_RPAREN goto bad_expression ; e.g. sizeof(int ,)
*8out = type_sizeof(a)
goto parse_sizeof_finish
:parse_sizeof_expr