* 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.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3915 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-02-17 21:07:15 +00:00
parent d1d388ab0c
commit 2568b19bdf
6 changed files with 68 additions and 23 deletions

View File

@ -1,3 +1,24 @@
Mon Feb 18 06:07:13 2008 Minero Aoki <aamine@loveruby.net>
* 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 <aamine@loveruby.net>
* net/loveruby/cflat/compiler/TypeChecker.java (checkCond): cond

View File

@ -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) {

View File

@ -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;

View File

@ -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)

View File

@ -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(); }

View File

@ -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)