* net/loveruby/cflat/parser/Parser.jj: pass location node to the CaseNode explicitly.

* net/loveruby/cflat/ast/CaseNode.java: default clause does not have value, we cannot extract location node from values.  Receive a location node as a first argument explicitly.
* net/loveruby/cflat/compiler/CodeGenerator.java: must define end label.
* net/loveruby/cflat/compiler/CodeGenerator.java: implement default clause.
* test: test switch stmt.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3990 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-08-31 16:49:26 +00:00
parent 94002785bd
commit b99c2c277d
5 changed files with 63 additions and 10 deletions

View File

@ -1,3 +1,20 @@
Mon Sep 1 01:49:23 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/parser/Parser.jj: pass location node to the
CaseNode explicitly.
* net/loveruby/cflat/ast/CaseNode.java: default clause does not
have value, we cannot extract location node from values. Receive
a location node as a first argument explicitly.
* net/loveruby/cflat/compiler/CodeGenerator.java: must define end
label.
* net/loveruby/cflat/compiler/CodeGenerator.java: implement
default clause.
* test: test switch stmt.
Mon Sep 1 01:26:20 2008 Minero Aoki <aamine@loveruby.net> Mon Sep 1 01:26:20 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/CodeGenerator.java: static function * net/loveruby/cflat/compiler/CodeGenerator.java: static function

View File

@ -8,8 +8,8 @@ public class CaseNode extends StmtNode {
protected List values; // List<Node> protected List values; // List<Node>
protected BlockNode body; protected BlockNode body;
public CaseNode(LabelPool pool, List values, BlockNode body) { public CaseNode(Location loc, LabelPool pool, List values, BlockNode body) {
super(((Node)values.get(0)).location()); super(loc);
this.pool = pool; this.pool = pool;
this.values = values; this.values = values;
this.body = body; this.body = body;
@ -20,6 +20,10 @@ public class CaseNode extends StmtNode {
return values.iterator(); return values.iterator();
} }
public boolean isDefault() {
return values.isEmpty();
}
public BlockNode body() { public BlockNode body() {
return body; return body;
} }

View File

@ -457,18 +457,25 @@ static public void p(String s) { System.err.println(s); }
Iterator cases = node.cases(); Iterator cases = node.cases();
while (cases.hasNext()) { while (cases.hasNext()) {
CaseNode caseNode = (CaseNode)cases.next(); CaseNode caseNode = (CaseNode)cases.next();
Iterator values = caseNode.values(); if (! caseNode.isDefault()) {
while (values.hasNext()) { Iterator values = caseNode.values();
IntegerLiteralNode ival = (IntegerLiteralNode)values.next(); while (values.hasNext()) {
mov(imm(ival.value()), reg("cx")); IntegerLiteralNode ival = (IntegerLiteralNode)values.next();
cmp(t, reg("cx", t), reg("ax", t)); mov(imm(ival.value()), reg("cx"));
je(caseNode.beginLabel()); cmp(t, reg("cx", t), reg("ax", t));
je(caseNode.beginLabel());
}
}
else {
jmp(caseNode.beginLabel());
} }
} }
jmp(node.endLabel());
cases = node.cases(); cases = node.cases();
while (cases.hasNext()) { while (cases.hasNext()) {
compile((CaseNode)cases.next()); compile((CaseNode)cases.next());
} }
label(node.endLabel());
} }
public void visit(CaseNode node) { public void visit(CaseNode node) {

View File

@ -955,7 +955,7 @@ CaseNode case_clause():
{ {
values=cases() body=case_body() values=cases() body=case_body()
{ {
return new CaseNode(labelPool, values, body); return new CaseNode(body.location(), labelPool, values, body);
} }
} }
@ -976,7 +976,8 @@ CaseNode default_clause():
{ {
<DEFAULT_> ":" body=case_body() <DEFAULT_> ":" body=case_body()
{ {
return new CaseNode(labelPool, new ArrayList(), body); return new CaseNode(body.location(), labelPool,
new ArrayList(), body);
} }
} }

24
test/switch.cb Normal file
View File

@ -0,0 +1,24 @@
import stdio;
int
main(int argc, char **argv)
{
switch (argc) {
case 1:
case 2:
puts("1 or 2");
break;
case 3:
case 4:
puts("3 or 4");
break;
case 5:
case 6:
puts("5 or 6");
break;
default:
puts("other");
break;
}
return 0;
}