mirror of https://github.com/aamine/cbc
* 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:
parent
5b4def1bd7
commit
3b0a50aaca
21
ChangeLog
21
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue