summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-01-21 14:41:08 -0500
committerpommicket <pommicket@gmail.com>2022-01-21 14:41:08 -0500
commit3641ac98dc7747b7c9ebe2b7ea4007ecab033d5a (patch)
tree21442c9f989bb4945543f1667b3278168aa3cdaf
parent7ae8a22a94e5c89efe0e7d9182329f65b6bdac02 (diff)
function types
-rw-r--r--05/main.c2
-rw-r--r--05/parse.b75
2 files changed, 58 insertions, 19 deletions
diff --git a/05/main.c b/05/main.c
index 68eb738..36f5511 100644
--- a/05/main.c
+++ b/05/main.c
@@ -3,4 +3,4 @@
long double d;
} (*x)(void);
*/
-typedef long int unsigned Foo;
+typedef long int unsigned (*Foo(int *,int,int,unsigned,void (*)(int)))(int x);
diff --git a/05/parse.b b/05/parse.b
index ac2869c..7ca80f8 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -13,7 +13,7 @@ function parse_tokens
:parse_typedef
token += 16
- type = parse_type_and_ident(&token, &ident)
+ type = parse_type(&token, &ident)
puts(ident)
putc(10)
print_type(type)
@@ -55,8 +55,22 @@ function token_skip_to_matching_rbrace
; parse things like `int x` or `int f(void, int, char *)`
; advances *p_token and sets *p_ident to a pointer to the identifier (or 0 if this is just a type)
-; and returns type ID
-function parse_type_and_ident
+; returns type ID
+function parse_type
+ argument p_token
+ argument p_ident
+ local type
+ local p
+ local n
+ type = types_bytes_used
+ p = types + type
+ n = parse_type_to(p_token, p_ident, p)
+ types_bytes_used = n - types
+ return type
+
+; like parse_type, but outputs to out.
+; returns new position of out, after type gets put there
+function parse_type_to
; split types into prefix (P) and suffix (S)
; struct Thing (*things[5])(void);
; PPPPPPPPPPPPPPP SSSSSSSSSS
@@ -64,20 +78,21 @@ function parse_type_and_ident
argument p_token
argument p_ident
- local typeid
+ argument out ; pointer to type
local token
local c
local p
+ local n
local base_type_end
local depth
local prefix
local prefix_end
local suffix
local suffix_end
- local out
token = *8p_token
prefix = token
+ *8p_ident = 0
c = *1token
if c == KEYWORD_STRUCT goto skip_struct_union_enum
@@ -181,9 +196,6 @@ function parse_type_and_ident
TYPEDEBUG putc(':)
TYPEDEBUG putc(32)
TYPEDEBUG print_tokens(suffix, suffix_end)
-
- typeid = types_bytes_used
- out = types + typeid
; main loop for parsing types
:parse_type_loop
@@ -196,13 +208,35 @@ function parse_type_and_ident
:parse_pointer_type
- byte 0xcc ; @TODO
+ *1out = TYPE_POINTER
+ out += 1
+ prefix_end = p
+ goto parse_type_loop
:parse_array_type
byte 0xcc ; @TODO
:parse_function_type
- byte 0xcc ; @TODO
+ p = suffix + 16
+ local RRR
+ RRR = out
+ *1out = TYPE_FUNCTION
+ out += 1
+ :function_type_loop
+ if *1p == SYMBOL_RPAREN goto function_type_loop_end ; only needed for 1st iteration
+ out = parse_type_to(&p, &c, out)
+ if *1p == SYMBOL_RPAREN goto function_type_loop_end
+ if *1p != SYMBOL_COMMA goto bad_type
+ p += 16
+ goto function_type_loop
+ :function_type_loop_end
+ *1out = 0
+ out += 1
+ suffix = p + 16
+ goto parse_type_loop
:parse_type_remove_parentheses
- byte 0xcc ; @TODO
+ if *1p != SYMBOL_LPAREN goto bad_type
+ prefix_end = p
+ suffix += 16
+ goto parse_type_loop
:parse_base_type
if *1prefix == TOKEN_IDENTIFIER goto base_type_typedef
if *1prefix == KEYWORD_STRUCT goto base_type_struct
@@ -311,8 +345,8 @@ function parse_type_and_ident
goto base_type_done
:base_type_done
- types_bytes_used = out - types
- return typeid
+ *8p_token = suffix_end
+ return out
:base_type_struct
byte 0xcc ; @TODO
:base_type_union
@@ -330,7 +364,8 @@ function parse_type_and_ident
:base_type_typedef
p = prefix + 8
c = ident_list_lookup(typedefs, *8p)
- out += type_copy(out, c)
+ n = type_length(c)
+ out = memcpy(out, c, n)
goto base_type_done
:skip_struct_union_enum
@@ -371,7 +406,7 @@ function type_length
:type_length_not_array
if *1p == TYPE_STRUCT goto return_5
if *1p == TYPE_UNION goto return_5
- if *1p == TYPE_FUNCTION goto type_length_not_function
+ if *1p != TYPE_FUNCTION goto type_length_not_function
local start
start = type
type += 1
@@ -379,9 +414,9 @@ function type_length
p = types + type
if *1p == 0 goto type_length_function_loop_end
type += type_length(type)
+ goto type_length_function_loop
:type_length_function_loop_end
type += 1
- ; return type
type += type_length(type)
return type - start
:type_length_not_function
@@ -394,7 +429,7 @@ function type_length
; returns length of type
-function type_copy
+function type_copy_ids
argument dest
argument src
local n
@@ -413,7 +448,7 @@ function type_create_pointer
*1p = TYPE_POINTER
types_bytes_used += 1
p = id + 1
- types_bytes_used += type_copy(p, type)
+ types_bytes_used += type_copy_ids(p, type)
return id
function parse_expression
@@ -1382,11 +1417,14 @@ function print_type
:print_type_function
type += 1
putc(40)
+ putc(40)
:print_type_function_loop
c = types + type
if *1c == 0 goto print_type_function_loop_end
print_type(type)
putc(44)
+ type += type_length(type)
+ goto print_type_function_loop
:print_type_function_loop_end
type += 1 ; 0 terminator
putc(41)
@@ -1395,4 +1433,5 @@ function print_type
putc('>)
putc(32)
print_type(type)
+ putc(41)
return