From c19bed7454e148a042bb0e8a7fe16020e94c879a Mon Sep 17 00:00:00 2001 From: pommicket Date: Wed, 2 Feb 2022 15:12:28 -0500 Subject: struct initializers, found some bugs (not fixed yet) --- 05/main.b | 3 +++ 05/main.c | 41 +++++++++++++++++++++++------------------ 05/parse.b | 47 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 65 insertions(+), 26 deletions(-) diff --git a/05/main.b b/05/main.b index 8a6ceb0..f9fb098 100644 --- a/05/main.b +++ b/05/main.b @@ -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 byte 0x48 byte 0x81 diff --git a/05/main.c b/05/main.c index 35d7917..a8149f8 100644 --- a/05/main.c +++ b/05/main.c @@ -27,23 +27,28 @@ /* typedef int x[sizeof(A)+sizeof"hello"]; */ /* typedef int y[sizeof(struct B)]; */ /* */ -static unsigned int x={55}; -static char *s = "hello"; -static char *t = "goodbye"; -static char u[8] = "hellothe"; -static char v[100] = "re my"; -static char w[] = "friendly"; -static char x_[] = "hi"; -typedef int A[sizeof x_ + sizeof u]; +/* static unsigned int x={55}; */ +/* static char *s = "hello"; */ +/* static char *t = "goodbye"; */ +/* static char u[8] = "hellothe"; */ +/* static char v[100] = "re my"; */ +/* static char w[] = "friendly"; */ +/* static char x_[] = "hi"; */ +/* 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}; -static char b[6][7] = {{'a'},{'b'},{'c'},{'d'},{'e'}}; -static char __b[][7] = {{'a'},"hello",'r'}; -static int _u = sizeof __b; +/* struct { */ +/* int a; */ +/* long b; */ +/* } x1[] = {0x1234567890, 1ul<<60|1ul<<3, 77}; */ +/* int y1 = 0x12345678; */ +typedef int R[sizeof "hi" / sizeof "hi"[0]]; -union { - int a; - long b; -} x1[3] = {0x1234567890, 1ul<<60|1ul<<3, 77}; -int y1 = 0x12345678; -typedef int R[sizeof x1]; +/* struct { */ +/* int x[2], y; */ +/* } test = {3, 5}; */ +/* unsigned marker = 0xdeadbeef; */ 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 -- cgit v1.2.3