From 5665bde91427725cf0231cab7e54a6b37b6fba7f Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Fri, 3 Jan 2020 17:13:21 -0500 Subject: improved the way #sizeof and #alignof work --- cgen.c | 9 ++------- eval.c | 23 ++++------------------- package.c | 36 +++++++++++++++++++++++++++++++++--- test.toc | 9 ++------- types.c | 21 +++++++++++++-------- 5 files changed, 54 insertions(+), 44 deletions(-) diff --git a/cgen.c b/cgen.c index 5a6ed55..fd5b1a5 100644 --- a/cgen.c +++ b/cgen.c @@ -1399,13 +1399,6 @@ static bool cgen_expr(CGenerator *g, Expression *e) { cgen_indent(g); fwrite(code->val.slice.data, 1, (size_t)code->val.slice.n, cgen_writing_to(g)); } break; - case EXPR_DSIZEOF: - case EXPR_DALIGNOF: { - Value val; - if (!eval_expr(g->evalr, e, &val)) - return false; - cgen_write(g, I64_FMT, val.i64); - } break; case EXPR_CAST: { Type *from = &e->cast.expr->type; Type *to = &e->cast.type; @@ -1427,6 +1420,8 @@ static bool cgen_expr(CGenerator *g, Expression *e) { cgen_write(g, ")"); } } break; + case EXPR_DSIZEOF: + case EXPR_DALIGNOF: /* handled by types.c */ case EXPR_TUPLE: /* the only time this should happen is if you're stating a tuple, e.g. 3, 5;, but we've errored about that before diff --git a/eval.c b/eval.c index 4affb26..e1d199e 100644 --- a/eval.c +++ b/eval.c @@ -1366,25 +1366,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { case EXPR_C: err_print(e->where, "Cannot run C code at compile time."); return false; - case EXPR_DSIZEOF: - case EXPR_DALIGNOF: { - Expression *of = e->kind == EXPR_DSIZEOF ? e->dsizeof.of : e->dalignof.of; - Type *type; - if (of->type.kind == TYPE_TYPE) { - /* it's a type, return the size/align of it */ - Value typeval; - if (!eval_expr(ev, of, &typeval)) return false; - type = typeval.type; - if (!type_resolve(ev->typer, type, e->where)) return false; - } else { - /* it's an expression, return the size/align of its type */ - type = &of->type; - } - if (e->kind == EXPR_DSIZEOF) - v->i64 = (I64)compiler_sizeof(type); - else - v->i64 = (I64)compiler_alignof(type); - } break; case EXPR_NEW: /* it's not strictly necessary to do the if here */ if (e->new.n) { @@ -1542,6 +1523,10 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { case EXPR_VAL: *v = e->val; break; + case EXPR_DSIZEOF: + case EXPR_DALIGNOF: + assert(0); + return false; } return true; } diff --git a/package.c b/package.c index 71b6aef..0090ab5 100644 --- a/package.c +++ b/package.c @@ -205,12 +205,42 @@ static bool export_expr(Exporter *ex, Expression *e) { break; case EXPR_C: assert(e->c.code->kind == EXPR_VAL); - export_val(ex, e->c.code->val, &e->c.code->type, e->where); + if (!export_val(ex, e->c.code->val, &e->c.code->type, e->where)) + return false; break; case EXPR_IDENT: export_ident(ex, e->ident); break; - + case EXPR_UNARY_OP: + export_u8(ex, (U8)e->unary.op); + if (!export_expr(ex, e->unary.of)) + return false; + break; + case EXPR_BINARY_OP: + export_u8(ex, (U8)e->binary.op); + if (!export_expr(ex, e->binary.lhs) + || !export_expr(ex, e->binary.rhs)) + return false; + break; + case EXPR_VAL: + if (!export_val(ex, e->val, &e->type, e->where)) + return false; + break; + case EXPR_TUPLE: + if (!export_len16(ex, arr_len(e->tuple), "expressions in a tuple", e->where)) + return false; + arr_foreach(e->tuple, Expression, item) + if (!export_expr(ex, item)) + return false; + break; + case EXPR_TYPE: + if (!export_type(ex, &e->typeval, e->where)) + return false; + break; + case EXPR_DSIZEOF: + case EXPR_DALIGNOF: + assert(0); + break; } return true; } @@ -241,7 +271,7 @@ static bool export_decl(Exporter *ex, Declaration *d) { else if (d->flags & DECL_SEMI_CONST) constness = 2; export_u8(ex, constness); - U8 expr_kind = 0; + U8 expr_kind = DECL_EXPORT_NONE; if (d->flags & DECL_HAS_EXPR) expr_kind = DECL_EXPORT_EXPR; if (d->flags & DECL_FOUND_VAL) diff --git a/test.toc b/test.toc index b381fb5..fba8ffb 100644 --- a/test.toc +++ b/test.toc @@ -1,7 +1,2 @@ -// #export -foo :: f64 = 0.07321; -// asdf, dsajkhf, sadjkfh ::= 5; -// #export asdf ::= "asdfasdfasdf"; -// #export -zla, asdf := foo, 9; -asfdsfad ::= '\n'; \ No newline at end of file +#export asdf ::= int; +#export ghjk := #sizeof(asdf); \ No newline at end of file diff --git a/types.c b/types.c index 529eaaf..486dac5 100644 --- a/types.c +++ b/types.c @@ -1492,15 +1492,20 @@ static bool types_expr(Typer *tr, Expression *e) { code->kind = EXPR_VAL; t->kind = TYPE_UNKNOWN; } break; - case EXPR_DSIZEOF: { - if (!types_expr(tr, e->dsizeof.of)) - return false; - t->kind = TYPE_BUILTIN; - t->builtin = BUILTIN_I64; - } break; - case EXPR_DALIGNOF: { - if (!types_expr(tr, e->dalignof.of)) + case EXPR_DSIZEOF: + case EXPR_DALIGNOF: { + Expression *of = e->kind == EXPR_DSIZEOF ? e->dsizeof.of : e->dalignof.of; + if (!types_expr(tr, of)) return false; + if (e->dsizeof.of->type.kind == TYPE_TYPE) { + Value val; + if (!eval_expr(tr->evalr, of, &val)) + return false; + e->val.i64 = (I64)compiler_sizeof(val.type); + } else { + e->val.i64 = (I64)compiler_sizeof(&of->type); + } + e->kind = EXPR_VAL; t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_I64; } break; -- cgit v1.2.3