summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-02 09:49:56 -0500
committerpommicket <pommicket@gmail.com>2022-02-02 09:49:56 -0500
commit92293e83acc10197737f94933ab7c98cb1a151cd (patch)
tree4f3531ee289a814d641929cd955a5e92458e77c5
parent22859ac40a9cedb4b7b7fcf6724548c625c35956 (diff)
string literal initializers, global variable expressions
-rw-r--r--05/constants.b3
-rw-r--r--05/main.c6
-rw-r--r--05/parse.b45
3 files changed, 50 insertions, 4 deletions
diff --git a/05/constants.b b/05/constants.b
index 01e5dd2..09d3056 100644
--- a/05/constants.b
+++ b/05/constants.b
@@ -133,6 +133,7 @@
; ushort (padding)
; uint type
; immediately following the header in memory are the arguments of the expression
+; - for global variables, the 64-bit runtime address
; - for constant ints, the 64-bit integral value
; - for constant floats, the 64-bit double value (even if expression has type float)
; - for string literals, a 64-bit pointer to the string (for the executable, not for the compiler)
@@ -144,7 +145,7 @@
; - for the ternary operator ? :, the first followed by the second followed by the third
; - for function calls, the function, followed by each of the arguments to the function — info indicates the number of arguments
; Note that file/line number are not stored in expressions.
-#define EXPRESSION_IDENTIFIER 200
+#define EXPRESSION_GLOBAL_VARIABLE 200
#define EXPRESSION_CONSTANT_INT 201
#define EXPRESSION_CONSTANT_FLOAT 202
#define EXPRESSION_STRING_LITERAL 203
diff --git a/05/main.c b/05/main.c
index 1f07113..62b198b 100644
--- a/05/main.c
+++ b/05/main.c
@@ -30,6 +30,12 @@
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];
+
/*
NOTE: THIS MUST WORK
int x[] = {1,2,3}
diff --git a/05/parse.b b/05/parse.b
index d556936..22fd621 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -236,6 +236,8 @@ function parse_constant_initializer
local token
local end
local depth
+ local a
+ local b
local c
local p
local expr
@@ -332,7 +334,29 @@ function parse_constant_initializer
goto const_init_ret
:string_literal_array_initializer
- byte 0xcc
+ p += 1
+ c = *8p ; array size
+ token += 8
+ a = output_file_data + rwdata_end_addr ; destination (where to put the string data)
+ b = output_file_data + *8token ; source (where the string data is now)
+ if c == 0 goto string_literal_sizeless_initializer
+ value = strlen(b)
+ if c < value goto string_literal_init_too_long ; e.g. char x[3] = "hello";
+ strcpy(a, b)
+ rwdata_end_addr += c ; advance by c, which is possibly more than the length of the string--the remaining bytes will be 0s
+ goto const_init_ret
+ :string_literal_sizeless_initializer ; e.g. char x[] = "hello";
+ c = strlen(b)
+ c += 1 ; null terminator
+ *8p = c ; set array size
+ strcpy(a, b)
+ rwdata_end_addr += c
+ goto const_init_ret
+ :string_literal_init_too_long
+ token_error(token, .str_string_literal_init_too_long)
+ :str_string_literal_init_too_long
+ string String literal is too long to fit in array.
+ byte 0
:stuff_after_string_literal
token_error(token, .str_stuff_after_string_literal)
:str_stuff_after_string_literal
@@ -1651,8 +1675,23 @@ function parse_expression
out += 8
return out
:not_enumerator
- in -= 16
- token_error(in, .str_undeclared_variable)
+ ; @TODO: check if it's a local variable
+
+ ; check if it's a global
+ c = ident_list_lookup(global_variables, a)
+ if c == 0 goto not_global
+ ; it is a global variable
+ *1out = EXPRESSION_GLOBAL_VARIABLE
+ out += 4
+ *4out = c > 32 ; extract type
+ out += 4
+ *8out = c & 0xffffffff ; extract address
+ out += 8
+ return out
+ :not_global
+
+ in -= 16
+ token_error(in, .str_undeclared_variable)
:str_undeclared_variable
string Undeclared variable.
byte 0