* net/loveruby/cflat/compiler/CodeGenerator.java (arefNode): calculate element address of multi-dimension array correctly.

* net/loveruby/cflat/compiler/CodeGenerator.java (compileStmt): output statement number and line number as comment.
* net/loveruby/cflat/ast/ArefNode.java: new method #isMultiDimension.
* net/loveruby/cflat/ast/ArefNode.java: new method #baseExpr.
* net/loveruby/cflat/ast/ArefNode.java: new method #elementSize.
* net/loveruby/cflat/ast/ArefNode.java: new method #length.
* net/loveruby/cflat/type/ArrayType.java: add comment.
* test: test multi-dimension array access.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4007 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-09-13 13:15:38 +00:00
parent 5b4def1bd7
commit 3b0a50aaca
8 changed files with 165 additions and 6 deletions

View File

@ -1,3 +1,24 @@
Sat Sep 13 22:15:34 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java (arefNode):
calculate element address of multi-dimension array correctly.
* net/loveruby/cflat/compiler/CodeGenerator.java (compileStmt):
output statement number and line number as comment.
* net/loveruby/cflat/ast/ArefNode.java: new method
#isMultiDimension.
* net/loveruby/cflat/ast/ArefNode.java: new method #baseExpr.
* net/loveruby/cflat/ast/ArefNode.java: new method #elementSize.
* net/loveruby/cflat/ast/ArefNode.java: new method #length.
* net/loveruby/cflat/type/ArrayType.java: add comment.
* test: test multi-dimension array access.
Sat Sep 13 21:34:45 2008 Minero Aoki <aamine@loveruby.net>
* test: test void function without return.

View File

@ -26,6 +26,29 @@ public class ArefNode extends ExprNode {
return true;
}
// isMultiDimension a[x][y][z] = true.
// isMultiDimension a[x][y] = true.
// isMultiDimension a[x] = false.
public boolean isMultiDimension() {
return (expr instanceof ArefNode) && !expr.type().isPointerAlike();
}
// Returns base expression of (multi-dimension) array.
// e.g. baseExpr of a[x][y][z] is a.
public ExprNode baseExpr() {
return isMultiDimension() ? ((ArefNode)expr).baseExpr() : expr;
}
// element size of this (multi-dimension) array
public long elementSize() {
//return baseExpr().type().baseType().allocSize();
return type().allocSize();
}
public long length() {
return ((ArrayType)expr.type()).length();
}
public boolean isConstantAddress() {
return false;
}

View File

@ -19,10 +19,12 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
protected ErrorHandler errorHandler;
protected TypeTable typeTable;
protected DefinedFunction currentFunction;
protected int stmtSeq;
public CodeGenerator(Assembler as, ErrorHandler errorHandler) {
this.as = as;
this.errorHandler = errorHandler;
this.stmtSeq = 1;
}
// #@@}
@ -406,8 +408,9 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
}
}
// needed?
protected void compileStmt(Node node) {
comment("stmt " + stmtSeq + " (line " + node.location().line() + ")");
stmtSeq++;
compile(node);
}
@ -811,19 +814,30 @@ public class CodeGenerator extends Visitor implements ASTLHSVisitor {
}
public void visitLHS(ArefNode node) {
compile(node.index());
imul(imm(node.type().size()), reg("ax"));
compileArrayIndex(node);
imul(imm(node.elementSize()), reg("ax"));
push(reg("ax"));
if (node.expr().type().isPointerAlike()) {
compile(node.expr());
if (node.baseExpr().type().isPointerAlike()) {
compile(node.baseExpr());
}
else {
compileLHS(node.expr());
compileLHS(node.baseExpr());
}
pop(reg("cx"));
add(reg("cx"), reg("ax"));
}
protected void compileArrayIndex(ArefNode node) {
compile(node.index());
if (node.isMultiDimension()) {
push(reg("ax"));
compileArrayIndex((ArefNode)node.expr());
imul(imm(node.length()), reg("ax"));
pop(reg("cx"));
add(reg("cx"), reg("ax"));
}
}
public void visitLHS(MemberNode node) {
compileLHS(node.expr());
add(imm(node.offset()), reg("ax"));

View File

@ -33,10 +33,12 @@ public class ArrayType extends Type {
return length;
}
// Value size as pointer
public long size() {
return pointerSize;
}
// Value size as allocated array
public long allocSize() {
if (isAllocated()) {
return baseType.allocSize() * length;

30
test/mdarray.cb Normal file
View File

@ -0,0 +1,30 @@
import stdio;
int
main(int argc, char **argv)
{
int[3][3] p;
p[0][0] = 3;
p[0][1] = 4;
p[0][2] = 5;
p[1][0] = 6;
p[1][1] = 7;
p[1][2] = 8;
p[2][0] = 9;
p[2][1] = 10;
p[2][2] = 11;
printf("%d;", p[0][0]);
printf("%d;", p[0][1]);
printf("%d;", p[0][2]);
printf("%d;", p[1][0]);
printf("%d;", p[1][1]);
printf("%d;", p[1][2]);
printf("%d;", p[2][0]);
printf("%d;", p[2][1]);
printf("%d;", p[2][2]);
puts("");
return 0;
}

29
test/mdarray2.cb Normal file
View File

@ -0,0 +1,29 @@
import stdio;
int
main(int argc, char **argv)
{
int[3][3] p;
p[0][0] = 3;
p[0][1] = 4;
p[0][2] = 5;
p[1][0] = 6;
p[1][1] = 7;
p[1][2] = 8;
p[2][0] = 9;
p[2][1] = 10;
p[2][2] = 11;
printf("%p\n", &p[0][0]);
printf("%p\n", &p[0][1]);
printf("%p\n", &p[0][2]);
printf("%p\n", &p[1][0]);
printf("%p\n", &p[1][1]);
printf("%p\n", &p[1][2]);
printf("%p\n", &p[2][0]);
printf("%p\n", &p[2][1]);
printf("%p\n", &p[2][2]);
return 0;
}

25
test/ptrarray.cb Normal file
View File

@ -0,0 +1,25 @@
import stdio;
int
main(int argc, char **argv)
{
int[4] ary;
int* ptr = ary;
ptr[0] = 775;
ptr[1] = 776;
ptr[2] = 777;
ptr[3] = 778;
printf("%d;%d;%d;%d;", ary[0], ary[1], ary[2], ary[3]);
printf("%d;%d;%d;%d;", ptr[0], ptr[1], ptr[2], ptr[3]);
ary[0] = 775;
ary[1] = 776;
ary[2] = 777;
ary[3] = 778;
printf("%d;%d;%d;%d;", ary[0], ary[1], ary[2], ary[3]);
printf("%d;%d;%d;%d;", ptr[0], ptr[1], ptr[2], ptr[3]);
puts("");
return 0;
}

View File

@ -141,11 +141,26 @@ test_17_jump() {
test_18_array() {
assert_out "1;5;9" ./array
assert_out "0;0;0" ./array2
assert_out "3;4;5;6;7;8;9;10;11;" ./mdarray
assert_compile_success mdarray2.cb
if ruby_exists
then
local offsets=$(./mdarray2 | ruby -e '
addrs = $stdin.read.split.map {|n| n.hex }
puts addrs.map {|a| a - addrs.first }.join(";")
')
assert_eq "0;4;8;12;16;20;24;28;32" "$offsets"
fi
assert_out "775;776;777;778;775;776;777;778;775;776;777;778;775;776;777;778;" ./ptrarray
assert_compile_error aref-semcheck.cb
assert_compile_error array-semcheck1.cb
assert_compile_error array-semcheck2.cb
}
ruby_exists() {
ruby -e "" 2>/dev/null
}
test_19_struct() {
assert_out "11;22" ./struct
assert_out "701;702;703;704" ./struct2