diff options
-rw-r--r-- | base_cgen.c | 1 | ||||
-rw-r--r-- | out.c | 2 | ||||
-rw-r--r-- | parse.c | 14 | ||||
-rw-r--r-- | test.toc | 4 | ||||
-rw-r--r-- | types.c | 41 |
5 files changed, 53 insertions, 9 deletions
diff --git a/base_cgen.c b/base_cgen.c index 3b92c8e..d83b690 100644 --- a/base_cgen.c +++ b/base_cgen.c @@ -130,7 +130,6 @@ static bool cgen_ident(CGenerator *g, Identifier i, Location *where) { static const char *builtin_type_to_str(BuiltinType b) { /* TODO: make this return int/long/etc. if stdint.h is not available */ switch (b) { - case BUILTIN_INT: return "int64_t"; case BUILTIN_I8: return "int8_t"; case BUILTIN_I16: return "int16_t"; case BUILTIN_I32: return "int32_t"; @@ -13,6 +13,8 @@ void main__(void) { float b = 32.300000; int64_t c = a; int64_t blah = 32; + float asfdljk = 12.300000; + int8_t asdkfjhakj = 1332948; } static void a___(void) { } @@ -6,7 +6,6 @@ typedef enum { } TypeKind; typedef enum { - BUILTIN_INT, BUILTIN_I8, BUILTIN_I16, BUILTIN_I32, @@ -20,10 +19,13 @@ typedef enum { BUILTIN_TYPE_COUNT } BuiltinType; +#define TYPE_FLAG_FLEXIBLE 0x01 + typedef struct Type { Location where; TypeKind kind; + unsigned short flags; union { BuiltinType builtin; struct { @@ -75,7 +77,6 @@ typedef struct Expression { Location where; ExprKind kind; Type type; - unsigned short flags; union { FloatLiteral floatl; IntLiteral intl; @@ -147,11 +148,11 @@ static Expression *parser_new_expr(Parser *p) { /* returns BUILTIN_TYPE_COUNT on failure */ static BuiltinType kw_to_builtin_type(Keyword kw) { switch (kw) { - case KW_INT: return BUILTIN_INT; case KW_I8: return BUILTIN_I8; case KW_I16: return BUILTIN_I16; case KW_I32: return BUILTIN_I32; case KW_I64: return BUILTIN_I64; + case KW_INT: return BUILTIN_I64; case KW_U8: return BUILTIN_U8; case KW_U16: return BUILTIN_U16; case KW_U32: return BUILTIN_U32; @@ -164,7 +165,6 @@ static BuiltinType kw_to_builtin_type(Keyword kw) { static Keyword builtin_type_to_kw(BuiltinType t) { switch (t) { - case BUILTIN_INT: return KW_INT; case BUILTIN_I8: return KW_I8; case BUILTIN_I16: return KW_I16; case BUILTIN_I32: return KW_I32; @@ -184,6 +184,7 @@ static Keyword builtin_type_to_kw(BuiltinType t) { static bool parse_type(Parser *p, Type *type) { Tokenizer *t = p->tokr; type->where = t->token->where; + type->flags = 0; switch (t->token->kind) { case TOKEN_KW: type->kind = TYPE_BUILTIN; @@ -220,6 +221,7 @@ static bool parse_type(Parser *p, Type *type) { if (t->token->kind == TOKEN_KW && t->token->kw <= KW_LAST_SYMBOL) { ret_type->kind = TYPE_VOID; + ret_type->flags = 0; } else { if (!parse_type(p, ret_type)) return false; @@ -430,7 +432,6 @@ static Token *expr_find_end(Parser *p, ExprEndKind ends_with) { static bool parse_expr(Parser *p, Expression *e, Token *end) { Tokenizer *t = p->tokr; if (end == NULL) return false; - e->flags = 0; e->where = t->token->where; if (end <= t->token) { tokr_err(t, "Empty expression."); @@ -450,9 +451,8 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { break; case NUM_LITERAL_INT: e->kind = EXPR_INT_LITERAL; - e->flags |= EXPR_FLAG_FLEXIBLE; e->type.kind = TYPE_BUILTIN; - e->type.builtin = BUILTIN_INT; /* TODO: if it's too big, use a u64 instead. */ + e->type.builtin = BUILTIN_I64; /* TODO: if it's too big, use a u64 instead. */ e->intl = num->intval; break; } @@ -7,8 +7,10 @@ main @= fn() { bar(); a : i64 = 5; b : float = 32.3; - c : i64 = a; + c : int = a; blah := 32; + asfdljk: float = 12.3; + asdkfjhakj : i8 = 1332948; }; @@ -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); |