commit 195442a2e5a780e9f0f8a5ac8ef738ec2d4e7869
parent 258c09122a8b198a6f881306f03680c3612ede87
Author: m21c <ho*******@gmail.com>
Date: Thu, 7 Oct 2021 19:07:01 +0200
implemented keyword-operators sizeof, alignof, lengthof and bitcast (not fully)
Diffstat:
| M | compiler.c | | | 111 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- |
1 file changed, 105 insertions(+), 6 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -1852,6 +1852,7 @@ qualifiers(Source *source, int allowmask)
f = QCONST, m = 0;
break;
+ /* TODO(m21c): remove this */
case KVAR:
f = QVAR, m = ~(QTYPE | QINFER);
break;
@@ -2493,9 +2494,16 @@ readatom(Source *source, int flags)
case KALIGNOF:
case KSIZEOF:
+ case KLENGTHOF:
lhs = tokennode(source, NULL);
gettok(source);
- lhs->lhs = readatom(source, PRELAT);
+ if (getkind(source) == '(') {
+ gettok(source);
+ lhs->lhs = exprlist(source, false, NULL);
+ expect(source, ')', "expected ')'");
+ } else {
+ lhs->lhs = readatom(source, 0);
+ }
break;
case KBITCAST:
@@ -2504,7 +2512,7 @@ readatom(Source *source, int flags)
expect(source, '(', "expected '('");
lhs->rhs = exprlist(source, false, NULL);
expect(source, ')', "expected ')'");
- lhs->lhs = readatom(source, PRELAT);
+ lhs->lhs = readatom(source, 0);
break;
case KBREAK:
@@ -2602,6 +2610,9 @@ readatom(Source *source, int flags)
joinerror:
error(getloc(source), "expected expression");
lhs = tokennode(source, NULL);
+ lhs->kind = 'N';
+ lhs->type = prim + TERRTYPE;
+ lhs->u.u = 0;
gettok(source);
}
@@ -3431,6 +3442,39 @@ typecheck(Env *env, Node *expr)
expr->type->u.rtarget = rhs->type;
return expr;
+ case KBITCAST:
+ assert(lhs);
+ assert(rhs);
+
+ expr->lhs = lhs = typecheck(env, lhs);
+
+ if (lhs->type->kind == TERRTYPE)
+ return expr->type = prim + TERRTYPE, expr;
+
+ if (rhs->type->kind == TERRTYPE)
+ return expr->type = prim + TERRTYPE, expr;
+
+ if (rhs->kind != 'T') {
+ error(&rhs->loc, "expected type");
+ expr->type = prim + TERRTYPE;
+ return expr;
+ }
+
+ expr->type = rhs->type;
+ return expr;
+
+ case KSIZEOF:
+ case KALIGNOF:
+ case KLENGTHOF:
+ assert(lhs);
+ expr->lhs = lhs = typecheck(env, lhs);
+
+ if (lhs->type->kind == TERRTYPE)
+ return expr->type = prim + TERRTYPE, expr;
+
+ expr->type = prim + TUSIZE;
+ return expr;
+
default:
return expr;
}
@@ -3590,6 +3634,14 @@ foldexpr(Env *env, Node *expr)
return expr;
+ case ASCOPE:
+ assert(expr->lhs);
+ assert(expr->u.env);
+
+ expr->lhs = foldexpr(expr->u.env, expr->lhs);
+
+ return expr;
+
case ASTMT:
rhs = expr;
advancestmt:
@@ -3607,11 +3659,32 @@ foldexpr(Env *env, Node *expr)
expr->rhs = foldexpr(env, rhs);
return expr;
- case ASCOPE:
- assert(expr->lhs);
- assert(expr->u.env);
+ case KSIZEOF:
+ case KALIGNOF:
+ case KLENGTHOF:
+ assert(lhs);
- expr->lhs = foldexpr(expr->u.env, expr->lhs);
+ expr->lhs = NULL;
+ if (expr->kind == KSIZEOF) {
+ expr->u.u = lhs->type->size;
+
+ } else if (expr->kind == KALIGNOF) {
+ expr->u.u = lhs->type->align;
+
+ } else /* if (expr->kind == KLENGTHOF) */ {
+
+ /* TODO(m21c): add case for slice */
+ if (lhs->type->kind == TARRAY)
+ expr->u.u = lhs->type->u.array.length;
+ else if (lhs->type->kind == TPTR) {
+ expr->u.u = 1;
+ } else {
+ expr->u.u = 0;
+ }
+ }
+
+ /* delete(lhs); */
+ expr->kind = 'N';
return expr;
@@ -4261,6 +4334,32 @@ printexpr(FILE *out, Node *expr, int indent)
n += printsubexpr(out, expr->rhs, false, indent);
break;
+ case KSIZEOF:
+ case KALIGNOF:
+ case KLENGTHOF:
+ n += highlight(out, HLKEYWORD);
+ n += fprintf(out, "%s", nodestrings[expr->kind]);
+ n += highlight(out, HLDELIM);
+ n += fprintf(out, "(");
+ n += printexpr(out, expr->lhs, indent);
+ n += highlight(out, HLDELIM);
+ n += fprintf(out, ")");
+ break;
+
+ case KBITCAST:
+ n += highlight(out, HLKEYWORD);
+ n += fprintf(out, "bitcast");
+ n += highlight(out, HLDELIM);
+ n += fprintf(out, "(");
+ n += highlight(out, HLTYPE);
+ n += printtype(out, expr->rhs->type, indent);
+ n += highlight(out, HLDELIM);
+ n += fprintf(out, ") (");
+ n += printexpr(out, expr->lhs, indent);
+ n += highlight(out, HLDELIM);
+ n += fprintf(out, ")");
+ break;
+
case KRETURN:
n += highlight(out, HLKEYWORD);
n += fprintf(out, "return ");