aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-03 00:34:14 -0500
committerMustafa Quraish <[email protected]>2022-02-03 02:56:55 -0500
commit4abf5167d1dd3fb404a50e422a9d87fcb4089dbb (patch)
tree36887402279610f930b163cac0b2d55f7f84db19 /src
parentAdd support for `char` type + string/char literals (diff)
downloadcup-4abf5167d1dd3fb404a50e422a9d87fcb4089dbb.tar.xz
cup-4abf5167d1dd3fb404a50e422a9d87fcb4089dbb.zip
Avoid pointer-arithmetic multiplications if we have `char*`
Simple optimization, it was just adding extra overhead anyway.
Diffstat (limited to 'src')
-rw-r--r--src/types.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/src/types.c b/src/types.c
index 9699f20..24458ff 100644
--- a/src/types.c
+++ b/src/types.c
@@ -114,7 +114,6 @@ Node *handle_unary_expr_types(Node *node, Token *token)
// Default to not changing the type
node->expr_type = old_type;
}
- // die_location(token->loc, "Unknown unary expression type in handle_unary_expr_types\n");
return node;
}
@@ -131,17 +130,21 @@ Node *handle_binary_expr_types(Node *node, Token *token)
} else if (left->type == TYPE_PTR && right->type == TYPE_INT) {
node->expr_type = left;
// Pointer arithmetic!
- Node *mul = Node_new(OP_MUL);
- mul->binary.left = node->binary.right;
- mul->binary.right = Node_from_int_literal(size_for_type(left->ptr));
- node->binary.right = mul;
+ if (size_for_type(left->ptr) != 1) {
+ Node *mul = Node_new(OP_MUL);
+ mul->binary.left = node->binary.right;
+ mul->binary.right = Node_from_int_literal(size_for_type(left->ptr));
+ node->binary.right = mul;
+ }
} else if (left->type == TYPE_INT && right->type == TYPE_PTR) {
node->expr_type = right;
// Pointer arithmetic!
- Node *mul = Node_new(OP_MUL);
- mul->binary.left = node->binary.left;
- mul->binary.right = Node_from_int_literal(size_for_type(left->ptr));
- node->binary.left = mul;
+ if (size_for_type(right->ptr) != 1) {
+ Node *mul = Node_new(OP_MUL);
+ mul->binary.left = node->binary.left;
+ mul->binary.right = Node_from_int_literal(size_for_type(right->ptr));
+ node->binary.left = mul;
+ }
} else {
die_location(token->loc, "Cannot add non-integer types");
}
@@ -153,26 +156,33 @@ Node *handle_binary_expr_types(Node *node, Token *token)
} else if (left->type == TYPE_PTR && right->type == TYPE_INT) {
node->expr_type = left;
// Pointer arithmetic!
- Node *mul = Node_new(OP_MUL);
- mul->binary.left = node->binary.right;
- mul->binary.right = Node_from_int_literal(size_for_type(left->ptr));
- node->binary.right = mul;
+ if (size_for_type(left->ptr) != 1) {
+ Node *mul = Node_new(OP_MUL);
+ mul->binary.left = node->binary.right;
+ mul->binary.right = Node_from_int_literal(size_for_type(left->ptr));
+ node->binary.right = mul;
+ }
} else if (left->type == TYPE_INT && right->type == TYPE_PTR) {
node->expr_type = right;
// Pointer arithmetic!
- Node *mul = Node_new(OP_MUL);
- mul->binary.left = node->binary.left;
- mul->binary.right = Node_from_int_literal(size_for_type(right->ptr));
- node->binary.left = mul;
+ if (size_for_type(right->ptr) != 1) {
+ Node *mul = Node_new(OP_MUL);
+ mul->binary.left = node->binary.left;
+ mul->binary.right = Node_from_int_literal(size_for_type(right->ptr));
+ node->binary.left = mul;
+ }
} else if (left->type == TYPE_PTR && right->type == TYPE_PTR) {
- // TODO: Check for different pointer types
node->expr_type = type_new(TYPE_INT);
- // Divide by size of pointer
- Node *div = Node_new(OP_DIV);
- div->binary.left = node;
- div->binary.right = Node_from_int_literal(size_for_type(left->ptr));
- div->expr_type = node->expr_type;
- node = div;
+ if (!type_equals(left->ptr, right->ptr))
+ die_location(token->loc, "Cannot subtract pointers of different types");
+
+ // Pointer arithmetic! (Divide by size of element)
+ if (size_for_type(left->ptr) != 1) {
+ Node *mul = Node_new(OP_MUL);
+ mul->binary.left = node->binary.left;
+ mul->binary.right = Node_from_int_literal(size_for_type(left->ptr));
+ node->binary.left = mul;
+ }
} else {
die_location(token->loc, "Cannot subtract non-integer types");
}