diff options
-rw-r--r-- | 05/constants.b | 3 | ||||
-rw-r--r-- | 05/main.c | 6 | ||||
-rw-r--r-- | 05/parse.b | 45 |
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 @@ -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} @@ -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 |