summaryrefslogtreecommitdiff
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
parent38e5501205573597c6b8ef92e56ca76141b8e792 (diff)
added flexible numerical constants
-rw-r--r--base_cgen.c1
-rw-r--r--out.c2
-rw-r--r--parse.c14
-rw-r--r--test.toc4
-rw-r--r--types.c41
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";
diff --git a/out.c b/out.c
index 8e24986..60532ee 100644
--- a/out.c
+++ b/out.c
@@ -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) {
}
diff --git a/parse.c b/parse.c
index c934154..4bd7bae 100644
--- a/parse.c
+++ b/parse.c
@@ -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;
}
diff --git a/test.toc b/test.toc
index 16f5def..5631694 100644
--- a/test.toc
+++ b/test.toc
@@ -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;
};
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);