diff options
-rw-r--r-- | abbrevs.txt | 1 | ||||
-rw-r--r-- | cgen.c | 61 | ||||
-rw-r--r-- | err.c | 10 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | parse.c | 11 | ||||
-rw-r--r-- | test.toc | 44 | ||||
-rw-r--r-- | tokenizer.c | 9 | ||||
-rw-r--r-- | types.c | 13 | ||||
-rw-r--r-- | types.h | 10 |
9 files changed, 98 insertions, 64 deletions
diff --git a/abbrevs.txt b/abbrevs.txt index 1075c21..5db40aa 100644 --- a/abbrevs.txt +++ b/abbrevs.txt @@ -1,6 +1,7 @@ allocr - allocator anon - anonymous arg - argument +ctx - context decl - declaration del - delete deref - dereference @@ -1141,65 +1141,50 @@ static bool cgen_val(CGenerator *g, Value *v, Type *t, Location where) { static bool cgen_decl(CGenerator *g, Declaration *d) { + int has_expr = d->flags & DECL_FLAG_HAS_EXPR; + bool is_tuple = d->type.kind == TYPE_TUPLE; if (cgen_fn_is_direct(g, d)) { if (!cgen_fn(g, &d->expr.fn, d->where)) return false; } else if ((d->flags & DECL_FLAG_CONST) || g->block == NULL) { - if (d->type.kind == TYPE_TUPLE) { - long idx = 0; - arr_foreach(d->idents, Identifier, i) { - if (!cgen_val_pre(g, &d->val.tuple[idx], &d->type.tuple[idx], d->where)) - return false; - if (g->block != NULL) - cgen_write(g, "static "); - if (!cgen_type_pre(g, &d->type.tuple[idx], d->where)) return false; - cgen_write(g, " "); - cgen_ident(g, *i); - if (!cgen_type_post(g, &d->type.tuple[idx], d->where)) return false; - cgen_write(g, " = "); - if (!cgen_val(g, &d->val.tuple[idx], &d->type.tuple[idx], d->where)) - return false; - idx++; - cgen_write(g, ";"); - cgen_nl(g); - } - } else { - if (!cgen_val_pre(g, &d->val, &d->type, d->where)) + /* declarations where we use a value */ + for (size_t idx = 0; idx < arr_len(d->idents); idx++) { + Identifier *i = &d->idents[idx]; + Type *type = is_tuple ? &d->type.tuple[idx] : &d->type; + Value *val = is_tuple ? &d->val.tuple[idx] : &d->val; + if (!cgen_val_pre(g, val, type, d->where)) return false; if (g->block != NULL) cgen_write(g, "static "); - if (!cgen_type_pre(g, &d->type, d->where)) return false; + if (!cgen_type_pre(g, type, d->where)) return false; cgen_write(g, " "); - cgen_ident(g, d->idents[0]); - if (!cgen_type_post(g, &d->type, d->where)) return false; - cgen_write(g, " = "); - if (!cgen_val(g, &d->val, &d->type, d->where)) - return false; + cgen_ident(g, *i); + if (!cgen_type_post(g, type, d->where)) return false; + if (has_expr) { + cgen_write(g, " = "); + if (!cgen_val(g, val, type, d->where)) + return false; + } cgen_write(g, ";"); cgen_nl(g); } } else { + /* declarations where we use an expression */ for (size_t idx = 0; idx < arr_len(d->idents); idx++) { Identifier *i = &d->idents[idx]; - Type *t = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type; - if (!cgen_type_pre(g, t, d->where)) return false; + Type *type = d->type.kind == TYPE_TUPLE ? &d->type.tuple[idx] : &d->type; + if (!cgen_type_pre(g, type, d->where)) return false; cgen_write(g, " "); cgen_ident(g, *i); - if (!cgen_type_post(g, t, d->where)) return false; - if (g->block == NULL && (d->flags & DECL_FLAG_HAS_EXPR)) { - cgen_write(g, " = "); - /* directly initialize iff we are in global scope */ - if (!cgen_expr(g, &d->expr)) - return false; - } else if (!(d->flags & DECL_FLAG_HAS_EXPR)) { + if (!cgen_type_post(g, type, d->where)) return false; + if (!has_expr) { cgen_write(g, " = "); - cgen_zero_value(g, t); + cgen_zero_value(g, type); } cgen_write(g, "; "); } - /* TODO: global tuples */ - if (g->block != NULL && (d->flags & DECL_FLAG_HAS_EXPR)) { + if (has_expr) { if (d->expr.type.kind == TYPE_TUPLE) { if (!cgen_set_tuple(g, NULL, d->idents, NULL, &d->expr)) return false; } else { @@ -38,15 +38,15 @@ static void err_vfprint(const char *fmt, va_list args) { } static void err_print_header_(Location where) { - err_fprint(TEXT_ERROR("error:") " at line %lu of %s:\n", (unsigned long)where.line, where.filename); + err_fprint(TEXT_ERROR("error:") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); } static void info_print_header_(Location where) { - err_fprint(TEXT_INFO("info:") " at line %lu of %s:\n", (unsigned long)where.line, where.filename); + err_fprint(TEXT_INFO("info:") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); } static void warn_print_header_(Location where) { - err_fprint(TEXT_WARN("warning:") " at line %lu of %s:\n", (unsigned long)where.line, where.filename); + err_fprint(TEXT_WARN("warning:") " at line %lu of %s:\n", (unsigned long)where.line, where.ctx->filename); } static void err_print_footer_(const char *context) { @@ -66,6 +66,7 @@ static void err_print_footer_(const char *context) { static void err_vprint(Location where, const char *fmt, va_list args) { + if (!where.ctx->enabled) return; err_print_header_(where); err_vfprint(fmt, args); err_print_footer_(where.code); @@ -73,6 +74,7 @@ static void err_vprint(Location where, const char *fmt, va_list args) { static void err_print_(int line, const char *file, Location where, const char *fmt, ...) { va_list args; + if (!where.ctx->enabled) return; if (file) err_fprint("Generated by line %d of %s:\n", line, file); va_start(args, fmt); @@ -84,6 +86,7 @@ static void err_print_(int line, const char *file, Location where, const char *f static void info_print(Location where, const char *fmt, ...) { va_list args; + if (!where.ctx->enabled) return; va_start(args, fmt); info_print_header_(where); err_vfprint(fmt, args); @@ -93,6 +96,7 @@ static void info_print(Location where, const char *fmt, ...) { static void warn_print(Location where, const char *fmt, ...) { va_list args; + if (!where.ctx->enabled) return; va_start(args, fmt); warn_print_header_(where); err_vfprint(fmt, args); @@ -54,7 +54,8 @@ int main(int argc, char **argv) { Identifiers file_idents; idents_create(&file_idents); Tokenizer t; - tokr_create(&t, &file_idents, in_filename); + ErrCtx err_ctx = {in_filename, true}; + tokr_create(&t, &file_idents, &err_ctx); if (!tokenize_string(&t, contents)) { err_fprint(TEXT_IMPORTANT("Errors occured while preprocessing.\n")); return EXIT_FAILURE; @@ -679,6 +679,17 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { tokr_err(t, "Empty expression."); return false; } + bool prev = t->err_ctx->enabled; + t->err_ctx->enabled = false; /* temporarily disable error context */ + Token *before = t->token; + if (parse_type(p, &e->typeval) && t->token == end) { + /* it's a type! */ + e->kind = EXPR_TYPE; + return true; + } + t->token = before; + t->err_ctx->enabled = prev; + if (end - t->token == 1) { /* 1-token expression */ switch (t->token->kind) { @@ -1,22 +1,34 @@ -puti @= fn(x: int) { - #C("printf(\"%ld\\n\", (long)x); -"); -}; +// puti @= fn(x: int) { +// #C("printf(\"%ld\\n\", (long)x); +// "); +// }; -putch @= fn(x: char) { - #C("printf(\"%c\\n\", x); -"); -}; +// putch @= fn(x: char) { +// #C("printf(\"%c\\n\", x); +// "); +// }; -putf @= fn(x: float) { - #C("printf(\"%f\\n\", (double)x); -"); -}; +// putf @= fn(x: float) { +// #C("printf(\"%f\\n\", (double)x); +// "); +// }; Foo @= int; +x, y : int; +a, b := 3, 5; +c: int; +d := 8; main @= fn() { - f := fn(x: int) { p := &x; *p = 5; }; - // f(3); - // x : Foo; -}; + x, y : int; + a, b := 3, 5; + c: int; + d := 8; +}; + +// main @= fn() { +// f := fn(x: int) { p := &x; *p = 5; }; +// x, y := 3; +// // f(3); +// // x : Foo; +// }; diff --git a/tokenizer.c b/tokenizer.c index 315379d..9997246 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -137,7 +137,7 @@ static char tokr_esc_seq(Tokenizer *t) { /* to be used during tokenization */ static void tokenization_err(Tokenizer *t, const char *fmt, ...) { va_list args; - Location where = {t->line, t->s, t->filename}; + Location where = {t->line, t->s, t->err_ctx}; va_start(args, fmt); err_vprint(where, fmt, args); va_end(args); @@ -153,6 +153,7 @@ static void tokenization_err(Tokenizer *t, const char *fmt, ...) { /* to be used after tokenization */ static void tokr_err_(const char *src_file, int src_line, Tokenizer *t, const char *fmt, ...) { + if (!t->token->where.ctx->enabled) return; err_fprint("At line %d of %s:\n", src_line, src_file); /* RELEASE: Remove this */ va_list args; va_start(args, fmt); @@ -164,7 +165,7 @@ static void tokr_err_(const char *src_file, int src_line, Tokenizer *t, const ch static void tokr_put_location(Tokenizer *tokr, Token *t) { t->where.line = tokr->line; t->where.code = tokr->s; - t->where.filename = tokr->filename; + t->where.ctx = tokr->err_ctx; } static void tokr_get_location(Tokenizer *tokr, Token *t) { @@ -172,12 +173,12 @@ static void tokr_get_location(Tokenizer *tokr, Token *t) { tokr->s = t->where.code; } -static void tokr_create(Tokenizer *t, Identifiers *idents, const char *filename) { +static void tokr_create(Tokenizer *t, Identifiers *idents, ErrCtx *err_ctx) { t->tokens = NULL; arr_resv(&t->tokens, 256); allocr_create(&t->allocr); t->idents = idents; - t->filename = filename; + t->err_ctx = err_ctx; } static inline void *tokr_malloc(Tokenizer *t, size_t bytes) { @@ -1139,6 +1139,19 @@ static bool types_decl(Typer *tr, Declaration *d) { d->flags |= DECL_FLAG_FOUND_VAL; } } + if (d->type.kind == TYPE_TUPLE) { + arr_foreach(d->type.tuple, Type, t) { + if (t->kind == TYPE_TYPE && !(d->flags & DECL_FLAG_CONST)) { + err_print(d->where, "Cannot declare non-constant type."); + return false; + } + } + } else { + if (d->type.kind == TYPE_TYPE && !(d->flags & DECL_FLAG_CONST)) { + err_print(d->where, "Cannot declare non-constant type."); + return false; + } + } } size_t n_idents = arr_len(d->idents); if (d->type.kind == TYPE_TUPLE) { @@ -31,10 +31,16 @@ typedef double F64; typedef U32 IdentID; /* identifier ID for cgen (anonymous variables) */ typedef uint32_t LineNo; + +typedef struct { + const char *filename; + bool enabled; +} ErrCtx; + typedef struct { LineNo line; char *code; - const char *filename; + ErrCtx *ctx; } Location; typedef struct Page { @@ -227,7 +233,7 @@ typedef struct { Allocator allocr; Token *tokens; char *s; /* string being parsed */ - const char *filename; + ErrCtx *err_ctx; LineNo line; Token *token; /* token currently being processed */ Identifiers *idents; |