summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-08 21:53:14 -0500
committerpommicket <pommicket@gmail.com>2022-02-08 21:53:14 -0500
commitd7a9a565a9819ef0e9d5ba6123b28b2556e73ca1 (patch)
tree0e54fb8b681b16ca5c108cdd3cfe052f92b9847b
parent0a2d05bdd5dd788de90b2291a981b851de183976 (diff)
fix declaring multiple variables after struct definition
-rw-r--r--05/main.b9
-rw-r--r--05/main.c18
-rw-r--r--05/parse.b17
-rw-r--r--05/preprocess.b4
-rw-r--r--05/tokenize.b6
5 files changed, 31 insertions, 23 deletions
diff --git a/05/main.b b/05/main.b
index 0abf323..8074bf5 100644
--- a/05/main.b
+++ b/05/main.b
@@ -34,6 +34,12 @@ global enumerators
; for unions, offset will always be 0.
global structures
global structures_bytes_used
+; ident map of "locations" (see token_get_location) where structs are defined
+; this is used in a horrible way to avoid getting struct redefinition errors from
+; struct A { int x; } a,b;
+; it's not foolproof -- you could have struct A {int x;} a; struct A {float x;} b; on one line
+; but that seems extremely unlikely to happen
+global structure_locations
; file offset/runtime address to write next piece of read-only data; initialized in main
global rodata_end_addr
; file offset/runtime address to write next piece of read-write data; initialized in main
@@ -223,7 +229,8 @@ function main
typedefs = ident_list_create(100000)
enumerators = ident_list_create(4000000)
- structures = ident_list_create(4000000)
+ structures = ident_list_create(2000000)
+ structure_locations = ident_list_create(2000000)
global_variables = ident_list_create(400000)
function_statements = ident_list_create(800000)
function_types = ident_list_create(800000)
diff --git a/05/main.c b/05/main.c
index c929f02..72c22aa 100644
--- a/05/main.c
+++ b/05/main.c
@@ -1,17 +1 @@
-#include "tests/parse_stb_image.h"
-/* #if 0 */
-/* #elif 1 */
-/* int f(){} */
-/* #endif */
-/* @TODO: some more testing of #if/#elif/#else/#endif */
-/* @TODO: ensure that
- struct Something {
- int a;
- } x,y;
- works
-*/
-
-
-
-int main() {
-}
+/* #include "tests/parse_stb_image.h" */
diff --git a/05/parse.b b/05/parse.b
index 1824924..a643751 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -2094,7 +2094,7 @@ function parse_base_type
goto base_type_done
:base_type_struct_definition
; @NONSTANDARD: we don't handle bit-fields.
-
+ local struct_location
local member_base_type
local member_prefix
local member_prefix_end
@@ -2105,7 +2105,9 @@ function parse_base_type
local member_align
local member_size
- if c != 0 goto struct_redefinition
+ struct_location = token_get_location(p)
+
+ if c != 0 goto struct_maybe_redefinition
struct = ident_list_create(8000) ; note: maximum "* 127 members in a single structure or union" C89 ยง 2.2.4.1
*1out = TYPE_STRUCT
out += 1
@@ -2119,6 +2121,7 @@ function parse_base_type
if *1struct_name == 0 goto struct_unnamed
ident_list_add(structures, struct_name, struct)
+ ident_list_add(structure_locations, struct_name, struct_location)
:struct_unnamed
:struct_defn_loop
@@ -2175,6 +2178,16 @@ function parse_base_type
:struct_defn_loop_end
out = types + types_bytes_used
goto base_type_done
+ :struct_maybe_redefinition
+ local other_location
+ other_location = ident_list_lookup(structure_locations, struct_name)
+ if other_location != struct_location goto struct_redefinition ; actual struct redefinition
+ ; we don't want lines like this to cause problems: struct A { int x,y; } a,b;
+ *1out = TYPE_STRUCT
+ out += 1
+ *8out = c
+ out += 8
+ goto base_type_done
:struct_redefinition
token_error(p, .str_struct_redefinition)
:str_struct_redefinition
diff --git a/05/preprocess.b b/05/preprocess.b
index e6f7b52..132f02c 100644
--- a/05/preprocess.b
+++ b/05/preprocess.b
@@ -980,8 +980,8 @@ function translation_phase_4
:pp_if_idents0_done
;print_tokens(if_tokens, p)
parse_expression(if_tokens, p, if_expr)
- print_expression(if_expr)
- putc(10)
+ ;print_expression(if_expr)
+ ;putc(10)
evaluate_constant_expression(p, if_expr, &b)
if b == 0 goto pp_directive_if0
goto pp_if_done
diff --git a/05/tokenize.b b/05/tokenize.b
index 7b9e280..841f7df 100644
--- a/05/tokenize.b
+++ b/05/tokenize.b
@@ -95,7 +95,11 @@ function get_keyword_str
:str_no_such_keyword_id
string @BAD_KEYWORD_ID
byte 0
-
+
+; returns a unique number associated with the line `token` appears on.
+function token_get_location
+ argument token
+ return *8token > 16 ; right shift by 16 to remove type,info, and extract 6 bytes of file,line
; turn pptokens into tokens, written to out.
; This corresponds to translation phases 5-6 and the first half of 7