summaryrefslogtreecommitdiff
path: root/05/parse.b
diff options
context:
space:
mode:
Diffstat (limited to '05/parse.b')
-rw-r--r--05/parse.b47
1 files changed, 39 insertions, 8 deletions
diff --git a/05/parse.b b/05/parse.b
index ad14ac2..1078809 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -164,6 +164,7 @@ function parse_tokens
byte 0
:parse_function_definition
p = types + type
+ ; @NOTE: remember to turn array members into pointers
if *1p != TYPE_FUNCTION goto lbrace_after_declaration
die(.str_fdNI) ; @TODO
:str_fdNI
@@ -257,6 +258,7 @@ function parse_constant_initializer
local a
local b
local c
+ local len
local p
local expr
local value
@@ -366,7 +368,6 @@ function parse_constant_initializer
:array_init_no_lbrace
addr0 = rwdata_end_addr
- local len
len = types + type
len += 1 ; skip TYPE_ARRAY
len = *8len
@@ -412,6 +413,8 @@ function parse_constant_initializer
string Bad array initializer.
byte 0
:parse_struct_initializer
+ addr0 = rwdata_end_addr
+
if *1token != SYMBOL_LBRACE goto struct_init_no_lbrace ; only happens when recursing
token += 16
:struct_init_no_lbrace
@@ -426,27 +429,55 @@ function parse_constant_initializer
p += 1
b = structure_is_union(*8p)
if b != 0 goto parse_union_initializer
- byte 0xcc ; @TODO
+
+ ; struct initializer
+ a = *8p
+ :struct_init_loop
+ if *1token == TOKEN_EOF goto struct_init_eof
+
+ ; skip name of member
+ a = memchr(a, 0)
+ a += 5 ; skip null terminator, offset
+ subtype = *4a
+ a += 4
+
+ parse_constant_initializer(&token, subtype)
+ if *1token == SYMBOL_RBRACE goto struct_init_loop_end
+ if *1a == 0 goto struct_init_loop_end ; finished reading all the members of the struct
+ if *1token != SYMBOL_COMMA goto bad_struct_initializer
+ token += 16 ; skip comma
+ goto struct_init_loop
+ :struct_init_loop_end
:struct_init_ret
+ c = type_sizeof(type)
+ rwdata_end_addr = addr0 + c ; add full size of struct/union to rwdata_end_addr, even if initialized member is smaller than that
+
if *1token != SYMBOL_RBRACE goto struct_init_noskip
p = *8p_token
if *1p != SYMBOL_LBRACE goto struct_init_noskip ; we don't want to skip the closing } because it doesn't belong to us.
token += 16 ; skip }
:struct_init_noskip
+
goto const_init_ret
:parse_union_initializer
- addr0 = rwdata_end_addr
a = ident_list_value_at_index(*8p, 0)
subtype = a > 32 ; extract type
-
parse_constant_initializer(&token, subtype)
-
- c = type_sizeof(type)
- rwdata_end_addr = addr0 + c ; add full size of union to rwdata_end_addr, even if initialized member is smaller than that.
goto struct_init_ret
-
+
+ :struct_init_eof
+ token_error(token, .str_struct_init_eof)
+ :str_struct_init_eof
+ string struct initializer does not end.
+ byte 0
+ :bad_struct_initializer
+ token_error(token, .str_bad_struct_initializer)
+ :str_bad_struct_initializer
+ string Bad struct initializer.
+ byte 0
+
:parse_string_array_initializer
p = types + type
p += 9