mirror of https://github.com/aamine/cbc
* now many tests work (30/1709 failed).
* net/loveruby/cflat/compiler/Simplifier.java: set location of AssignStmtNode. * net/loveruby/cflat/compiler/Simplifier.java: allocate tmp variable in scope. * net/loveruby/cflat/compiler/Simplifier.java: opAssign/inc/dec handling was completely wrong (there still be some problems yet). * net/loveruby/cflat/compiler/CodeGenerator.java (compileLHS): implemented for IR. * net/loveruby/cflat/compiler/CodeGenerator.java (loadVarible): implemented for IR. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4142 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
97fbe0672c
commit
63170db30b
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
|||
Mon Apr 20 03:52:10 2009 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* now many tests work (30/1709 failed).
|
||||
|
||||
* net/loveruby/cflat/compiler/Simplifier.java: set location of
|
||||
AssignStmtNode.
|
||||
|
||||
* net/loveruby/cflat/compiler/Simplifier.java: allocate tmp
|
||||
variable in scope.
|
||||
|
||||
* net/loveruby/cflat/compiler/Simplifier.java: opAssign/inc/dec
|
||||
handling was completely wrong (there still be some problems yet).
|
||||
|
||||
* net/loveruby/cflat/compiler/CodeGenerator.java (compileLHS):
|
||||
implemented for IR.
|
||||
|
||||
* net/loveruby/cflat/compiler/CodeGenerator.java (loadVarible):
|
||||
implemented for IR.
|
||||
|
||||
Mon Apr 20 00:39:13 2009 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/ast/IR.java: new class to represents IR.
|
||||
|
|
|
@ -3,8 +3,8 @@ package net.loveruby.cflat.ast;
|
|||
public class AssignStmtNode extends StmtNode {
|
||||
protected ExprNode lhs, rhs;
|
||||
|
||||
public AssignStmtNode(ExprNode lhs, ExprNode rhs) {
|
||||
super(null);
|
||||
public AssignStmtNode(Location loc, ExprNode lhs, ExprNode rhs) {
|
||||
super(loc);
|
||||
this.lhs = lhs;
|
||||
this.rhs = rhs;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,11 @@ public class DefinedVariable extends Variable {
|
|||
sequence = -1;
|
||||
}
|
||||
|
||||
static private long tmpSeq = 0;
|
||||
|
||||
static public DefinedVariable tmp(Type t) {
|
||||
return new DefinedVariable(false, new TypeNode(t), "@tmp", null);
|
||||
return new DefinedVariable(false,
|
||||
new TypeNode(t), "@tmp" + tmpSeq++, null);
|
||||
}
|
||||
|
||||
public boolean isDefined() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.loveruby.cflat.ast;
|
||||
import net.loveruby.cflat.compiler.ErrorHandler;
|
||||
import net.loveruby.cflat.exception.*;
|
||||
import net.loveruby.cflat.type.Type;
|
||||
import java.util.*;
|
||||
|
||||
public class LocalScope extends Scope {
|
||||
|
@ -44,6 +45,12 @@ public class LocalScope extends Scope {
|
|||
}
|
||||
// #@@}
|
||||
|
||||
public DefinedVariable allocateTmp(Type t) {
|
||||
DefinedVariable var = DefinedVariable.tmp(t);
|
||||
defineVariable(var);
|
||||
return var;
|
||||
}
|
||||
|
||||
// #@@range/get{
|
||||
public Entity get(String name) throws SemanticException {
|
||||
DefinedVariable var = variables.get(name);
|
||||
|
|
|
@ -16,6 +16,7 @@ public class VariableNode extends ExprNode {
|
|||
|
||||
public VariableNode(DefinedVariable var) {
|
||||
this.entity = var;
|
||||
this.name = var.name();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
|
|
|
@ -1067,11 +1067,19 @@ public class CodeGenerator implements ASTVisitor<Void,Void>, ELFConstants {
|
|||
//
|
||||
|
||||
private void compileLHS(ExprNode lhs) {
|
||||
// FIXME FIXME FIXME
|
||||
if (lhs instanceof VariableNode) {
|
||||
// for variables: apply loadVariableAddress
|
||||
loadVariableAddress((VariableNode)lhs, reg("ax"));
|
||||
}
|
||||
else if (lhs instanceof DereferenceNode) {
|
||||
// for *expr: remove DereferenceNode
|
||||
DereferenceNode n = (DereferenceNode)lhs;
|
||||
compile(n.expr());
|
||||
}
|
||||
else {
|
||||
// otherwise: fatal error
|
||||
compile(lhs);
|
||||
throw new Error("must not happen");
|
||||
}
|
||||
}
|
||||
|
||||
// #@@range/compile_Assign{
|
||||
|
@ -1141,12 +1149,13 @@ public class CodeGenerator implements ASTVisitor<Void,Void>, ELFConstants {
|
|||
*/
|
||||
// #@@range/loadVariable{
|
||||
protected void loadVariable(ExprNode node, Register dest) {
|
||||
/*
|
||||
if (node.shouldEvaluatedToAddress()) {
|
||||
// "int[4] a; a" implies &a
|
||||
// "x = puts" implies &puts
|
||||
loadVariableAddress(node, dest);
|
||||
}
|
||||
else if (node.memref() == null) {
|
||||
else*/ if (node.memref() == null) {
|
||||
mov(node.address(), dest);
|
||||
load(node.type(), mem(dest), dest);
|
||||
}
|
||||
|
|
|
@ -44,12 +44,14 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
//
|
||||
|
||||
private List<StmtNode> stmts;
|
||||
private LinkedList<LocalScope> scopeStack;
|
||||
private LinkedList<Label> breakStack;
|
||||
private LinkedList<Label> continueStack;
|
||||
private Map<String, JumpEntry> jumpMap;
|
||||
|
||||
public Void visit(DefinedFunction f) {
|
||||
stmts = new ArrayList<StmtNode>();
|
||||
scopeStack = new LinkedList<LocalScope>();
|
||||
breakStack = new LinkedList<Label>();
|
||||
continueStack = new LinkedList<Label>();
|
||||
jumpMap = new HashMap<String, JumpEntry>();
|
||||
|
@ -80,7 +82,7 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
|
||||
// insert node before the current statement.
|
||||
private void assignBeforeStmt(ExprNode lhs, ExprNode rhs) {
|
||||
stmts.add(beforeStmt, new AssignStmtNode(lhs, rhs));
|
||||
stmts.add(beforeStmt, new AssignStmtNode(null, lhs, rhs));
|
||||
beforeStmt++;
|
||||
}
|
||||
|
||||
|
@ -142,12 +144,14 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
public Void visit(BlockNode node) {
|
||||
for (DefinedVariable var : node.variables()) {
|
||||
if (var.initializer() != null) {
|
||||
assign(ref(var), var.initializer());
|
||||
assign(var.location(), ref(var), var.initializer());
|
||||
}
|
||||
}
|
||||
scopeStack.add(node.scope());
|
||||
for (StmtNode s : node.stmts()) {
|
||||
transform(s);
|
||||
}
|
||||
scopeStack.removeLast();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -284,7 +288,9 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
}
|
||||
|
||||
public Void visit(ReturnNode node) {
|
||||
if (node.expr() != null) {
|
||||
node.setExpr(transform(node.expr()));
|
||||
}
|
||||
stmts.add(node);
|
||||
return null;
|
||||
}
|
||||
|
@ -295,12 +301,15 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
}
|
||||
|
||||
private void assign(ExprNode lhs, ExprNode rhs) {
|
||||
stmts.add(new AssignStmtNode(lhs, rhs));
|
||||
assign(null, lhs, rhs);
|
||||
}
|
||||
|
||||
private void assign(Location loc, ExprNode lhs, ExprNode rhs) {
|
||||
stmts.add(new AssignStmtNode(loc, lhs, rhs));
|
||||
}
|
||||
|
||||
private DefinedVariable tmpVar(Type t) {
|
||||
// FIXME: allocate in scope??
|
||||
return DefinedVariable.tmp(t);
|
||||
return scopeStack.getLast().allocateTmp(t);
|
||||
}
|
||||
|
||||
class JumpEntry {
|
||||
|
@ -429,13 +438,26 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
private ExprNode transformOpAssign(ExprNode lhs, String op, ExprNode rhs) {
|
||||
rhs = expandPointerArithmetic(rhs, op, lhs);
|
||||
if (isStatement()) {
|
||||
assignBeforeStmt(lhs, rhs);
|
||||
if (lhs.isConstantAddress()) {
|
||||
// lhs = lhs op rhs
|
||||
assign(lhs, binaryOp(lhs, op, rhs));
|
||||
}
|
||||
else {
|
||||
// a = &lhs, *a = *a op rhs
|
||||
ExprNode addr = addressOf(lhs);
|
||||
DefinedVariable a = tmpVar(addr.type());
|
||||
assign(ref(a), addr);
|
||||
assign(deref(a), binaryOp(deref(a), op, rhs));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
DefinedVariable tmp = tmpVar(rhs.type());
|
||||
assignBeforeStmt(ref(tmp), rhs);
|
||||
return ref(tmp);
|
||||
// a = &lhs, *a = *a op rhs, *a
|
||||
ExprNode addr = addressOf(lhs);
|
||||
DefinedVariable a = tmpVar(addr.type());
|
||||
assignBeforeStmt(ref(a), addr);
|
||||
assignBeforeStmt(deref(a), binaryOp(deref(a), op, rhs));
|
||||
return deref(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,7 +551,7 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
public ExprNode visit(ArefNode node) {
|
||||
ExprNode offset = binaryOp(intValue(node.elementSize()),
|
||||
"*", transformArrayIndex(node));
|
||||
return binaryOp(transform(node.baseExpr()), "+", offset);
|
||||
return deref(binaryOp(transform(node.baseExpr()), "+", offset));
|
||||
}
|
||||
|
||||
// For multidimension array: t[e][d][c][b][a];
|
||||
|
@ -627,16 +649,16 @@ class Simplifier implements ASTVisitor<Void, ExprNode> {
|
|||
return new VariableNode(var);
|
||||
}
|
||||
|
||||
// add DereferenceNode on top of the var.
|
||||
private DereferenceNode deref(DefinedVariable var) {
|
||||
return deref(ref(var));
|
||||
}
|
||||
|
||||
// add DereferenceNode on top of the expr.
|
||||
private DereferenceNode deref(ExprNode expr) {
|
||||
return new DereferenceNode(expr);
|
||||
}
|
||||
|
||||
// add DereferenceNode on top of the var.
|
||||
private DereferenceNode deref(DefinedVariable var) {
|
||||
return new DereferenceNode(new VariableNode(var));
|
||||
}
|
||||
|
||||
private BinaryOpNode binaryOp(ExprNode left, String op, ExprNode right) {
|
||||
return new BinaryOpNode(left, op, right);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue