diff options
-rw-r--r-- | cgen.c | 25 | ||||
-rw-r--r-- | decls_cgen.c | 19 | ||||
-rw-r--r-- | err.c | 4 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | identifiers.c | 28 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | parse.c | 2 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.c | 35 | ||||
-rw-r--r-- | types.h | 2 |
11 files changed, 61 insertions, 70 deletions
@@ -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); @@ -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); } } @@ -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); @@ -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 @@ -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)) @@ -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) { @@ -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); @@ -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; |