From be9a3b4bd5f7e9a44c16d942e2f7050927d0e277 Mon Sep 17 00:00:00 2001 From: pommicket Date: Wed, 2 Feb 2022 23:02:31 -0500 Subject: arrays decay to pointers - also found bug --- 05/main.b | 3 --- 05/main.c | 2 +- 05/parse.b | 54 ++++++++++++++++++++++++++++++++++++++++++++++++------ 05/util.b | 1 + 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 -- cgit v1.2.3