summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-02 23:02:31 -0500
committerpommicket <pommicket@gmail.com>2022-02-02 23:02:31 -0500
commitbe9a3b4bd5f7e9a44c16d942e2f7050927d0e277 (patch)
tree7844fc466d43c3177cb41486fb29d61a4522e261
parente8378ddac0aee99e567082233d8488c3c915bd3a (diff)
arrays decay to pointers - also found bug
-rw-r--r--05/main.b3
-rw-r--r--05/main.c2
-rw-r--r--05/parse.b54
-rw-r--r--05/util.b1
4 files changed, 50 insertions, 10 deletions
diff --git a/05/main.b b/05/main.b
index f9fb098..8a6ceb0 100644
--- a/05/main.b
+++ b/05/main.b
@@ -1,6 +1,3 @@
-; @TODO: string literals should have type char[n] where n = strlen(s)+1
-; gah
-
; add 24 + 16 = 40 to the stack pointer to put argc, argv in the right place
byte 0x48
byte 0x81
diff --git a/05/main.c b/05/main.c
index a8149f8..008efd1 100644
--- a/05/main.c
+++ b/05/main.c
@@ -46,7 +46,7 @@
/* long b; */
/* } x1[] = {0x1234567890, 1ul<<60|1ul<<3, 77}; */
/* int y1 = 0x12345678; */
-typedef int R[sizeof "hi" / sizeof "hi"[0]];
+typedef int R[*(int*)3];
/* struct { */
/* int x[2], y; */
diff --git a/05/parse.b b/05/parse.b
index cdecd8f..41ee6fd 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -1329,7 +1329,7 @@ function parse_expression
local first_token
:parse_expression_top
- ;print_tokens(tokens, tokens_end)
+ print_tokens(tokens, tokens_end)
type = out + 4
@@ -1487,12 +1487,16 @@ function parse_expression
byte 0
:type_plus
+ type_decay_array_to_pointer(*4a)
+ type_decay_array_to_pointer(*4b)
p = types + *4a
if *1p == TYPE_POINTER goto type_binary_left ; pointer plus integer
p = types + *4b
if *1p == TYPE_POINTER goto type_binary_right ; integer plus pointer
goto type_binary_usual
:type_minus
+ type_decay_array_to_pointer(*4a)
+ type_decay_array_to_pointer(*4b)
p = types + *4a
if *1p == TYPE_POINTER goto type_minus_left_ptr
goto type_binary_usual
@@ -1501,6 +1505,7 @@ function parse_expression
if *1p == TYPE_POINTER goto type_long ; pointer difference
goto type_binary_left ; pointer minus integer
:type_subscript
+ type_decay_array_to_pointer(*4a)
p = types + *4a
if *1p == TYPE_POINTER goto type_subscript_pointer
if *1p == TYPE_ARRAY goto type_subscript_array
@@ -1614,10 +1619,17 @@ function parse_expression
*4type = type_create_pointer(*4a)
return out
:unary_dereference
+ print_type(*4a)
+ putc(10)
+ type_decay_array_to_pointer(*4a)
+ print_type(*4a)
+ putc(10)
+ ; @TODO : dereferencing a function (annoyingly, p is the same as *p for function pointers)
if *1p != TYPE_POINTER goto unary_bad_type
*4type = *4a + 1
return out
:unary_type_logical_not
+ type_decay_array_to_pointer(*4a)
if *1p > TYPE_POINTER goto unary_bad_type
*4type = TYPE_INT
return out
@@ -1880,9 +1892,19 @@ function parse_expression
p = out + 8
*8p = value
- ; must be char*
+ ; the type of this is array of n chars, where n = strlen(s)+1
+ type = types + types_bytes_used
+ *1type = TYPE_ARRAY
+ type += 1
+ p = output_file_data + value
+ *8type = strlen(p)
+ *8type += 1
+ type += 8
+ *1type = TYPE_CHAR
+
p = out + 4
- *4p = TYPE_POINTER_TO_CHAR
+ *4p = types_bytes_used
+ types_bytes_used += 10 ; TYPE_ARRAY + length + TYPE_CHAR
in += 16
out += 16
@@ -1922,6 +1944,23 @@ function parse_expression
:return_type_double
return TYPE_DOUBLE
+; if type is an array type, turn it into a pointer.
+; e.g.
+; char s[] = "hello";
+; char *t = s + 3; /* s "decays" into a pointer */
+function type_decay_array_to_pointer
+ argument type
+ local dest
+ local src
+ src = types + type
+ if *1src != TYPE_ARRAY goto return_0
+ dest = types + type
+ *1dest = TYPE_POINTER
+ src = type + 9 ; skip TYPE_ARRAY and size
+ dest = type + 1 ; skip TYPE_POINTER
+ type_copy_ids(dest, src)
+ return
+
function type_sizeof
argument type
local p
@@ -2512,6 +2551,8 @@ function operator_precedence
:operator_precedence_unary
op = *1token
+
+
if op == KEYWORD_SIZEOF goto return_0xe0
if op == SYMBOL_PLUS_PLUS goto return_0xe0
if op == SYMBOL_MINUS_MINUS goto return_0xe0
@@ -2673,12 +2714,13 @@ function binop_symbol_to_expression_type
return *1p
function is_operator
- argument symbol
+ argument token_type
local b
- b = binop_symbol_to_expression_type(symbol)
+ b = binop_symbol_to_expression_type(token_type)
if b != 0 goto return_1
- b = unary_op_to_expression_type(symbol)
+ b = unary_op_to_expression_type(token_type)
if b != 0 goto return_1
+ if token_type == KEYWORD_SIZEOF goto return_1
goto return_0
function binop_expression_type_to_symbol
diff --git a/05/util.b b/05/util.b
index 9e7afbb..6efb8e7 100644
--- a/05/util.b
+++ b/05/util.b
@@ -322,6 +322,7 @@ function memccpy
return dest
; like C, but returns 0
+; also, you can copy overlapping regions as long as dest < src.
function memcpy
argument dest
argument src