* net/loveruby/cflat/compiler/TypeChecker.java: ptr==ptr should work.

* net/loveruby/cflat/compiler/TypeChecker.java: ptr&&ptr should work.
* net/loveruby/cflat/compiler/TypeChecker.java: any==any should always returns int.
* net/loveruby/cflat/compiler/CodeGenerator.java: ditto.
* test: test it.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3975 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-08-30 11:07:44 +00:00
parent 7e39838625
commit 80651a70cc
11 changed files with 86 additions and 40 deletions

View File

@ -1,3 +1,18 @@
Sat Aug 30 20:07:18 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/TypeChecker.java: ptr==ptr should
work.
* net/loveruby/cflat/compiler/TypeChecker.java: ptr&&ptr should
work.
* net/loveruby/cflat/compiler/TypeChecker.java: any==any should
always returns int.
* net/loveruby/cflat/compiler/CodeGenerator.java: ditto.
* test: test it.
Sat Aug 30 18:00:17 2008 Minero Aoki <aamine@loveruby.net>
* test/test_cbc.sh: test overrapped lvar.

View File

@ -598,7 +598,7 @@ static public void p(String s) { System.err.println(s); }
else {
// Comparison operators
cmp(t, reg("cx", t), reg("ax", t));
if (t.isSigned()) {
if (!t.isPointer() && t.isSigned()) {
if (op.equals("==")) sete (al());
else if (op.equals("!=")) setne(al());
else if (op.equals(">")) setg (al());

View File

@ -229,7 +229,8 @@ class TypeChecker extends Visitor {
super.visit(node);
if (node.operator().equals("+")
|| node.operator().equals("-")) {
expectsSameIntegerOrPointerDiff(node);
Type t = expectsSameIntegerOrPointerDiff(node);
if (t != null) node.setType(t);
}
else if (node.operator().equals("*")
|| node.operator().equals("/")
@ -239,7 +240,8 @@ class TypeChecker extends Visitor {
|| node.operator().equals("^")
|| node.operator().equals("<<")
|| node.operator().equals(">>")) {
expectsSameInteger(node);
Type t = expectsSameInteger(node);
if (t != null) node.setType(t);
}
else if (node.operator().equals("==")
|| node.operator().equals("!=")
@ -247,7 +249,8 @@ class TypeChecker extends Visitor {
|| node.operator().equals("<=")
|| node.operator().equals(">")
|| node.operator().equals(">=")) {
expectsComparableScalars(node);
Type t = expectsComparableScalars(node);
if (t != null) node.setType(t);
}
else {
throw new Error("unknown binary operator: " + node.operator());
@ -257,12 +260,14 @@ class TypeChecker extends Visitor {
public void visit(LogicalAndNode node) {
super.visit(node);
expectsComparableScalars(node);
Type t = expectsComparableScalars(node);
if (t != null) node.setType(t);
}
public void visit(LogicalOrNode node) {
super.visit(node);
expectsComparableScalars(node);
Type t = expectsComparableScalars(node);
if (t != null) node.setType(t);
}
/**
@ -272,51 +277,62 @@ class TypeChecker extends Visitor {
* * pointer + integer
* * integer + pointer
*/
protected void expectsSameIntegerOrPointerDiff(BinaryOpNode node) {
protected Type expectsSameIntegerOrPointerDiff(BinaryOpNode node) {
if (node.left().type().isPointer()) {
mustBeInteger(node.right(), node.operator());
node.setType(node.left().type());
return node.left().type();
}
else if (node.right().type().isPointer()) {
mustBeInteger(node.left(), node.operator());
node.setType(node.right().type());
return node.right().type();
}
else {
expectsSameInteger(node);
return expectsSameInteger(node);
}
}
// +, -, *, /, %, &, |, ^, <<, >>
// #@@range/expectsSameInteger{
protected void expectsSameInteger(BinaryOpNode node) {
if (! node.left().type().isInteger()) {
wrongTypeError(node.left(), node.operator());
return;
}
if (! node.right().type().isInteger()) {
wrongTypeError(node.right(), node.operator());
return;
}
arithmeticImplicitCast(node);
protected Type expectsSameInteger(BinaryOpNode node) {
if (! mustBeInteger(node.left(), node.operator())) return null;
if (! mustBeInteger(node.right(), node.operator())) return null;
return arithmeticImplicitCast(node);
}
// #@@}
// ==, !=, <, <=, >, >=, &&, ||
protected void expectsComparableScalars(BinaryOpNode node) {
if (! node.left().type().isScalar()) {
wrongTypeError(node.left(), node.operator());
return;
// ==, !=, >, >=, <, <=, &&, ||
protected Type expectsComparableScalars(BinaryOpNode node) {
if (! mustBeScalar(node.left(), node.operator())) return null;
if (! mustBeScalar(node.right(), node.operator())) return null;
if (node.left().type().isPointer()) {
ExprNode right = forcePointerType(node.left(), node.right());
node.setRight(right);
return node.left().type();
}
if (! node.right().type().isScalar()) {
wrongTypeError(node.right(), node.operator());
return;
if (node.right().type().isPointer()) {
ExprNode left = forcePointerType(node.right(), node.left());
node.setLeft(left);
return node.right().type();
}
return arithmeticImplicitCast(node);
}
// cast slave node to master node.
protected ExprNode forcePointerType(ExprNode master, ExprNode slave) {
if (master.type().isCompatible(slave.type())) {
// needs no cast
return slave;
}
else {
warn(slave, "incompatible implicit cast from "
+ slave.type() + " to " + master.type());
return new CastNode(master.type(), slave);
}
arithmeticImplicitCast(node);
}
// Processes usual arithmetic conversion for binary operations.
// #@@range/arithmeticImplicitCast{
protected void arithmeticImplicitCast(BinaryOpNode node) {
protected Type arithmeticImplicitCast(BinaryOpNode node) {
Type r = integralPromotion(node.right().type());
Type l = integralPromotion(node.left().type());
Type target = usualArithmeticConversion(l, r);
@ -328,7 +344,7 @@ class TypeChecker extends Visitor {
// insert cast on right expr
node.setRight(new CastNode(target, node.right()));
}
node.setType(target);
return target;
}
// #@@}

View File

@ -19,7 +19,7 @@ main(int argc, char **argv)
addr2 = &i;
}
printf(";%d", i);
printf(";%s", (unsigned long)addr1 == (unsigned long)addr2 ? "OK" : "NG");
printf(";%s", addr1 == addr2 ? "OK" : "NG");
puts("");
return 0;

View File

@ -7,6 +7,7 @@ main(int argc, char **argv)
printf(";%s", 0 ? "NG" : "OK");
printf(";%s", 0==0 ? "OK" : "NG");
printf(";%s", 0==1 ? "NG" : "OK");
printf(";%s", 0==1 ? (void*)0 : "OK");
puts("");
return 0;
}

View File

@ -3,7 +3,11 @@ import stdio;
int
main(int argc, char **argv)
{
char *s = "OK";
char *t = "??";
printf("%d;%d;%d", (5 == 3), (5 == 5), (3 == 5));
printf(";%d;%d;%d", (s == t), (s == s), (t == s));
puts("");
return 0;
}

View File

@ -3,6 +3,8 @@ import stdio;
int
main(int argc, char **argv)
{
printf("%d;%d;%d;%d\n", 0&&0, 1&&0, 0&&1, 1&&2);
printf("%d;%d;%d;%d", 0&&0, 1&&0, 0&&1, 1&&2);
printf(";%s", ("NG" && "OK"));
puts("");
return 0;
}

View File

@ -4,6 +4,8 @@ int
main(int argc, char **argv)
{
printf("%d;%d;%d", !0, !1, !2);
printf(";%d", !"str");
printf(";%d", !(void*)0);
puts("");
return 0;
}

View File

@ -3,6 +3,8 @@ import stdio;
int
main(int argc, char **argv)
{
printf("%d;%d;%d;%d\n", 0||0, 1||0, 0||1, 1||2);
printf("%d;%d;%d;%d", 0||0, 1||0, 0||1, 1||2);
printf(";%s", (void*)0 || "OK");
puts("");
return 0;
}

View File

@ -3,7 +3,11 @@ import stdio;
int
main(int argc, char **argv)
{
char *s = "OK";
char *t = "??";
printf("%d;%d;%d", (5 != 3), (5 != 5), (3 != 5));
printf(";%d;%d;%d", (s != t), (s != s), (t != s));
puts("");
return 0;
}

View File

@ -85,8 +85,8 @@ test_08_bitop() {
}
test_09_cmp() {
assert_out "0;1;0" ./eq
assert_out "1;0;1" ./neq
assert_out "0;1;0;0;1;0" ./eq
assert_out "1;0;1;1;0;1" ./neq
assert_out "1;0;0" ./gt
assert_out "0;0;1" ./lt
assert_out "1;1;0" ./gteq
@ -106,10 +106,10 @@ test_12_if() {
}
test_13_logical() {
assert_out "1;0;0" ./logicalnot
assert_out "OK;OK;OK;OK" ./condexpr
assert_out "0;0;0;2" ./logicaland
assert_out "0;1;1;1" ./logicalor
assert_out "1;0;0;0;1" ./logicalnot
assert_out "OK;OK;OK;OK;OK" ./condexpr
assert_out "0;0;0;2;OK" ./logicaland
assert_out "0;1;1;1;OK" ./logicalor
}
test_14_while() {