summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.sh2
-rw-r--r--decls_cgen.c4
-rw-r--r--main.c5
-rw-r--r--out.c5
-rw-r--r--parse.c5
-rw-r--r--test.toc8
-rw-r--r--types.c70
-rw-r--r--util/str.c9
8 files changed, 75 insertions, 33 deletions
diff --git a/build.sh b/build.sh
index 3c967db..32347fd 100755
--- a/build.sh
+++ b/build.sh
@@ -1,3 +1,3 @@
#!/bin/bash
CC=gcc
-$CC -o toc main.c -O0 -g -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Wno-unused-function -Wno-unused-parameter -std=c11 || exit 1
+$CC -o toc main.c -O0 -g -Wall -Wextra -Wpedantic -Wconversion -Wshadow -Wno-unused-function -std=c11 || exit 1
diff --git a/decls_cgen.c b/decls_cgen.c
index 0d9e5d1..6158ebe 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -1,5 +1,5 @@
/* C declarations of functions and global variables */
-static bool cgen_decl_fn(CGenerator *g, FnExpr *f, Location where) {
+static bool cgen_decl_fn(CGenerator *g, FnExpr *f) {
/* assign an ID to the function */
if (f->name && g->block == NULL) {
f->id = f->name->c_fn_reps++;
@@ -23,7 +23,7 @@ static bool cgen_decls_expr(CGenerator *g, Expression *e) {
} else {
g->writing_to = CGEN_WRITING_TO_C;
}
- if (!cgen_decl_fn(g, f, e->where))
+ if (!cgen_decl_fn(g, f))
return false;
g->writing_to = CGEN_WRITING_TO_C;
diff --git a/main.c b/main.c
index 0a3d00b..8f696b0 100644
--- a/main.c
+++ b/main.c
@@ -55,7 +55,10 @@ int main(int argc, char **argv) {
fprint_parsed_file(stdout, &f);
tokr_free(&t);
- types_file(&f);
+ if (!types_file(&f)) {
+ err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n"));
+ return EXIT_FAILURE;
+ }
/* TODO (eventually): use a tmp file (don't overwrite old output if there's an error) */
const char *c_out_filename = "out.c";
diff --git a/out.c b/out.c
index 35ba8a9..8e24986 100644
--- a/out.c
+++ b/out.c
@@ -9,9 +9,12 @@ void main__(void) {
void (*bar)(void) = a___1;
a___();
a___1();
+ int64_t a = 5;
+ float b = 32.300000;
+ int64_t c = a;
+ int64_t blah = 32;
}
static void a___(void) {
- void (*x)(void) = a___1;
}
static void a___1(void) {
}
diff --git a/parse.c b/parse.c
index 5e63e17..c934154 100644
--- a/parse.c
+++ b/parse.c
@@ -199,7 +199,7 @@ static bool parse_type(Parser *p, Type *type) {
tokr_err(t, "Expected ( for function type.");
return false;
}
- Type *ret_type = arr_add(&type->fn.types);
+ arr_add(&type->fn.types); /* add return type */
t->token++;
if (!token_is_kw(t->token, KW_RPAREN)) {
while (1) {
@@ -215,7 +215,7 @@ static bool parse_type(Parser *p, Type *type) {
}
}
t->token++; /* move past ) */
-
+ Type *ret_type = type->fn.types.data;
/* if there's a symbol, that can't be the start of a type */
if (t->token->kind == TOKEN_KW
&& t->token->kw <= KW_LAST_SYMBOL) {
@@ -447,7 +447,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
e->type.kind = TYPE_BUILTIN;
e->type.builtin = BUILTIN_FLOAT;
e->floatl = num->floatval;
- printf("%g\n",(double)e->floatl);
break;
case NUM_LITERAL_INT:
e->kind = EXPR_INT_LITERAL;
diff --git a/test.toc b/test.toc
index 547d731..16f5def 100644
--- a/test.toc
+++ b/test.toc
@@ -1,10 +1,14 @@
main @= fn() {
- foo @ fn() = fn() {x : fn() = bar;};
- bar : fn() = fn( ){};
+ foo @ fn() = fn() {};
+ bar : fn() = fn() {};
foo();
bar();
+ a : i64 = 5;
+ b : float = 32.3;
+ c : i64 = a;
+ blah := 32;
};
diff --git a/types.c b/types.c
index ffc0a8a..9eb2eb6 100644
--- a/types.c
+++ b/types.c
@@ -1,3 +1,4 @@
+/* pass NULL for file */
static bool block_enter(Block *b) {
bool ret = true;
arr_foreach(&b->stmts, Statement, stmt) {
@@ -71,7 +72,7 @@ static size_t type_to_string(Type *a, char *buffer, size_t bufsize) {
}
written += str_copy(buffer + written, bufsize - written, ")");
if (ret_type->kind != TYPE_VOID) {
- written += str_copy(buffer + written, bufsize - written, " ");
+ written += str_copy(buffer + written, bufsize - written, " ");
written += type_to_string(ret_type, buffer + written, bufsize - written);
}
return written;
@@ -86,11 +87,21 @@ static size_t type_to_string(Type *a, char *buffer, size_t bufsize) {
static bool type_eq(Type *a, Type *b) {
if (a->kind != b->kind) return false;
switch (a->kind) {
+ case TYPE_VOID: return true;
case TYPE_BUILTIN:
return a->builtin == b->builtin;
- /* TODO */
+ case TYPE_FN: {
+
+ if (a->fn.types.len != b->fn.types.len) return false;
+ Type *a_types = a->fn.types.data, *b_types = b->fn.types.data;
+ for (size_t i = 0; i < a->fn.types.len; i++)
+ if (!type_eq(&a_types[i], &b_types[i]))
+ return false;
+ return true;
}
- return true;
+ }
+ assert(0);
+ return false;
}
/* expected must equal got, or an error will be produced */
@@ -107,6 +118,8 @@ static bool type_must_eq(Location where, Type *expected, Type *got) {
}
static bool types_stmt(Statement *s);
+static bool types_decl(Declaration *d);
+
static bool types_expr(Expression *e) {
Type *t = &e->type;
@@ -121,7 +134,12 @@ static bool types_expr(Expression *e) {
Type *param_type = arr_add(&t->fn.types);
*param_type = param->type;
}
-
+ block_enter(&f->body);
+ arr_foreach(&f->body.stmts, Statement, s) {
+ if (!types_stmt(s))
+ return false;
+ }
+ block_exit(&f->body);
} break;
case EXPR_INT_LITERAL:
t->kind = TYPE_BUILTIN;
@@ -131,11 +149,34 @@ static bool types_expr(Expression *e) {
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_FLOAT;
break;
+ case EXPR_IDENT: {
+ IdentDecl *decl = ident_decl(e->ident);
+ if (!decl) {
+ char *s = ident_to_str(e->ident);
+ err_print(e->where, "Undeclared identifier: %s", s);
+ free(s);
+ }
+ *t = decl->decl->type;
+ } break;
/* TODO */
}
return true;
}
+static bool types_decl(Declaration *d) {
+ if (d->flags & DECL_FLAG_FOUND_TYPE) return true;
+ if (!types_expr(&d->expr)) return false;
+ if (d->flags & DECL_FLAG_INFER_TYPE) {
+ d->type = d->expr.type;
+ } else {
+ if (!type_must_eq(d->expr.where, &d->type, &d->expr.type)) {
+ return false;
+ }
+ }
+ d->flags |= DECL_FLAG_FOUND_TYPE;
+
+ return types_expr(&d->expr);
+}
static bool types_stmt(Statement *s) {
switch (s->kind) {
@@ -143,23 +184,10 @@ static bool types_stmt(Statement *s) {
if (!types_expr(&s->expr))
return false;
break;
- case STMT_DECL: {
- Declaration *d = &s->decl;
-
- if (d->flags & DECL_FLAG_FOUND_TYPE) return true;
- if (!types_expr(&d->expr)) return false;
- if (d->flags & DECL_FLAG_INFER_TYPE) {
- d->type = d->expr.type;
- } else {
- if (!type_must_eq(d->expr.where, &d->type, &d->expr.type)) {
- return false;
- }
- }
- d->flags |= DECL_FLAG_FOUND_TYPE;
-
- return types_expr(&d->expr);
- } break;
-
+ case STMT_DECL:
+ if (!types_decl(&s->decl))
+ return false;
+ break;
}
return true;
}
diff --git a/util/str.c b/util/str.c
index b05cc63..ac4fb26 100644
--- a/util/str.c
+++ b/util/str.c
@@ -6,13 +6,18 @@ destsz must be greater than 0.
*/
size_t str_copy(char *dest, size_t destsz, const char *src) {
assert(destsz);
+ if (!*src) {
+ *dest = 0;
+ return 0;
+ }
for (size_t i = 0; i < destsz-1; i++) {
+ *dest = *src;
if (!*src) {
*dest = 0;
return i;
}
- *dest++ = *src++;
+ src++; dest++;
}
- dest[destsz] = 0;
+ dest[destsz-1] = 0;
return destsz-1;
}