summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/idents.b38
-rw-r--r--05/main.b2
-rw-r--r--05/main.c2
-rw-r--r--05/parse.b96
4 files changed, 97 insertions, 41 deletions
diff --git a/05/idents.b b/05/idents.b
index 0deaf35..c4fff0f 100644
--- a/05/idents.b
+++ b/05/idents.b
@@ -7,6 +7,44 @@ function ident_list_create
*1list = 255
return list
+function ident_list_clear
+ argument list
+ *1list = 255
+ return
+
+function ident_list_free
+ argument list
+ free(list)
+ return
+
+function ident_list_len
+ argument list
+ local len
+ len = 0
+ :ilist_len_loop
+ if *1list == 255 goto ilist_len_ret
+ list = memchr(list, 0)
+ list += 9 ; skip null byte and value
+ len += 1
+ goto ilist_len_loop
+ :ilist_len_ret
+ return len
+
+function ident_list_value_at_index
+ argument list
+ argument idx
+ :ilist_vai_loop
+ if *1list == 255 goto return_0
+ list = memchr(list, 0)
+ list += 1
+ if idx <= 0 goto ilist_vai_ret
+ list += 8
+ idx -= 1
+ goto ilist_vai_loop
+ :ilist_vai_ret
+ return *8list
+
+
function ident_list_add
argument list
argument ident
diff --git a/05/main.b b/05/main.b
index 2200156..02597f6 100644
--- a/05/main.b
+++ b/05/main.b
@@ -38,6 +38,8 @@ global struct_names
; for unions, offset will always be 0.
global structures
global structures_bytes_used
+; ident list of type IDs
+global parse_type_result
#include util.b
#include idents.b
diff --git a/05/main.c b/05/main.c
index 4b2e9ba..a95bc08 100644
--- a/05/main.c
+++ b/05/main.c
@@ -3,4 +3,4 @@
long double d;
} (*x)(void);
*/
-typedef int Foo(struct Bar *);
+typedef int Foo;
diff --git a/05/parse.b b/05/parse.b
index 6f7392d..11ff4df 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -29,6 +29,7 @@ function parse_tokens
local token
local ident
local type
+ local p
token = tokens
:parse_tokens_loop
@@ -39,16 +40,27 @@ function parse_tokens
:parse_typedef
token += 16
- type = parse_type(&token, &ident)
- if ident == 0 goto typedef_no_ident
+ type = parse_type(&token)
+ if type != 0 goto typedef_no_ident
if *1token != SYMBOL_SEMICOLON goto typedef_no_semicolon
- puts(ident)
- putc(':)
- putc(32)
- print_type(type)
- putc(10)
- ident_list_add(typedefs, ident, type)
+ p = parse_type_result
+ :typedef_loop
+ if *1p == 255 goto typedef_loop_end
+ ident = p
+ p = memchr(p, 0)
+ p += 1
+ type = *8p
+ p += 8
+ puts(ident)
+ putc(':)
+ putc(32)
+ print_type(type)
+ putc(10)
+ ident_list_add(typedefs, ident, type)
+ goto typedef_loop
+ :typedef_loop_end
+
token += 16 ; skip semicolon
goto parse_tokens_loop
:typedef_no_ident
@@ -127,35 +139,17 @@ function token_skip_to_matching_rsquare
string Unmatched [
byte 0
-; ident list of type IDs
-global parse_types_result
-
; parse things like `int x` or `int f(void, int, char *)`
; advances *p_token
-; returns type ID, or 0, in which case you should look at parse_type_idents
+; returns type ID, or 0, in which case you should look at parse_type_result
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 base (B), prefix (P) and suffix (S)
; struct Thing (*things[5])(void), *something_else[3];
; BBBBBBBBBBBB PP SSSSSSSSSS P SSS
; Here, we call `struct Thing` the "base type".
argument p_token
- argument p_ident
- argument out ; pointer to type
+ local typeid
local token
local c
local p
@@ -166,10 +160,11 @@ function parse_type_to
local prefix_end
local suffix
local suffix_end
+ local ident
token = *8p_token
prefix = token
- *8p_ident = 0
+ ident_list_clear(parse_type_result)
c = *1token
if c == KEYWORD_STRUCT goto skip_struct_union_enum
@@ -185,15 +180,17 @@ function parse_type_to
if c == KEYWORD_INT goto skip_base_type_loop_cont ;e.g. unsigned int x;
if c == KEYWORD_LONG goto skip_base_type_loop_cont ;e.g. unsigned long x;
if c == KEYWORD_DOUBLE goto skip_base_type_loop_cont ;e.g. long double x;
- goto find_prefix_end
+ goto skip_base_type_loop_end
:skip_base_type_loop_cont
token += 16
goto skip_base_type_loop
- :find_prefix_end
- ; find end of prefix
+ :skip_base_type_loop_end
+
+ ; find end of 1st prefix
base_type_end = token
+ ident = 0
:find_prefix_end_loop
c = *1token
if c == TOKEN_IDENTIFIER goto found_prefix_end
@@ -218,7 +215,7 @@ function parse_type_to
if *1token != TOKEN_IDENTIFIER goto parse_type_no_ident
token += 8
- *8p_ident = *8token
+ ident = *8token
token += 8
:parse_type_no_ident
@@ -237,7 +234,7 @@ function parse_type_to
if c == SYMBOL_RPAREN goto suffix_end_decdepth
if c == SYMBOL_TIMES goto suffix_end_cont
if depth == 0 goto suffix_end_found
- if c == TOKEN_EOF goto to_bad_type
+ if c == TOKEN_EOF goto pt_bad_type
goto suffix_end_cont
:suffix_end_incdepth
@@ -274,24 +271,31 @@ function parse_type_to
TYPEDEBUG putc(32)
TYPEDEBUG print_tokens(suffix, suffix_end)
- out = parse_type_given_base_prefix_suffix(*8p_token, prefix, prefix_end, suffix, suffix_end, out)
+ typeid = types_bytes_used
+ p = types + typeid
+ p = parse_type_given_base_prefix_suffix(*8p_token, prefix, prefix_end, suffix, suffix_end, p)
+ if ident == 0 goto type_no_ident
+ ident_list_add(parse_type_result, typeid)
+ typeid = 0
+ :type_no_ident
*8p_token = suffix_end
- return out
+ types_bytes_used = p - types
+ return typeid
:skip_struct_union_enum
token += 16
if *1token != TOKEN_IDENTIFIER goto skip_sue_no_name
token += 16 ; struct *blah*
:skip_sue_no_name
- if *1token != SYMBOL_LBRACE goto find_prefix_end ; e.g. struct Something x[5];
+ if *1token != SYMBOL_LBRACE goto skip_base_type_loop_end ; e.g. struct Something x[5];
; okay we have something like
; struct {
; int x, y;
; } test;
token_skip_to_matching_rbrace(&token)
token += 16
- goto find_prefix_end
- :to_bad_type
+ goto skip_base_type_loop_end
+ :pt_bad_type
token_error(*8p_token, .str_bad_type)
:str_bad_type
string Bad type.
@@ -361,12 +365,22 @@ function parse_type_given_base_prefix_suffix
string Very large or negative array size.
byte 0
:parse_function_type
+ local prev_parse_type_result
+ prev_parse_type_result = parse_type_result
+ parse_type_result = ident_list_create(16000)
p = suffix + 16
*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)
+ n = parse_type(&p)
+ if n != 0 goto fparam_have_type
+ c = ident_list_len(parse_type_result)
+ if c != 1 goto bps_bad_type
+ n = ident_list_value_at_index(parse_type_result, 0)
+ :fparam_have_type
+ n += type_length(n)
+ out = types + n
if *1p == SYMBOL_RPAREN goto function_type_loop_end
if *1p != SYMBOL_COMMA goto bps_bad_type
p += 16
@@ -375,6 +389,8 @@ function parse_type_given_base_prefix_suffix
*1out = 0
out += 1
suffix = p + 16
+ ident_list_free(parse_type_result)
+ parse_type_result = prev_parse_type_result
goto parse_type_loop
:parse_type_remove_parentheses
if *1p != SYMBOL_LPAREN goto bps_bad_type