summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c25
-rw-r--r--decls_cgen.c19
-rw-r--r--err.c4
-rw-r--r--eval.c2
-rw-r--r--identifiers.c28
-rw-r--r--main.c4
-rw-r--r--parse.c2
-rw-r--r--test.toc8
-rw-r--r--tokenizer.c2
-rw-r--r--types.c35
-rw-r--r--types.h2
11 files changed, 61 insertions, 70 deletions
diff --git a/cgen.c b/cgen.c
index 9b4ff3a..bfcd389 100644
--- a/cgen.c
+++ b/cgen.c
@@ -224,12 +224,11 @@ static inline void cgen_nl(CGenerator *g) {
g->will_indent = true;
}
-static char *cgen_ident_to_str(Identifier i) {
- /* TODO: FIXME for unicode idents */
- return ident_to_str(i);
+static inline char *cgen_ident_to_str(Identifier i) {
+ return ident_to_str_reduced_charset(i);
}
-static void cgen_ident_id(CGenerator *g, IdentID id) {
+static inline void cgen_ident_id(CGenerator *g, IdentID id) {
cgen_write(g, "a%lu_", (unsigned long)id);
}
/* used for fields */
@@ -1896,7 +1895,8 @@ static bool cgen_val(CGenerator *g, Value v, Type *t, Location where) {
static bool cgen_decl(CGenerator *g, Declaration *d) {
if (d->flags & DECL_FOREIGN)
return true; /* already dealt with */
-
+ if (g->block == NULL && g->fn == NULL)
+ return true; /* already dealt with */
int has_expr = d->flags & DECL_HAS_EXPR;
if (cgen_fn_is_direct(g, d))
return true; /* dealt with in cgen_defs_ */
@@ -1909,8 +1909,6 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
continue;
}
Value *val = decl_val_at_index(d, idx);
- if (g->block == NULL && g->fn == NULL)
- cgen_write(g, "static ");
if (has_expr) {
if (!cgen_val_pre(g, *val, type, d->where))
return false;
@@ -1936,7 +1934,6 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
for (int idx = 0; idx < nidents; ++idx) {
Identifier i = d->idents[idx];
Type *type = decl_type_at_index(d, idx);
- if (g->block == NULL && g->fn == NULL) cgen_write(g, "static ");
if (!cgen_type_pre(g, type, d->where)) return false;
cgen_write(g, " ");
cgen_ident(g, i);
@@ -2013,8 +2010,7 @@ static bool cgen_ret(CGenerator *g, Expression *ret) {
cgen_write(g, "return ");
if (!cgen_expr(g, ret)) return false;
}
- cgen_write(g, ";");
- cgen_nl(g);
+ cgen_writeln(g, ";");
return true;
}
@@ -2030,10 +2026,11 @@ static bool cgen_stmt(CGenerator *g, Statement *s) {
if (!cgen_decl(g, s->decl)) return false;
break;
case STMT_EXPR:
- if (!cgen_expr_pre(g, &s->expr)) return false;
- if (!cgen_expr(g, &s->expr)) return false;
- cgen_write(g, ";");
- cgen_nl(g);
+ if (!type_is_compileonly(&s->expr.type)) {
+ if (!cgen_expr_pre(g, &s->expr)) return false;
+ if (!cgen_expr(g, &s->expr)) return false;
+ cgen_writeln(g, ";");
+ }
break;
case STMT_RET: {
unsigned has_expr = s->ret.flags & RET_HAS_EXPR;
diff --git a/decls_cgen.c b/decls_cgen.c
index d5a2836..5b9bde2 100644
--- a/decls_cgen.c
+++ b/decls_cgen.c
@@ -202,17 +202,14 @@ static bool cgen_decls_decl(CGenerator *g, Declaration *d) {
cgen_ident(g, ident);
if (!cgen_type_post(g, type, d->where))
return false;
- if (g->block) {
- assert(g->block->flags & BLOCK_IS_NMS);
- if (d->flags & DECL_HAS_EXPR) {
- Value *val = decl_val_at_index(d, i);
- cgen_write(g, " = ");
- if (!cgen_val(g, *val, type, d->where))
- return false;
- } else {
- cgen_write(g, " = ");
- cgen_zero_value(g, type);
- }
+ if (d->flags & DECL_HAS_EXPR) {
+ Value *val = decl_val_at_index(d, i);
+ cgen_write(g, " = ");
+ if (!cgen_val(g, *val, type, d->where))
+ return false;
+ } else {
+ cgen_write(g, " = ");
+ cgen_zero_value(g, type);
}
cgen_write(g, ";");
cgen_nl(g);
diff --git a/err.c b/err.c
index e0aab89..a40499e 100644
--- a/err.c
+++ b/err.c
@@ -114,11 +114,11 @@ static void warn_print_header_(Location where) {
static void err_print_footer_(Location where, bool show_ctx_stack) {
ErrCtx *ctx = where.file->ctx;
- err_fprint(ctx, "\n");
+ err_fprint(ctx, "\n\t");
print_location_highlight(err_ctx_file(ctx), where);
if (ctx && show_ctx_stack) {
arr_foreach(ctx->instance_stack, Location, inst) {
- err_fprint(ctx, "While generating the instance of a function\n");
+ err_fprint(ctx, "While generating the instance of a function\n\t");
print_location_highlight(err_ctx_file(ctx), *inst);
}
}
diff --git a/eval.c b/eval.c
index 6f6412a..748fc52 100644
--- a/eval.c
+++ b/eval.c
@@ -777,7 +777,7 @@ static void *eval_ptr_to_struct_field(Evaluator *ev, Expression *dot_expr) {
} else {
void *ptr;
assert(type_is_builtin(struct_type, BUILTIN_NMS));
- Identifier translated = ident_translate(dot_expr->binary.rhs->ident, &dot_expr->binary.lhs->val.nms->idents);
+ Identifier translated = dot_expr->binary.dot.translated_ident;
if (!eval_address_of_ident(translated, &dot_expr->type, dot_expr->where, &ptr)) {
return NULL;
}
diff --git a/identifiers.c b/identifiers.c
index 73bc413..370ad7d 100644
--- a/identifiers.c
+++ b/identifiers.c
@@ -136,13 +136,39 @@ static void fprint_ident_reduced_charset(FILE *out, Identifier id) {
for (const char *s = id->str; is_ident(*s); ++s) {
int c = (unsigned char)(*s);
if (c > 127) {
- fprintf(out, "x__%x", c);
+ fprintf(out, "x__%02x", c);
} else {
putc(*s, out);
}
}
}
+static char *ident_to_str_reduced_charset(Identifier id) {
+ assert(id);
+ size_t nchars = 0;
+ for (const char *s = id->str; is_ident(*s); ++s) {
+ int c = (unsigned char)(*s);
+ if (c > 127)
+ nchars += 5;
+ else
+ ++nchars;
+ }
+ char *ret = err_malloc(nchars+1);
+ char *p = ret;
+ for (const char *s = id->str; is_ident(*s); ++s) {
+ int c = (unsigned char)(*s);
+ if (c > 127)
+ sprintf(p, "x__%02x", c);
+ else
+ *p = (char)c;
+ ++p;
+ }
+ *p = 0;
+ assert(p == ret + nchars);
+ return ret;
+}
+
+
/* NULL = no such identifier. returns identifier "foo" for both "foo\0" and "foo+92384324..." */
static Identifier ident_get(Identifiers *ids, char *s) {
size_t len = ident_str_len(s);
diff --git a/main.c b/main.c
index c648cd3..3e990ff 100644
--- a/main.c
+++ b/main.c
@@ -18,14 +18,13 @@
/*
TODO:
-the problem right now is that we're copying blocks but not updating our references to the copy
make eval_ptr_to_struct_field return a bool (just in case it successfully returns a NULL pointer)
nms["foo"]
make sure #export still works properly
fix cgen_ident_to_str for unicode idents
check for leaks
---
-error about statements of expression with compile-only types (e.g. int;)
+warn about non-anonymous namespace statements of expression with compile-only types (e.g. int;)
allow for circular dependencies in functions returning types---this will be complicated
foo, _ := bar();
nice syntax for #including something into a namespace
@@ -35,6 +34,7 @@ constants in structs
#if
variadic fns
+switch to / add as an alternative: libffi
---
X ::= newtype(int); or something
diff --git a/parse.c b/parse.c
index 397666a..7d13602 100644
--- a/parse.c
+++ b/parse.c
@@ -1082,8 +1082,6 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) {
}
case KW_NMS: {
Namespace *n = &e->nms;
- idents_create(&n->idents, p->allocr, p->block);
-
e->kind = EXPR_NMS;
++t->token;
if (!parse_block(p, &n->body, 0))
diff --git a/test.toc b/test.toc
index 05b3095..767ef38 100644
--- a/test.toc
+++ b/test.toc
@@ -1,7 +1,5 @@
-foo ::= nms {
- bar ::= 5;
+
+nms {
+ x := 1;
};
-main ::= fn() {
- foo.bar;
-}; \ No newline at end of file
diff --git a/tokenizer.c b/tokenizer.c
index d1b5921..5a7e272 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -200,7 +200,7 @@ static void tokenization_err_(
err_fprint(ctx, " at line %lu of %s:\n", (unsigned long)t->line, t->file->filename);
err_vfprint(ctx, fmt, args);
va_end(args);
- err_fprint(ctx, "\n");
+ err_fprint(ctx, "\n\t");
U32 pos = (U32)(t->s - t->file->contents);
print_pos_highlight(err_ctx_file(ctx), ctx, t->file, pos, pos + 1);
while (*t->s) {
diff --git a/types.c b/types.c
index 9cedc5f..4483d2e 100644
--- a/types.c
+++ b/types.c
@@ -372,6 +372,7 @@ static bool type_of_fn(Typer *tr, FnExpr *f, Type *t, U16 flags) {
static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t) {
t->flags = 0;
Identifier i = *ident;
+#if 0
#ifdef TOC_DEBUG
if (i->idents->scope != tr->block) {
printf("Ident declaration mismatch for this ident:\n");
@@ -385,6 +386,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier *ident, Type *t)
#else
assert(i->idents->scope == tr->block);
#endif
+#endif
if (i->decl_kind == IDECL_NONE) {
long nblocks = (long)arr_len(tr->blocks);
long idx;
@@ -1066,31 +1068,6 @@ static char *eval_expr_as_cstr(Typer *tr, Expression *e, const char *what_is_thi
return str;
}
-static bool nms_translate_idents_in_stmts(Namespace *nms, Statement *stmts) {
- arr_foreach(stmts, Statement, s) {
- switch (s->kind) {
- case STMT_INCLUDE:
- if (!nms_translate_idents_in_stmts(nms, s->inc.stmts))
- return false;
- break;
- case STMT_DECL: {
- Declaration *d = s->decl;
- arr_foreach(d->idents, Identifier, i) {
- *i = ident_translate_forced(*i, &nms->idents);
- }
- } break;
- case STMT_EXPR:
- case STMT_RET:
- err_print(s->where, "Only declarations can appear in namespaces.");
- return false;
- }
- }
- return true;
-}
-
-static inline bool nms_translate_idents(Namespace *nms) {
- return nms_translate_idents_in_stmts(nms, nms->body.stmts);
-}
static bool types_expr(Typer *tr, Expression *e) {
if (e->flags & EXPR_FOUND_TYPE) return true;
@@ -2128,17 +2105,17 @@ static bool types_expr(Typer *tr, Expression *e) {
Namespace *nms = nms_val.nms;
lhs->kind = EXPR_VAL;
lhs->val.nms = nms;
- Identifier translated = ident_translate(rhs->ident, &nms->idents);
+ Identifier translated = ident_translate(rhs->ident, &nms->body.idents);
if (!translated) {
char *s = ident_to_str(rhs->ident);
err_print(rhs->where, "%s is not a member of this namespace.", s);
return false;
}
+ assert(translated->decl_kind != IDECL_NONE);
if (!type_of_ident(tr, rhs->where, &translated, t)) {
return false;
}
- e->kind = EXPR_IDENT;
- e->ident = translated;
+ e->binary.dot.translated_ident = translated;
} else {
char *s = type_to_str(lhs_type);
err_print(e->where, "Operator . applied to type %s, which is not a structure or pointer to structure.", s);
@@ -2196,8 +2173,6 @@ static bool types_expr(Typer *tr, Expression *e) {
e->nms.associated_ident = NULL; /* set when we type the declaration */
t->kind = TYPE_BUILTIN;
t->builtin = BUILTIN_NMS;
- if (!nms_translate_idents(&e->nms))
- return false;
} break;
case EXPR_VAL:
assert(0);
diff --git a/types.h b/types.h
index 446de4c..c81fdfa 100644
--- a/types.h
+++ b/types.h
@@ -700,7 +700,6 @@ const char *const builtin_val_names[BUILTIN_VAL_COUNT] =
typedef struct Namespace {
Block body;
- Identifiers idents;
Identifier associated_ident; /* if this is foo ::= nms { ... }, then associated_ident is foo; can be NULL */
struct {
IdentID id; /* used as prefix if prefix is NULL */
@@ -733,6 +732,7 @@ typedef struct Expression {
struct Expression *rhs;
union {
Field *field; /* for struct. */
+ Identifier translated_ident; /* for nms. */
} dot;
} binary;
CallExpr call;