local variables in expressions

This commit is contained in:
pommicket 2022-02-05 19:41:45 -05:00
parent 41f122f01e
commit a61c4f88f9
3 changed files with 32 additions and 3 deletions

View file

@ -144,6 +144,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 local variables, the 64-bit rbp offset (number to be subtracted from rbp)
; - for global variables, the 64-bit runtime address ; - 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)
@ -156,6 +157,7 @@
; - 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
; File/line number are not stored in expressions. ; File/line number are not stored in expressions.
; Note that string literals are stored as constant integers (you can check the type to know what it is) ; Note that string literals are stored as constant integers (you can check the type to know what it is)
#define EXPRESSION_LOCAL_VARIABLE 199
#define EXPRESSION_GLOBAL_VARIABLE 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

View file

@ -19,6 +19,7 @@ int h(void) {
struct { struct {
char a,b; char a,b;
} P[] = {1,2,3,4,5}; } P[] = {1,2,3,4,5};
int *Y = x;
static int marker = 0x12345678; static int marker = 0x12345678;
return 5; return 5;
} }

View file

@ -429,9 +429,12 @@ function parse_statement
if *1token == SYMBOL_LBRACE goto local_init_lbrace if *1token == SYMBOL_LBRACE goto local_init_lbrace
n = token_next_semicolon_or_comma_not_in_brackets(token) n = token_next_semicolon_or_comma_not_in_brackets(token)
out -= 16 out -= 16
*8out = expressions_end p = expressions_end
*8out = p
out += 16 out += 16
expressions_end = parse_expression(token, n, expressions_end) expressions_end = parse_expression(token, n, p)
p += 4
type_decay_array_to_pointer(*4p) ; fix typing for `int[] x = {5,6}; int *y = x;`
token = n token = n
goto local_decl_continue goto local_decl_continue
:local_init_lbrace :local_init_lbrace
@ -2428,7 +2431,10 @@ function parse_expression
p += n < 3 p += n < 3
c = ident_list_lookup(*8p, a) c = ident_list_lookup(*8p, a)
if c != 0 goto found_global_variable if c != 0 goto found_global_variable
; @TODO: check if it's a local variable p = local_variables
p += n < 3
c = ident_list_lookup(*8p, a)
if c != 0 goto found_local_variable
n -= 1 n -= 1
if n >= 0 goto var_lookup_loop if n >= 0 goto var_lookup_loop
@ -2451,6 +2457,15 @@ function parse_expression
:str_undeclared_variable :str_undeclared_variable
string Undeclared variable. string Undeclared variable.
byte 0 byte 0
:found_local_variable
; it's a local variable
*1out = EXPRESSION_LOCAL_VARIABLE
out += 4
*4out = c > 32 ; extract type
out += 4
*8out = c & 0xffffffff ; extract rbp offset
out += 8
return out
:expression_integer :expression_integer
*1out = EXPRESSION_CONSTANT_INT *1out = EXPRESSION_CONSTANT_INT
p = in + 8 p = in + 8
@ -3379,6 +3394,7 @@ function print_expression
:print_expr_skip_type :print_expr_skip_type
c = *1expression c = *1expression
if c == EXPRESSION_LOCAL_VARIABLE goto print_local_variable
if c == EXPRESSION_GLOBAL_VARIABLE goto print_global_variable if c == EXPRESSION_GLOBAL_VARIABLE goto print_global_variable
if c == EXPRESSION_CONSTANT_INT goto print_expr_int if c == EXPRESSION_CONSTANT_INT goto print_expr_int
if c == EXPRESSION_CONSTANT_FLOAT goto print_expr_float if c == EXPRESSION_CONSTANT_FLOAT goto print_expr_float
@ -3409,6 +3425,16 @@ function print_expression
:str_global_at :str_global_at
string global@ string global@
byte 0 byte 0
:print_local_variable
puts(.str_local_prefix)
expression += 8
putn(*8expression)
putc('])
expression += 8
return expression
:str_local_prefix
string [rsp-
byte 0
:print_global_variable :print_global_variable
puts(.str_global_at) puts(.str_global_at)
expression += 8 expression += 8