diff --git a/ChangeLog b/ChangeLog index 0a3c501..e08b7bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Sun Sep 7 07:37:34 2008 Minero Aoki + + * net/loveruby/cflat/compiler/CodeGenerator.java: opassign should + not spill DX because division uses DX. + + * net/loveruby/cflat/ast/PtrMemberNode.java: #dereferedType should + return Type instead of ComplexType because DereferenceChecker + checks derefered type by this method. + + * test: test ptr->memb with complex pointer expression. + Sun Sep 7 06:50:56 2008 Minero Aoki * net/loveruby/cflat/compiler/CodeGenerator.java: calculate LHS diff --git a/net/loveruby/cflat/ast/PtrMemberNode.java b/net/loveruby/cflat/ast/PtrMemberNode.java index 3c7f5ff..52310cb 100644 --- a/net/loveruby/cflat/ast/PtrMemberNode.java +++ b/net/loveruby/cflat/ast/PtrMemberNode.java @@ -13,10 +13,10 @@ public class PtrMemberNode extends ExprNode { } public Type type() { - return dereferedType().memberType(member); + return dereferedComplexType().memberType(member); } - public ComplexType dereferedType() { + public ComplexType dereferedComplexType() { try { PointerType pt = expr.type().getPointerType(); return pt.baseType().getComplexType(); @@ -26,6 +26,16 @@ public class PtrMemberNode extends ExprNode { } } + public Type dereferedType() { + try { + PointerType pt = expr.type().getPointerType(); + return pt.baseType(); + } + catch (ClassCastException err) { + throw new SemanticError(err.getMessage()); + } + } + public ExprNode expr() { return expr; } @@ -47,7 +57,7 @@ public class PtrMemberNode extends ExprNode { } public long offset() { - return dereferedType().memberOffset(member); + return dereferedComplexType().memberOffset(member); } public Location location() { diff --git a/net/loveruby/cflat/compiler/CodeGenerator.java b/net/loveruby/cflat/compiler/CodeGenerator.java index 906b432..7bbc38d 100644 --- a/net/loveruby/cflat/compiler/CodeGenerator.java +++ b/net/loveruby/cflat/compiler/CodeGenerator.java @@ -766,11 +766,12 @@ public class CodeGenerator extends Visitor { else { push(reg("ax")); compileLHS(node.lhs()); -//FIXME: DANGER mov(reg("ax"), reg("dx")); load(node.type(), mem(reg("dx")), reg("ax")); pop(reg("cx")); + push(reg("dx")); compileBinaryOp(node.operator(), node.type()); + pop(reg("dx")); save(node.type(), reg("ax"), mem(reg("dx"))); } } diff --git a/test/opassign.cb b/test/opassign.cb index de474f2..0150bba 100644 --- a/test/opassign.cb +++ b/test/opassign.cb @@ -58,6 +58,35 @@ main(int argc, char **argv) printf(";%d", *p); } + // complex LHS + { + int x = 0; + int *p = &x; + + *p += 1; + printf(";%d", *p); + + p[0] += 2; + printf(";%d", *p); + + *&*p += 3; + printf(";%d", *p); + } + + // complex LHS #2 + { + int[2] a; + + a[0] = 77; + a[1] = 78; + + a[0] += 5; + printf(";%d", a[0]); + + *(a + 1) += 3; + printf(";%d", a[1]); + } + puts(""); return 0; } diff --git a/test/ptrmemb.cb b/test/ptrmemb.cb index 3ceff13..2d733ef 100644 --- a/test/ptrmemb.cb +++ b/test/ptrmemb.cb @@ -32,7 +32,20 @@ main(int argc, char **argv) (*uptr).x = 6; printf(";%d", (*uptr).y); + printf(";%d", f()->x); + printf(";%d", f()->y); + puts(""); return 0; } + +static struct s ss; + +struct s * +f(void) +{ + ss.x = 77; + ss.y = 78; + return &ss; +} diff --git a/test/test_cbc.sh b/test/test_cbc.sh index 244eddd..ceeb5b0 100644 --- a/test/test_cbc.sh +++ b/test/test_cbc.sh @@ -93,7 +93,7 @@ test_09_cmp() { test_10_assign() { assert_out "1;2;2;3;4;5;6;7;8;8;9;10;11;777;S;12" ./assign - assert_out "3;4;3;12;4;1;1;7;5;1;4;e;H;76;75" ./opassign + assert_out "3;4;3;12;4;1;1;7;5;1;4;e;H;76;75;1;3;6;82;81" ./opassign assert_out "0;1;2;2;3;3;4" ./inc assert_out "4;3;2;2;1;1;0" ./dec } @@ -186,7 +186,7 @@ test_22_pointer() { assert_out "777" ./pointer2 assert_out "1;777;3;4;1;777;3;4" ./pointer3 assert_out "777" ./pointer4 - assert_out "1;2;3;4;5;6" ./ptrmemb + assert_out "1;2;3;4;5;6;77;78" ./ptrmemb assert_compile_error deref-semcheck1.cb assert_compile_error deref-semcheck2.cb assert_compile_error deref-semcheck3.cb