commit 7b85c1a71cc092ae3fddc1c82a55fcb3cc3fdac0
parent 26e5decafcdc1a186e85805033b1f4aedb0d8667
Author: m21c <ho*******@gmail.com>
Date: Tue, 5 Oct 2021 23:58:47 +0200
added type-check for if-clause
Diffstat:
| M | compiler.c | | | 128 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------- |
1 file changed, 91 insertions(+), 37 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -2905,58 +2905,90 @@ static Node *
conv(Node *node);
static Node *
-wrap(Type *ty, Node *node)
+wrap(Type *type, Node *node)
{
- assert(ty);
- assert(node->type);
+ Type *nodetype = node->type;
+
+ assert(type);
+ assert(nodetype);
- if (ty->kind == node->type->kind)
+ /* TODO(m21c): do proper type-check */
+ if (type->kind == nodetype->kind)
return node;
if (node->kind == 'N') {
/* TODO(m21c): layout correct type-conversions ? */
- if (isfloattype(node->type)) {
- if (isfloattype(ty)) {
+ if (isfloattype(nodetype)) {
+ if (isfloattype(type)) {
node->u.d = maskfloat(
- ty->size,
+ type->size,
node->u.d
);
- } else if (isinttype(ty)) {
+ } else if (isinttype(type)) {
node->u.u = maskint(
- ty->size,
+ type->size,
(int64_t) node->u.d
);
}
- } else if (isinttype(node->type)) {
- if (isfloattype(ty)) {
+ } else if (isinttype(nodetype)) {
+ if (isfloattype(type)) {
node->u.d = maskfloat(
- ty->size, (double)
+ type->size, (double)
(int64_t) convint(node->type->size,
!isunsignedtype(node->type),
node->u.u
)
);
- } else if (isinttype(ty)) {
+ } else if (isinttype(type)) {
node->u.u = maskint(
- ty->size,
+ type->size,
convint(
- node->type->size,
- !isunsignedtype(node->type),
+ nodetype->size,
+ !isunsignedtype(nodetype),
node->u.u
)
);
}
}
- node->type = ty;
+ node->type = type;
+ return node;
+ }
+
+ /* NOTE(m21c): no implicit (de-)referencing if the wrap-type is bool */
+ if (type->kind == TBOOL)
+ goto doconversion;
+
+ /* TODO(m21c): skip implicit (de-)referencing on arithmetic
+ * conversion, also skip if called from conv() */
+
+ /* implicit referencing: */
+ if (type->kind == TPTR && type->target->kind == nodetype->kind) {
+ node = makenode(node, node);
+ node->kind = OADDR;
+ node->type = type->target;
+
+ /* TODO(m21c): check for lvalue & maybe do further
+ * type-checks*/
+ return node;
+ }
+
+ /* implicit de-referencing: */
+ if (nodetype->kind == TPTR && nodetype->target->kind == type->kind) {
+ node = makenode(node, node);
+ node->kind = ODEREF;
+ node->type = type;
+
+ /* TODO(m21c): maybe do further type-checks*/
return node;
}
+doconversion:
node = makenode(node, node);
node->kind = ACONV;
- node->type = ty;
+ node->type = type;
return node;
}
@@ -3300,6 +3332,36 @@ typecheck(Env *env, Node *expr)
expr->rhs = wrap(expr->type, rhs);
return expr;
+ case AIF:
+ lhs = expr->lhs;
+ rhs = expr->rhs;
+
+ assert(expr->u.payload);
+ expr->u.payload = typecheck(env, expr->u.payload);
+ expr->u.payload = wrap(prim + TBOOL, expr->u.payload);
+
+ if (lhs)
+ expr->lhs = typecheck(env, lhs);
+
+ if (rhs)
+ expr->rhs = typecheck(env, lhs);
+
+ /* TODO(m21c): find a way how we do type-checking for the
+ * last expression in a statement-list, which
+ * might be needed by the enclosed statement-list
+ */
+
+ expr->type = prim + TVOID;
+ return expr;
+
+ case ASCOPE:
+ assert(expr->lhs);
+ assert(expr->u.env);
+
+ expr->lhs = typecheck(expr->u.env, expr->lhs);
+
+ return expr;
+
case ASTMT:
rhs = expr;
advancestmt:
@@ -3317,6 +3379,17 @@ typecheck(Env *env, Node *expr)
return expr;
+ case AADDR:
+ case ADEREF:
+ assert(expr->lhs);
+ expr->lhs = typecheck(env, expr->lhs);
+ expr->lhs = conv(expr->lhs);
+
+ return expr;
+
+ case 'I':
+ return resolvepending(env, expr);
+
joincomma:
lhs = expr->lhs;
rhs = expr->rhs;
@@ -3349,25 +3422,6 @@ typecheck(Env *env, Node *expr)
expr->type->u.rtarget = rhs->type;
return expr;
- case ASCOPE:
- assert(expr->lhs);
- assert(expr->u.env);
-
- expr->lhs = typecheck(expr->u.env, expr->lhs);
-
- return expr;
-
- case AADDR:
- case ADEREF:
- assert(expr->lhs);
- expr->lhs = typecheck(env, expr->lhs);
- expr->lhs = conv(expr->lhs);
-
- return expr;
-
- case 'I':
- return resolvepending(env, expr);
-
default:
return expr;
}