diff --git a/ChangeLog b/ChangeLog index 6022bf6..2a7a2d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +Mon Feb 18 06:07:13 2008 Minero Aoki + + * net/loveruby/cflat/compiler/TypeChecker.java (mustBeScalar): + checks if type is an integer, a pointer, or an array (previous + #mustBeScalarAlike definition). + + * net/loveruby/cflat/compiler/TypeChecker.java + (expectsSameInteger, expectsComparableScalars): return immediately + after first error. + + * net/loveruby/cflat/compiler/TypeChecker.java (PrefixOpNode, + SuffixOpNode): allow array parameter. + + * net/loveruby/cflat/type/Type.java: new method #isScalar. + + * net/loveruby/cflat/type/IntegerType.java: is a scalar. + + * net/loveruby/cflat/type/ArrayType.java: is a scalar. + + * net/loveruby/cflat/type/PointerType.java: is a scalar. + Mon Feb 18 05:35:14 2008 Minero Aoki * net/loveruby/cflat/compiler/TypeChecker.java (checkCond): cond diff --git a/net/loveruby/cflat/compiler/TypeChecker.java b/net/loveruby/cflat/compiler/TypeChecker.java index d0139ca..54afbe6 100644 --- a/net/loveruby/cflat/compiler/TypeChecker.java +++ b/net/loveruby/cflat/compiler/TypeChecker.java @@ -106,7 +106,7 @@ class TypeChecker extends Visitor { } protected void checkCond(ExprNode cond) { - mustBeScalarAlike(cond, "condition expression"); + mustBeScalar(cond, "condition expression"); } public void visit(SwitchNode node) { @@ -301,15 +301,27 @@ class TypeChecker extends Visitor { // +, -, *, /, %, &, |, ^, <<, >> protected void expectsSameInteger(BinaryOpNode node) { - mustBeInteger(node.left(), node.operator()); - mustBeInteger(node.right(), node.operator()); + if (! node.left().type().isInteger()) { + wrongTypeError(node.left(), node.operator()); + return; + } + if (! node.right().type().isInteger()) { + wrongTypeError(node.right(), node.operator()); + return; + } insertImplicitCast(node); } // ==, !=, <, <=, >, >=, &&, || protected void expectsComparableScalars(BinaryOpNode node) { - mustBeScalarAlike(node.left(), node.operator()); - mustBeScalarAlike(node.right(), node.operator()); + if (! node.left().type().isScalar()) { + wrongTypeError(node.left(), node.operator()); + return; + } + if (! node.right().type().isScalar()) { + wrongTypeError(node.right(), node.operator()); + return; + } insertImplicitCast(node); } @@ -336,7 +348,7 @@ class TypeChecker extends Visitor { public void visit(UnaryOpNode node) { super.visit(node); if (node.operator().equals("!")) { - mustBeScalarAlike(node.expr(), node.operator()); + mustBeScalar(node.expr(), node.operator()); } else { mustBeInteger(node.expr(), node.operator()); @@ -346,13 +358,26 @@ class TypeChecker extends Visitor { // ++, -- public void visit(PrefixOpNode node) { super.visit(node); - mustBeScalar(node.expr(), node.operator()); + expectsScalarLHS(node.expr(), node.operator()); } // ++, -- public void visit(SuffixOpNode node) { super.visit(node); - mustBeScalar(node.expr(), node.operator()); + expectsScalarLHS(node.expr(), node.operator()); + } + + protected void expectsScalarLHS(ExprNode node, String op) { + if (node.isParameter()) { + // parameter is always a scalar. + } + else if (node.type().isArray()) { + // We cannot modify non-parameter array. + wrongTypeError(node, op); + } + else { + mustBeScalar(node, op); + } } /** @@ -407,29 +432,24 @@ class TypeChecker extends Visitor { return new CastNode(new TypeNode(t), n); } - protected void mustBeInteger(ExprNode node, String op) { - if (node.type().isInteger()) return; - notIntegerError(node, node.type(), op); + protected void mustBeInteger(ExprNode expr, String op) { + if (! expr.type().isInteger()) { + wrongTypeError(expr, op); + } } - protected void mustBeScalar(ExprNode node, String op) { - if (node.type().isInteger()) return; - if (node.type().isPointer()) return; - notIntegerError(node, node.type(), op); - } - - protected void mustBeScalarAlike(ExprNode node, String op) { - if (node.type().isInteger()) return; - if (node.type().isPointerAlike()) return; - notIntegerError(node, node.type(), op); + protected void mustBeScalar(ExprNode expr, String op) { + if (! expr.type().isScalar()) { + wrongTypeError(expr, op); + } } protected void incompatibleTypeError(Node n, Type l, Type r) { error(n, "incompatible type: " + l + " and " + r); } - protected void notIntegerError(Node n, Type type, String op) { - error(n, "wrong operand type for " + op + ": " + type); + protected void wrongTypeError(ExprNode expr, String op) { + error(expr, "wrong operand type for " + op + ": " + expr.type()); } protected void warn(Node n, String msg) { diff --git a/net/loveruby/cflat/type/ArrayType.java b/net/loveruby/cflat/type/ArrayType.java index 82531b3..44cb64e 100644 --- a/net/loveruby/cflat/type/ArrayType.java +++ b/net/loveruby/cflat/type/ArrayType.java @@ -21,6 +21,7 @@ public class ArrayType extends Type { public boolean isUnallocatedArray() { return !isAllocated(); } public boolean isDereferable() { return true; } public boolean isPointerAlike() { return isUnallocatedArray(); } + public boolean isScalar() { return true; } public Type baseType() { return baseType; diff --git a/net/loveruby/cflat/type/IntegerType.java b/net/loveruby/cflat/type/IntegerType.java index 975e61f..3175bfd 100644 --- a/net/loveruby/cflat/type/IntegerType.java +++ b/net/loveruby/cflat/type/IntegerType.java @@ -14,6 +14,7 @@ public class IntegerType extends Type { public boolean isInteger() { return true; } public boolean isSigned() { return isSigned; } + public boolean isScalar() { return true; } // Use default #equals //public boolean equals(Object other) diff --git a/net/loveruby/cflat/type/PointerType.java b/net/loveruby/cflat/type/PointerType.java index f096758..f13ad46 100644 --- a/net/loveruby/cflat/type/PointerType.java +++ b/net/loveruby/cflat/type/PointerType.java @@ -11,6 +11,7 @@ public class PointerType extends Type { public boolean isPointer() { return true; } public boolean isPointerAlike() { return true; } + public boolean isScalar() { return true; } public boolean isDereferable() { return true; } public boolean isCallable() { return baseType.isFunction(); } diff --git a/net/loveruby/cflat/type/Type.java b/net/loveruby/cflat/type/Type.java index f966078..6145a39 100644 --- a/net/loveruby/cflat/type/Type.java +++ b/net/loveruby/cflat/type/Type.java @@ -31,6 +31,7 @@ public abstract class Type { // Ability methods (unary) public boolean isDereferable() { return false; } public boolean isPointerAlike() { return false; } + public boolean isScalar() { return false; } public boolean isCallable() { return false; } // Ability methods (binary)