summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-09-28 15:42:46 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-09-28 15:42:46 -0400
commita4ee519c30cf2790347872eb8f78292f40e300a4 (patch)
tree941fe98c4c3f0b0eb4cf2e4a8bfe234bb7251b34 /types.c
parent2c78e1afeff7a9756801d1ced7c2949d78ec2e5b (diff)
some work on eval
Diffstat (limited to 'types.c')
-rw-r--r--types.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/types.c b/types.c
index dd724c3..dcfa7aa 100644
--- a/types.c
+++ b/types.c
@@ -628,7 +628,7 @@ static bool types_expr(Typer *tr, Expression *e) {
}
} break;
case EXPR_DIRECT:
- t->kind = TYPE_UNKNOWN;
+ /* type automatically set to unknown */
arr_foreach(&e->direct.args, Argument, arg) {
if (arg->name) {
err_print(arg->where, "Directives should not have named arguments.");
@@ -653,6 +653,9 @@ static bool types_expr(Typer *tr, Expression *e) {
Expression *of = e->unary.of;
Type *of_type = &of->type;
if (!types_expr(tr, e->unary.of)) return false;
+ if (of_type->kind == TYPE_UNKNOWN) {
+ return true;
+ }
switch (e->unary.op) {
case UNARY_MINUS:
if (of_type->kind != TYPE_BUILTIN || !type_builtin_is_numerical(of_type->builtin)) {
@@ -707,6 +710,9 @@ static bool types_expr(Typer *tr, Expression *e) {
if (!types_expr(tr, e->binary.lhs)
|| !types_expr(tr, e->binary.rhs))
return false;
+ if (lhs_type->kind == TYPE_UNKNOWN || rhs_type->kind == TYPE_UNKNOWN) {
+ return true;
+ }
switch (e->binary.op) {
case BINARY_SET:
if (!expr_must_lval(e->binary.lhs)) {
@@ -755,15 +761,21 @@ static bool types_expr(Typer *tr, Expression *e) {
int lhs_is_flexible = lhs_type->flags & TYPE_FLAG_FLEXIBLE;
int rhs_is_flexible = rhs_type->flags & TYPE_FLAG_FLEXIBLE;
if (lhs_is_flexible && rhs_is_flexible) {
- *t = *lhs_type;
+ /* both flexible */
if (rhs_type->builtin == BUILTIN_F32) {
/* promote to float */
- t->builtin = BUILTIN_F32;
+ lhs_type->builtin = BUILTIN_F32;
}
- } else if (!lhs_is_flexible)
+ if (lhs_type->builtin == BUILTIN_F32)
+ rhs_type->builtin = BUILTIN_F32;
*t = *lhs_type;
- else
+ } else if (!lhs_is_flexible) {
+ /* lhs inflexible, rhs ? */
+ *t = *lhs_type;
+ } else {
+ /* lhs flexible, rhs ? */
*t = *rhs_type;
+ }
} break;
}
}
@@ -883,13 +895,19 @@ static bool types_decl(Typer *tr, Declaration *d) {
}
}
}
- d->flags |= DECL_FLAG_FOUND_TYPE;
if (d->type.kind == TYPE_TUPLE) {
/* TODO(eventually): Should this be allowed? */
err_print(d->where, "Declaring a tuple is not allowed.");
return false;
}
ret:
+ /* pretend we found the type even if we didn't to prevent too many errors */
+ d->flags |= DECL_FLAG_FOUND_TYPE;
+ if (!success) {
+ /* use unknown type if we didn't get the type */
+ d->type.flags = 0;
+ d->type.kind = TYPE_UNKNOWN;
+ }
arr_remove_last(&tr->in_decls);
return success;
}