summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--05/constants.b2
-rw-r--r--05/main.c1
-rw-r--r--05/parse.b32
3 files changed, 32 insertions, 3 deletions
diff --git a/05/constants.b b/05/constants.b
index bef0245..73e321a 100644
--- a/05/constants.b
+++ b/05/constants.b
@@ -144,6 +144,7 @@
; ushort (padding)
; uint type
; 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 constant ints, the 64-bit integral value
; - 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
; 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)
+#define EXPRESSION_LOCAL_VARIABLE 199
#define EXPRESSION_GLOBAL_VARIABLE 200
#define EXPRESSION_CONSTANT_INT 201
#define EXPRESSION_CONSTANT_FLOAT 202
diff --git a/05/main.c b/05/main.c
index 3386be0..8fa4dbd 100644
--- a/05/main.c
+++ b/05/main.c
@@ -19,6 +19,7 @@ int h(void) {
struct {
char a,b;
} P[] = {1,2,3,4,5};
+ int *Y = x;
static int marker = 0x12345678;
return 5;
}
diff --git a/05/parse.b b/05/parse.b
index 38609e8..40f2a30 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -429,9 +429,12 @@ function parse_statement
if *1token == SYMBOL_LBRACE goto local_init_lbrace
n = token_next_semicolon_or_comma_not_in_brackets(token)
out -= 16
- *8out = expressions_end
+ p = expressions_end
+ *8out = p
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
goto local_decl_continue
:local_init_lbrace
@@ -2428,7 +2431,10 @@ function parse_expression
p += n < 3
c = ident_list_lookup(*8p, a)
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
if n >= 0 goto var_lookup_loop
@@ -2451,6 +2457,15 @@ function parse_expression
:str_undeclared_variable
string Undeclared variable.
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
*1out = EXPRESSION_CONSTANT_INT
p = in + 8
@@ -3379,6 +3394,7 @@ function print_expression
:print_expr_skip_type
c = *1expression
+ if c == EXPRESSION_LOCAL_VARIABLE goto print_local_variable
if c == EXPRESSION_GLOBAL_VARIABLE goto print_global_variable
if c == EXPRESSION_CONSTANT_INT goto print_expr_int
if c == EXPRESSION_CONSTANT_FLOAT goto print_expr_float
@@ -3409,6 +3425,16 @@ function print_expression
:str_global_at
string global@
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
puts(.str_global_at)
expression += 8