summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-08-28 16:11:58 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-08-28 16:11:58 -0400
commit4227b244b99cdfb1a1022f7816e52256bcca4bc7 (patch)
tree54d6d5220b0d3a7997d10ffd33c848d9aecf3829 /types.c
parent38e5501205573597c6b8ef92e56ca76141b8e792 (diff)
added flexible numerical constants
Diffstat (limited to 'types.c')
-rw-r--r--types.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/types.c b/types.c
index 9eb2eb6..03ef9e7 100644
--- a/types.c
+++ b/types.c
@@ -83,9 +83,47 @@ static size_t type_to_string(Type *a, char *buffer, size_t bufsize) {
return 0;
}
+static bool type_builtin_is_floating(BuiltinType b) {
+ switch (b) {
+ case BUILTIN_FLOAT:
+ case BUILTIN_DOUBLE:
+ return true;
+ default: return false;
+ }
+}
+
+static bool type_builtin_is_numerical(BuiltinType b) {
+ switch (b) {
+ case BUILTIN_FLOAT:
+ case BUILTIN_DOUBLE:
+ case BUILTIN_I8:
+ case BUILTIN_I16:
+ case BUILTIN_I32:
+ case BUILTIN_I64:
+ case BUILTIN_U8:
+ case BUILTIN_U16:
+ case BUILTIN_U32:
+ case BUILTIN_U64:
+ return true;
+ default: return false;
+ }
+}
static bool type_eq(Type *a, Type *b) {
if (a->kind != b->kind) return false;
+ if (a->flags & TYPE_FLAG_FLEXIBLE) {
+ if (b->flags & TYPE_FLAG_FLEXIBLE) return true;
+ assert(a->kind == TYPE_BUILTIN);
+
+ if (a->builtin == BUILTIN_FLOAT) {
+ return type_builtin_is_floating(b->builtin);
+ }
+ assert(a->builtin == BUILTIN_I64);
+ return type_builtin_is_numerical(b->builtin);
+ }
+ if (b->flags & TYPE_FLAG_FLEXIBLE) {
+ return type_eq(b, a); /* OPTIM? */
+ }
switch (a->kind) {
case TYPE_VOID: return true;
case TYPE_BUILTIN:
@@ -123,6 +161,7 @@ static bool types_decl(Declaration *d);
static bool types_expr(Expression *e) {
Type *t = &e->type;
+ t->flags = 0;
switch (e->kind) {
case EXPR_FN: {
FnExpr *f = &e->fn;
@@ -144,10 +183,12 @@ static bool types_expr(Expression *e) {
case EXPR_INT_LITERAL:
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_I64;
+ t->flags |= TYPE_FLAG_FLEXIBLE;
break;
case EXPR_FLOAT_LITERAL:
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_FLOAT;
+ t->flags |= TYPE_FLAG_FLEXIBLE;
break;
case EXPR_IDENT: {
IdentDecl *decl = ident_decl(e->ident);