diff --git a/ChangeLog b/ChangeLog index d3297fd..4409143 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +Sun Nov 16 23:57:08 2008 Minero Aoki + + * net/loveruby/cflat/compiler/TypeResolver.java: an array on the + parameter list is a pointer really. + + * net/loveruby/cflat/compiler/TypeChecker.java: an array for stmt + value *is* valid because it is a pointer really. + + * net/loveruby/cflat/compiler/CodeGenerator.java: st.x while st.x + is an array should make a pointer. + + * net/loveruby/cflat/type/Type.java: remove #isPointerAlike, there + is only a Pointer and an Array already. + + * net/loveruby/cflat/type/ArrayType.java: ditto. + + * net/loveruby/cflat/type/PointerType.java: ditto. + + * net/loveruby/cflat/type/UserType.java: ditto. + + * net/loveruby/cflat/ast/ArefNode.java: ditto. + + * net/loveruby/cflat/ast/Variable.java: ditto. + + * net/loveruby/cflat/ast/ExprNode.java: ditto. + + * test: check st.x[1] access. + + * test: check pst->x[1] access. + Sun Nov 16 22:29:33 2008 Minero Aoki * net/loveruby/cflat/compiler/TypeResolver.java: "f = puts" diff --git a/net/loveruby/cflat/ast/ArefNode.java b/net/loveruby/cflat/ast/ArefNode.java index c45636f..5aade8a 100644 --- a/net/loveruby/cflat/ast/ArefNode.java +++ b/net/loveruby/cflat/ast/ArefNode.java @@ -29,7 +29,7 @@ public class ArefNode extends ExprNode { // isMultiDimension a[x][y] = true. // isMultiDimension a[x] = false. public boolean isMultiDimension() { - return (expr instanceof ArefNode) && !expr.type().isPointerAlike(); + return (expr instanceof ArefNode) && !expr.type().isPointer(); } // Returns base expression of (multi-dimension) array. diff --git a/net/loveruby/cflat/ast/ExprNode.java b/net/loveruby/cflat/ast/ExprNode.java index 9031947..4ce0c5c 100644 --- a/net/loveruby/cflat/ast/ExprNode.java +++ b/net/loveruby/cflat/ast/ExprNode.java @@ -39,7 +39,7 @@ abstract public class ExprNode extends Node { } public boolean shouldEvaluatedToAddress() { - return false; + return type().isArray(); } public boolean isConstant() { diff --git a/net/loveruby/cflat/ast/Variable.java b/net/loveruby/cflat/ast/Variable.java index c547ea4..77c557c 100644 --- a/net/loveruby/cflat/ast/Variable.java +++ b/net/loveruby/cflat/ast/Variable.java @@ -7,6 +7,6 @@ abstract public class Variable extends Entity { } public boolean cannotLoad() { - return type().isAllocatedArray(); + return type().isArray(); } } diff --git a/net/loveruby/cflat/compiler/CodeGenerator.java b/net/loveruby/cflat/compiler/CodeGenerator.java index 9f9a4ee..5b498db 100644 --- a/net/loveruby/cflat/compiler/CodeGenerator.java +++ b/net/loveruby/cflat/compiler/CodeGenerator.java @@ -1008,12 +1008,22 @@ public class CodeGenerator public void visit(MemberNode node) { compileLHS(node.expr()); - load(node.type(), mem(node.offset(), reg("ax")), reg("ax")); + if (node.shouldEvaluatedToAddress()) { + add(imm(node.offset()), reg("ax")); + } + else { + load(node.type(), mem(node.offset(), reg("ax")), reg("ax")); + } } public void visit(PtrMemberNode node) { compile(node.expr()); - load(node.type(), mem(node.offset(), reg("ax")), reg("ax")); + if (node.shouldEvaluatedToAddress()) { + add(imm(node.offset()), reg("ax")); + } + else { + load(node.type(), mem(node.offset(), reg("ax")), reg("ax")); + } } public void visit(DereferenceNode node) { @@ -1045,12 +1055,7 @@ public class CodeGenerator compileArrayIndex(node); imul(imm(node.elementSize()), reg("ax")); push(reg("ax")); - if (node.baseExpr().type().isPointerAlike()) { - compile(node.baseExpr()); - } - else { - compileLHS(node.baseExpr()); - } + compile(node.baseExpr()); pop(reg("cx")); add(reg("cx"), reg("ax")); } diff --git a/net/loveruby/cflat/compiler/TypeChecker.java b/net/loveruby/cflat/compiler/TypeChecker.java index 8dbe49f..6b16bbd 100644 --- a/net/loveruby/cflat/compiler/TypeChecker.java +++ b/net/loveruby/cflat/compiler/TypeChecker.java @@ -557,7 +557,7 @@ class TypeChecker extends Visitor { // #@@} protected boolean isInvalidStatementType(Type t) { - return t.isStruct() || t.isUnion() || t.isAllocatedArray(); + return t.isStruct() || t.isUnion(); } protected boolean isInvalidReturnType(Type t) { diff --git a/net/loveruby/cflat/compiler/TypeResolver.java b/net/loveruby/cflat/compiler/TypeResolver.java index 9fe97d7..258f302 100644 --- a/net/loveruby/cflat/compiler/TypeResolver.java +++ b/net/loveruby/cflat/compiler/TypeResolver.java @@ -107,7 +107,12 @@ public class TypeResolver extends Visitor { protected void resolveFunctionHeader(Function func) { bindType(func.typeNode()); for (Parameter param : func.parameters()) { - bindType(param.typeNode()); + Type t = typeTable.get(param.typeNode().typeRef()); + // arrays must be converted to pointers in a function parameter. + if (t.isArray()) { + t = typeTable.pointerTo(t.getArrayType().baseType()); + } + param.typeNode().setType(t); } } // #@@} diff --git a/net/loveruby/cflat/type/ArrayType.java b/net/loveruby/cflat/type/ArrayType.java index dd155d4..ddd3660 100644 --- a/net/loveruby/cflat/type/ArrayType.java +++ b/net/loveruby/cflat/type/ArrayType.java @@ -18,7 +18,6 @@ public class ArrayType extends Type { public boolean isArray() { return true; } public boolean isDereferable() { return true; } - public boolean isPointerAlike() { return length == undefined; } public boolean isScalar() { return true; } public boolean isSigned() { return false; } diff --git a/net/loveruby/cflat/type/PointerType.java b/net/loveruby/cflat/type/PointerType.java index 10ed326..94d98ae 100644 --- a/net/loveruby/cflat/type/PointerType.java +++ b/net/loveruby/cflat/type/PointerType.java @@ -10,7 +10,6 @@ public class PointerType extends Type { } public boolean isPointer() { return true; } - public boolean isPointerAlike() { return true; } public boolean isScalar() { return true; } public boolean isSigned() { return false; } public boolean isDereferable() { return true; } diff --git a/net/loveruby/cflat/type/Type.java b/net/loveruby/cflat/type/Type.java index a04bcf4..a91ff19 100644 --- a/net/loveruby/cflat/type/Type.java +++ b/net/loveruby/cflat/type/Type.java @@ -25,7 +25,6 @@ public abstract class Type { // Ability methods (unary) public boolean isDereferable() { return false; } - public boolean isPointerAlike() { return false; } public boolean isAllocatedArray() { return false; } public boolean isIncompleteArray() { return false; } public boolean isScalar() { return false; } diff --git a/net/loveruby/cflat/type/UserType.java b/net/loveruby/cflat/type/UserType.java index b1fa785..5a94fbe 100644 --- a/net/loveruby/cflat/type/UserType.java +++ b/net/loveruby/cflat/type/UserType.java @@ -40,7 +40,6 @@ public class UserType extends NamedType { public boolean isFunction() { return realType().isFunction(); } public boolean isDereferable() { return realType().isDereferable(); } - public boolean isPointerAlike() { return realType().isPointerAlike(); } public boolean isCallable() { return realType().isCallable(); } public boolean isScalar() { return realType().isScalar(); } diff --git a/test/ptrmemb2.cb b/test/ptrmemb2.cb new file mode 100644 index 0000000..86593eb --- /dev/null +++ b/test/ptrmemb2.cb @@ -0,0 +1,15 @@ +import stdio; + +struct st { + int[4] x; +}; + +int +main(void) +{ + struct st s; + struct st* p = &s; + p->x[1] = 7; + printf("%d\n", p->x[1]); + return 0; +} diff --git a/test/struct3.cb b/test/struct3.cb new file mode 100644 index 0000000..824bc2c --- /dev/null +++ b/test/struct3.cb @@ -0,0 +1,14 @@ +import stdio; + +struct st { + int[4] x; +}; + +int +main(void) +{ + struct st s; + s.x[1] = 7; + printf("%d\n", s.x[1]); + return 0; +} diff --git a/test/test_cbc.sh b/test/test_cbc.sh index 73e4c7b..0854603 100644 --- a/test/test_cbc.sh +++ b/test/test_cbc.sh @@ -166,6 +166,7 @@ ruby_exists() { test_19_struct() { assert_out "11;22" ./struct assert_out "701;702;703;704" ./struct2 + assert_out "7" ./struct3 assert_stat 0 ./struct-semcheck assert_compile_success empstruct.cb assert_compile_error struct-semcheck2.cb @@ -204,6 +205,7 @@ test_22_pointer() { assert_out "1;777;3;4;1;777;3;4" ./pointer3 assert_out "777" ./pointer4 assert_out "1;2;3;4;5;6;77;78" ./ptrmemb + assert_out "7" ./ptrmemb2 assert_compile_error deref-semcheck1.cb assert_compile_error deref-semcheck2.cb assert_compile_error deref-semcheck3.cb @@ -305,7 +307,7 @@ test_34_varargs() { test_35_invalidstmt() { assert_compile_error invalidstmt1.cb assert_compile_error invalidstmt2.cb - assert_compile_error invalidstmt3.cb + assert_compile_success validstmt1.cb } ### diff --git a/test/invalidstmt3.cb b/test/validstmt1.cb similarity index 100% rename from test/invalidstmt3.cb rename to test/validstmt1.cb