summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--abbrevs.txt1
-rw-r--r--cgen.c61
-rw-r--r--err.c10
-rw-r--r--main.c3
-rw-r--r--parse.c11
-rw-r--r--test.toc44
-rw-r--r--tokenizer.c9
-rw-r--r--types.c13
-rw-r--r--types.h10
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
diff --git a/cgen.c b/cgen.c
index 57eb93f..0cf65a7 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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 {
diff --git a/err.c b/err.c
index a8289cb..85d386a 100644
--- a/err.c
+++ b/err.c
@@ -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);
diff --git a/main.c b/main.c
index 87819ab..ea6e821 100644
--- a/main.c
+++ b/main.c
@@ -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;
diff --git a/parse.c b/parse.c
index 71936ba..73cbe80 100644
--- a/parse.c
+++ b/parse.c
@@ -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) {
diff --git a/test.toc b/test.toc
index 148b50a..652af26 100644
--- a/test.toc
+++ b/test.toc
@@ -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) {
diff --git a/types.c b/types.c
index 2d4e702..0acc468 100644
--- a/types.c
+++ b/types.c
@@ -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) {
diff --git a/types.h b/types.h
index 4265310..5faa096 100644
--- a/types.h
+++ b/types.h
@@ -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;