mirror of https://github.com/aamine/cbc
* 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:
parent
7e39838625
commit
80651a70cc
15
ChangeLog
15
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
// #@@}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue