struct initializers, found some bugs (not fixed yet)

This commit is contained in:
pommicket 2022-02-02 15:12:28 -05:00
parent 2a65d49d59
commit c19bed7454
3 changed files with 65 additions and 26 deletions

View file

@ -1,3 +1,6 @@
; @TODO: string literals should have type char[n] where n = strlen(s)+1
; gah
; add 24 + 16 = 40 to the stack pointer to put argc, argv in the right place ; add 24 + 16 = 40 to the stack pointer to put argc, argv in the right place
byte 0x48 byte 0x48
byte 0x81 byte 0x81

View file

@ -27,23 +27,28 @@
/* typedef int x[sizeof(A)+sizeof"hello"]; */ /* typedef int x[sizeof(A)+sizeof"hello"]; */
/* typedef int y[sizeof(struct B)]; */ /* typedef int y[sizeof(struct B)]; */
/* */ /* */
static unsigned int x={55}; /* static unsigned int x={55}; */
static char *s = "hello"; /* static char *s = "hello"; */
static char *t = "goodbye"; /* static char *t = "goodbye"; */
static char u[8] = "hellothe"; /* static char u[8] = "hellothe"; */
static char v[100] = "re my"; /* static char v[100] = "re my"; */
static char w[] = "friendly"; /* static char w[] = "friendly"; */
static char x_[] = "hi"; /* static char x_[] = "hi"; */
typedef int A[sizeof x_ + sizeof u]; /* 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; */
static int a[5] = {1,2,3}; /* struct { */
static char b[6][7] = {{'a'},{'b'},{'c'},{'d'},{'e'}}; /* int a; */
static char __b[][7] = {{'a'},"hello",'r'}; /* long b; */
static int _u = sizeof __b; /* } x1[] = {0x1234567890, 1ul<<60|1ul<<3, 77}; */
/* int y1 = 0x12345678; */
typedef int R[sizeof "hi" / sizeof "hi"[0]];
union { /* struct { */
int a; /* int x[2], y; */
long b; /* } test = {3, 5}; */
} x1[3] = {0x1234567890, 1ul<<60|1ul<<3, 77}; /* unsigned marker = 0xdeadbeef; */
int y1 = 0x12345678;
typedef int R[sizeof x1];

View file

@ -164,6 +164,7 @@ function parse_tokens
byte 0 byte 0
:parse_function_definition :parse_function_definition
p = types + type p = types + type
; @NOTE: remember to turn array members into pointers
if *1p != TYPE_FUNCTION goto lbrace_after_declaration if *1p != TYPE_FUNCTION goto lbrace_after_declaration
die(.str_fdNI) ; @TODO die(.str_fdNI) ; @TODO
:str_fdNI :str_fdNI
@ -257,6 +258,7 @@ function parse_constant_initializer
local a local a
local b local b
local c local c
local len
local p local p
local expr local expr
local value local value
@ -366,7 +368,6 @@ function parse_constant_initializer
:array_init_no_lbrace :array_init_no_lbrace
addr0 = rwdata_end_addr addr0 = rwdata_end_addr
local len
len = types + type len = types + type
len += 1 ; skip TYPE_ARRAY len += 1 ; skip TYPE_ARRAY
len = *8len len = *8len
@ -412,6 +413,8 @@ function parse_constant_initializer
string Bad array initializer. string Bad array initializer.
byte 0 byte 0
:parse_struct_initializer :parse_struct_initializer
addr0 = rwdata_end_addr
if *1token != SYMBOL_LBRACE goto struct_init_no_lbrace ; only happens when recursing if *1token != SYMBOL_LBRACE goto struct_init_no_lbrace ; only happens when recursing
token += 16 token += 16
:struct_init_no_lbrace :struct_init_no_lbrace
@ -426,27 +429,55 @@ function parse_constant_initializer
p += 1 p += 1
b = structure_is_union(*8p) b = structure_is_union(*8p)
if b != 0 goto parse_union_initializer 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 :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 if *1token != SYMBOL_RBRACE goto struct_init_noskip
p = *8p_token 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. 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 } token += 16 ; skip }
:struct_init_noskip :struct_init_noskip
goto const_init_ret goto const_init_ret
:parse_union_initializer :parse_union_initializer
addr0 = rwdata_end_addr
a = ident_list_value_at_index(*8p, 0) a = ident_list_value_at_index(*8p, 0)
subtype = a > 32 ; extract type subtype = a > 32 ; extract type
parse_constant_initializer(&token, subtype) 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 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 :parse_string_array_initializer
p = types + type p = types + type
p += 9 p += 9