diff options
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | decls_cgen.c | 4 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | out.c | 5 | ||||
-rw-r--r-- | parse.c | 5 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | types.c | 70 | ||||
-rw-r--r-- | util/str.c | 9 |
8 files changed, 75 insertions, 33 deletions
@@ -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; @@ -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"; @@ -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) { } @@ -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; @@ -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; }; @@ -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; } @@ -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; } |