From e2dbc82213a6e5da74de2220eeeab78da41fb519 Mon Sep 17 00:00:00 2001 From: Mustafa Quraish Date: Wed, 2 Feb 2022 19:22:15 -0500 Subject: Add initial support for arrays (also no testing) Usual disclaimer at this point: Quick&Dirty implementation, hasn't been tested other than basic sanity checks. Arrays are automatically decayed into pointers when the identifier is accessed. --- src/types.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src/types.c') diff --git a/src/types.c b/src/types.c index bf855de..8876b22 100644 --- a/src/types.c +++ b/src/types.c @@ -21,6 +21,7 @@ i64 size_for_type(Type *type) { case TYPE_INT: return 8; case TYPE_PTR: return 8; + case TYPE_ARRAY: return type->array_size * size_for_type(type->ptr); default: assert(false && "Unreachable type"); } } @@ -44,6 +45,7 @@ static char *data_type_to_str(DataType type) case TYPE_NONE: return "void"; case TYPE_INT: return "int"; case TYPE_PTR: return "*"; + case TYPE_ARRAY: return "array"; default: assert(false && "Unreachable"); } } @@ -76,12 +78,16 @@ Node *handle_unary_expr_types(Node *node, Token *token) node->expr_type = type_new(TYPE_INT); } else if (node->type == OP_ADDROF) { Type *ptr = type_new(TYPE_PTR); - ptr->ptr = old_type; + // The address of an array is a pointer to the first element + ptr->ptr = old_type->type == TYPE_ARRAY ? old_type->ptr : old_type; node->expr_type = ptr; } else if (node->type == OP_DEREF) { if (old_type->type != TYPE_PTR) die_location(token->loc, "Cannot dereference non-pointer type"); node->expr_type = old_type->ptr; + // If the dereferenced type is an array, we need to decay it to a + // pointer to the first element. + node = decay_array_to_pointer(node, token); } else if (node->type == OP_NEG) { if (old_type->type != TYPE_INT) die_location(token->loc, "Cannot negate non-integer type"); @@ -184,3 +190,15 @@ Node *handle_binary_expr_types(Node *node, Token *token) } return node; } + +Node *decay_array_to_pointer(Node *node, Token *token) +{ + // We can only take the address of an lvalue, so we need to ensure that + if (is_lvalue(node->type) && node->expr_type->type == TYPE_ARRAY) { + Node *address = Node_new(OP_ADDROF); + address->unary_expr = node; + address = handle_unary_expr_types(address, token); + node = address; + } + return node; +} \ No newline at end of file -- cgit v1.2.3