string literal initializers, global variable expressions
This commit is contained in:
parent
22859ac40a
commit
92293e83ac
3 changed files with 50 additions and 4 deletions
|
@ -133,6 +133,7 @@
|
||||||
; ushort (padding)
|
; ushort (padding)
|
||||||
; uint type
|
; uint type
|
||||||
; immediately following the header in memory are the arguments of the expression
|
; 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 ints, the 64-bit integral value
|
||||||
; - for constant floats, the 64-bit double value (even if expression has type float)
|
; - 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)
|
; - 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 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
|
; - 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.
|
; 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_INT 201
|
||||||
#define EXPRESSION_CONSTANT_FLOAT 202
|
#define EXPRESSION_CONSTANT_FLOAT 202
|
||||||
#define EXPRESSION_STRING_LITERAL 203
|
#define EXPRESSION_STRING_LITERAL 203
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
static unsigned int x=55;
|
static unsigned int x=55;
|
||||||
static char *s = "hello";
|
static char *s = "hello";
|
||||||
static char *t = "goodbye";
|
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
|
NOTE: THIS MUST WORK
|
||||||
int x[] = {1,2,3}
|
int x[] = {1,2,3}
|
||||||
|
|
45
05/parse.b
45
05/parse.b
|
@ -236,6 +236,8 @@ function parse_constant_initializer
|
||||||
local token
|
local token
|
||||||
local end
|
local end
|
||||||
local depth
|
local depth
|
||||||
|
local a
|
||||||
|
local b
|
||||||
local c
|
local c
|
||||||
local p
|
local p
|
||||||
local expr
|
local expr
|
||||||
|
@ -332,7 +334,29 @@ function parse_constant_initializer
|
||||||
goto const_init_ret
|
goto const_init_ret
|
||||||
|
|
||||||
:string_literal_array_initializer
|
: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
|
:stuff_after_string_literal
|
||||||
token_error(token, .str_stuff_after_string_literal)
|
token_error(token, .str_stuff_after_string_literal)
|
||||||
:str_stuff_after_string_literal
|
:str_stuff_after_string_literal
|
||||||
|
@ -1651,8 +1675,23 @@ function parse_expression
|
||||||
out += 8
|
out += 8
|
||||||
return out
|
return out
|
||||||
:not_enumerator
|
:not_enumerator
|
||||||
in -= 16
|
; @TODO: check if it's a local variable
|
||||||
token_error(in, .str_undeclared_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
|
:str_undeclared_variable
|
||||||
string Undeclared variable.
|
string Undeclared variable.
|
||||||
byte 0
|
byte 0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue