aboutsummaryrefslogtreecommitdiff
path: root/src/types.c
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-02 19:22:15 -0500
committerMustafa Quraish <[email protected]>2022-02-02 19:22:15 -0500
commite2dbc82213a6e5da74de2220eeeab78da41fb519 (patch)
tree7f6d9a40fde00ec761e100a92bd93f555725d56c /src/types.c
parentMove type-related stuff to a separate file (diff)
downloadcup-e2dbc82213a6e5da74de2220eeeab78da41fb519.tar.xz
cup-e2dbc82213a6e5da74de2220eeeab78da41fb519.zip
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.
Diffstat (limited to 'src/types.c')
-rw-r--r--src/types.c20
1 files changed, 19 insertions, 1 deletions
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