summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-02 15:12:28 -0500
committerpommicket <pommicket@gmail.com>2022-02-02 15:12:28 -0500
commitc19bed7454e148a042bb0e8a7fe16020e94c879a (patch)
tree6418663dd22eb6b6783fe58c1819a916624d0343
parent2a65d49d59918527ae32096b2094d09d62918730 (diff)
struct initializers, found some bugs (not fixed yet)
-rw-r--r--05/main.b3
-rw-r--r--05/main.c41
-rw-r--r--05/parse.b47
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