diff --git a/ChangeLog b/ChangeLog index 58f37db..3d5dc53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Sun Apr 26 22:41:08 2009 Minero Aoki + + * net/loveruby/cflat/compiler/IRGenerator.java (BlockNode): static + variables are special case. + + * net/loveruby/cflat/compiler/IRGenerator.java (SwitchNode): + Switch must precedes Case bodies to prevent programs from infinite + loop. + + * net/loveruby/cflat/compiler/CodeGenerator.java (Bin): fix MOD + problem. + + * net/loveruby/cflat/compiler/CodeGenerator.java (Bin): fix LSHIFT + problem. + Sun Apr 26 22:08:35 2009 Minero Aoki * now IR nodes are separated from AST. Sources are compilable but diff --git a/net/loveruby/cflat/ast/CaseNode.java b/net/loveruby/cflat/ast/CaseNode.java index e87d980..efe6e59 100644 --- a/net/loveruby/cflat/ast/CaseNode.java +++ b/net/loveruby/cflat/ast/CaseNode.java @@ -3,7 +3,7 @@ import net.loveruby.cflat.asm.Label; import java.util.*; public class CaseNode extends StmtNode { - protected Label beginLabel; + protected Label label; protected List values; protected BlockNode body; @@ -11,17 +11,13 @@ public class CaseNode extends StmtNode { super(loc); this.values = values; this.body = body; - this.beginLabel = new Label(); + this.label = new Label(); } public List values() { return values; } - public void setValues(List values) { - this.values = values; - } - public boolean isDefault() { return values.isEmpty(); } @@ -30,8 +26,8 @@ public class CaseNode extends StmtNode { return body; } - public Label beginLabel() { - return beginLabel; + public Label label() { + return label; } protected void _dump(Dumper d) { diff --git a/net/loveruby/cflat/compiler/CodeGenerator.java b/net/loveruby/cflat/compiler/CodeGenerator.java index 6fe6a89..6e48371 100644 --- a/net/loveruby/cflat/compiler/CodeGenerator.java +++ b/net/loveruby/cflat/compiler/CodeGenerator.java @@ -905,7 +905,7 @@ public class CodeGenerator implements IRVisitor, ELFConstants { mov(imm(0), reg("dx")); div(t, reg("cx", t)); } - if (op.equals("%")) { + if (op == Op.MOD) { mov(reg("dx"), reg("ax")); } break; @@ -930,6 +930,7 @@ public class CodeGenerator implements IRVisitor, ELFConstants { break; case LSHIFT: sal(t, cl(), reg("ax", t)); + break; // #@@} // #@@range/compileBinaryOp_cmpops{ default: diff --git a/net/loveruby/cflat/compiler/IRGenerator.java b/net/loveruby/cflat/compiler/IRGenerator.java index 653a168..834b395 100644 --- a/net/loveruby/cflat/compiler/IRGenerator.java +++ b/net/loveruby/cflat/compiler/IRGenerator.java @@ -149,8 +149,14 @@ class IRGenerator implements ASTVisitor { public Void visit(BlockNode node) { for (DefinedVariable var : node.variables()) { - if (var.initializer() != null) { - assign(var.location(), ref(var), transform(var.initializer())); + if (var.hasInitializer()) { + if (var.isPrivate()) { + // static variables + var.setIR(transform(var.initializer())); + } + else { + assign(var.location(), ref(var), transform(var.initializer())); + } } } scopeStack.add(node.scope()); @@ -193,25 +199,25 @@ class IRGenerator implements ASTVisitor { Label defaultLabel = endLabel; Expr cond = transform(node.cond()); - pushBreak(endLabel); for (CaseNode c : node.cases()) { - Label caseLabel = new Label(); - label(caseLabel); - transform(c.body()); - if (c.isDefault()) { - defaultLabel = caseLabel; + defaultLabel = c.label(); } else { for (ExprNode val : c.values()) { Expr v = transform(val); - cases.add(new Case(((IntValue)v).value(), caseLabel)); + cases.add(new Case(((IntValue)v).value(), c.label())); } } } + stmts.add(new Switch(node.location(), cond, cases, defaultLabel, endLabel)); + pushBreak(endLabel); + for (CaseNode c : node.cases()) { + label(c.label()); + transform(c.body()); + } popBreak(); label(endLabel); - stmts.add(new Switch(node.location(), cond, cases, defaultLabel, endLabel)); return null; }