summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/constants.b4
-rw-r--r--05/main.b12
-rw-r--r--05/main.c12
-rw-r--r--05/parse.b27
4 files changed, 35 insertions, 20 deletions
diff --git a/05/constants.b b/05/constants.b
index 9c20fdc..06b141f 100644
--- a/05/constants.b
+++ b/05/constants.b
@@ -199,7 +199,8 @@
; char, unsigned char, etc.: TYPE_CHAR, TYPE_UNSIGNED_CHAR, etc. as a single byte
; pointer to type t: TYPE_PTR t
; array of n t's: TYPE_ARRAY {n as 8 bytes} t
-; struct/union: TYPE_STRUCT/TYPE_UNION {0 for incomplete types/4-byte pointer to struct/union}
+; struct/union: TYPE_STRUCT {8-byte pointer to struct/union data (see structures in main.b)}
+; note: incomplete structs/unions are replaced with void.
; function: TYPE_FUNCTION {arg1 type} {arg2 type} ... {argn type} 0 {return type}
; note that enum types are just treated as ints.
#define TYPE_VOID 1
@@ -216,7 +217,6 @@
#define TYPE_DOUBLE 12
#define TYPE_POINTER 13
#define TYPE_STRUCT 14
-#define TYPE_UNION 15
#define TYPE_ARRAY 16
#define TYPE_FUNCTION 17
diff --git a/05/main.b b/05/main.b
index f5b702a..2200156 100644
--- a/05/main.b
+++ b/05/main.b
@@ -30,6 +30,14 @@ global types_bytes_used
global typedefs
; ident list of enum values
global enumerators
+; struct/union names
+; an ident list of pointers to struct data (see structures below)
+global struct_names
+; structs and unions
+; each struct/union is an ident list of 64-bit values, (type << 32) | offset
+; for unions, offset will always be 0.
+global structures
+global structures_bytes_used
#include util.b
#include idents.b
@@ -146,7 +154,8 @@ function main
fill_in_powers_of_10()
typedefs = ident_list_create(100000)
- enumerators = ident_list_create(400000)
+ enumerators = ident_list_create(4000000)
+ struct_names = ident_list_create(4000000)
dat_banned_objmacros = 255
dat_banned_fmacros = 255
@@ -155,6 +164,7 @@ function main
*1file_list = 255
object_macros = malloc(4000000)
function_macros = malloc(4000000)
+ structures = malloc(40000000)
types = malloc(16000000)
types_init(types, &types_bytes_used)
diff --git a/05/main.c b/05/main.c
index 23a25c3..5499d36 100644
--- a/05/main.c
+++ b/05/main.c
@@ -3,14 +3,4 @@
long double d;
} (*x)(void);
*/
-typedef int Foo[(char)((unsigned char)0xff + (unsigned char)0xf02)];
-typedef enum {
- HELLO,
- THERE,
- TEST = 1-3,
- EEE = TEST+4,
- ASDFASDF,
- FFF,
- HELLO2
-} y;
-typedef int Bar[FFF];
+typedef int Foo(struct Bar { int x, y; }*);
diff --git a/05/parse.b b/05/parse.b
index f962e2a..2df0b23 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -455,9 +455,28 @@ function parse_type_to
*8p_token = suffix_end
return out
:base_type_struct
- byte 0xcc ; @TODO
:base_type_union
- byte 0xcc ; @TODO
+ p = prefix + 16
+ if *1p != TOKEN_IDENTIFIER goto base_type_struct_definition
+ p += 16
+ if *1p == SYMBOL_LBRACE goto base_type_struct_definition
+ p -= 8
+ c = ident_list_lookup(struct_names, *8p)
+ if c == 0 goto base_type_incomplete_struct
+ ; e.g. struct Foo x; where struct Foo has been defined
+ *1out = TYPE_STRUCT
+ out += 1
+ *8out = c
+ out += 8
+ goto base_type_done
+ :base_type_incomplete_struct
+ ; e.g. struct Foo *x; where struct Foo hasn't been defined
+ *1out = TYPE_VOID
+ out += 1
+ goto base_type_done
+ :base_type_struct_definition
+ if *1p != SYMBOL_LBRACE goto bad_type
+ byte 0xcc ; @TODO
:base_type_enum
local q
@@ -600,7 +619,6 @@ function type_length
return n + 9
:type_length_not_array
if *1p == TYPE_STRUCT goto return_5
- if *1p == TYPE_UNION goto return_5
if *1p != TYPE_FUNCTION goto type_length_not_function
local start
start = type
@@ -2056,7 +2074,6 @@ function print_type
if c == TYPE_POINTER goto print_type_pointer
if c == TYPE_ARRAY goto print_type_array
if c == TYPE_STRUCT goto print_type_struct
- if c == TYPE_UNION goto print_type_union
if c == TYPE_FUNCTION goto print_type_function
fputs(2, .str_bad_print_type)
exit(1)
@@ -2100,8 +2117,6 @@ function print_type
goto print_type_top
:print_type_struct
return puts(.str_struct)
- :print_type_union
- return puts(.str_union)
:print_type_function
type += 1
putc(40)