diff options
-rw-r--r-- | 05/main.b | 9 | ||||
-rw-r--r-- | 05/main.c | 18 | ||||
-rw-r--r-- | 05/parse.b | 17 | ||||
-rw-r--r-- | 05/preprocess.b | 4 | ||||
-rw-r--r-- | 05/tokenize.b | 6 |
5 files changed, 31 insertions, 23 deletions
@@ -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) @@ -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" */ @@ -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 |