summaryrefslogtreecommitdiff
path: root/types.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-08-29 18:44:59 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-08-29 18:44:59 -0400
commita1e9fe04ad8384b6dfa9a99d10cf65630f299b10 (patch)
tree5e6a4fd4cbbfbce815940222f5e01e6b5e91b783 /types.c
parent7c790561cca382660081dfae3a6fe50fc31ad2a5 (diff)
More constant expressions
Diffstat (limited to 'types.c')
-rw-r--r--types.c82
1 files changed, 7 insertions, 75 deletions
diff --git a/types.c b/types.c
index 2bfbb6f..50815ac 100644
--- a/types.c
+++ b/types.c
@@ -48,78 +48,6 @@ static bool block_exit(Block *b) {
return ret;
}
-
-/* returns the number of characters written, not including the null character */
-static size_t type_to_str(Type *t, char *buffer, size_t bufsize) {
- switch (t->kind) {
- case TYPE_VOID:
- return str_copy(buffer, bufsize, "void");
- case TYPE_BUILTIN: {
- const char *s = keywords[builtin_type_to_kw(t->builtin)];
- return str_copy(buffer, bufsize, s);
- }
- case TYPE_FN: {
- /* number of chars written */
- size_t written = str_copy(buffer, bufsize, "fn (");
- Type *ret_type = t->fn.types.data;
- Type *param_types = ret_type + 1;
- size_t nparams = t->fn.types.len - 1;
- for (size_t i = 0; i < nparams; i++) {
- if (i > 0)
- written += str_copy(buffer + written, bufsize - written, ", ");
- written += type_to_str(&param_types[i], buffer + written, bufsize - written);
- }
- written += str_copy(buffer + written, bufsize - written, ")");
- if (ret_type->kind != TYPE_VOID) {
- written += str_copy(buffer + written, bufsize - written, " ");
- written += type_to_str(ret_type, buffer + written, bufsize - written);
- }
- return written;
- } break;
- case TYPE_ARR: {
- size_t written = str_copy(buffer, bufsize, "[");
- if (t->flags & TYPE_FLAG_RESOLVED) {
- snprintf(buffer + written, bufsize - written, INT_LITERAL_FMT, t->arr.n);
- written += strlen(buffer + written);
- } else {
- written += str_copy(buffer + written, bufsize - written, "N");
- }
- written += str_copy(buffer + written, bufsize - written, "]");
- written += type_to_str(t->arr.of, buffer + written, bufsize - written);
- return written;
- } break;
- }
-
- assert(0);
- 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) {
@@ -310,11 +238,15 @@ static bool type_of_expr(Expression *e, Type *t) {
static bool type_resolve(Type *t) {
if (t->flags & TYPE_FLAG_RESOLVED) return true;
switch (t->kind) {
- case TYPE_ARR:
+ case TYPE_ARR: {
/* it's an array */
if (!type_resolve(t->arr.of)) return false; /* resolve inner type */
- if (!eval_expr_as_int(t->arr.n_expr, &t->arr.n)) return false; /* resolve N */
- break;
+ Integer size;
+ if (!eval_expr_as_int(t->arr.n_expr, &size)) return false; /* resolve N */
+ if (size < 0)
+ err_print(t->arr.n_expr->where, "Negative array length (" INTEGER_FMT ")", size);
+ t->arr.n = (UInteger)size;
+ } break;
case TYPE_FN:
arr_foreach(&t->fn.types, Type, child_type) {
if (!type_resolve(child_type))