r4887@macbookpro: aamine | 2009-05-23 23:30:32 +0900

* net/loveruby/cflat/compiler/IRGenerator.java: refactoring: use reverse(node.args) instead of ListIterator.
 * net/loveruby/cflat/sysdep/x86/CodeGenerator.java: ditto.
 * net/loveruby/cflat/utils/ListUtils.java: new utility class.
 * net/loveruby/cflat/ast/FuncallNode.java: remove #finalArgs.
 * net/loveruby/cflat/ir/Call.java: ditto.
 * net/loveruby/cflat/ast/FuncallNode.java: refactoring: rename method: arguments -> args.
 * net/loveruby/cflat/compiler/Visitor.java: follow it.
 * net/loveruby/cflat/compiler/TypeChecker.java: ditto.
 


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4232 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2009-05-23 14:31:37 +00:00
parent e002c1089a
commit a54e95aa16
11 changed files with 101 additions and 45 deletions

View File

@ -1,3 +1,23 @@
Sat May 23 23:31:17 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/IRGenerator.java: refactoring: use
reverse(node.args) instead of ListIterator.
* net/loveruby/cflat/sysdep/x86/CodeGenerator.java: ditto.
* net/loveruby/cflat/utils/ListUtils.java: new utility class.
* net/loveruby/cflat/ast/FuncallNode.java: remove #finalArgs.
* net/loveruby/cflat/ir/Call.java: ditto.
* net/loveruby/cflat/ast/FuncallNode.java: refactoring: rename
method: arguments -> args.
* net/loveruby/cflat/compiler/Visitor.java: follow it.
* net/loveruby/cflat/compiler/TypeChecker.java: ditto.
Sat May 23 22:31:06 2009 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/parser/Parser.jj: now NULL is not a reserved

View File

@ -5,11 +5,11 @@ import java.util.*;
public class FuncallNode extends ExprNode {
protected ExprNode expr;
protected List<ExprNode> arguments;
protected List<ExprNode> args;
public FuncallNode(ExprNode expr, List<ExprNode> arguments) {
public FuncallNode(ExprNode expr, List<ExprNode> args) {
this.expr = expr;
this.arguments = arguments;
this.args = args;
}
public ExprNode expr() {
@ -38,20 +38,16 @@ public class FuncallNode extends ExprNode {
}
public long numArgs() {
return arguments.size();
return args.size();
}
public List<ExprNode> arguments() {
return arguments;
public List<ExprNode> args() {
return args;
}
// called from TypeChecker
public void replaceArgs(List<ExprNode> args) {
this.arguments = args;
}
public ListIterator<ExprNode> finalArg() {
return arguments.listIterator(arguments.size());
this.args = args;
}
public Location location() {
@ -60,7 +56,7 @@ public class FuncallNode extends ExprNode {
protected void _dump(Dumper d) {
d.printMember("expr", expr);
d.printNodeList("arguments", arguments);
d.printNodeList("args", args);
}
public <S,E> E accept(ASTVisitor<S,E> visitor) {

View File

@ -6,6 +6,7 @@ import net.loveruby.cflat.type.TypeTable;
import net.loveruby.cflat.ir.*;
import net.loveruby.cflat.asm.Label;
import net.loveruby.cflat.utils.ErrorHandler;
import net.loveruby.cflat.utils.ListUtils;
import net.loveruby.cflat.exception.*;
import java.util.*;
@ -554,30 +555,25 @@ class IRGenerator implements ASTVisitor<Void, Expr> {
}
// #@@}
// #@@range/Funcall{
public Expr visit(FuncallNode node) {
List<Expr> newArgs = new ArrayList<Expr>();
ListIterator<ExprNode> args = node.finalArg();
while (args.hasPrevious()) {
newArgs.add(0, transformExpr(args.previous()));
List<Expr> args = new ArrayList<Expr>();
for (ExprNode arg : ListUtils.reverse(node.args())) {
args.add(0, transformExpr(arg));
}
Expr call = new Call(asmType(node.type()),
transformExpr(node.expr()), args);
if (isStatement()) {
stmts.add(
new ExprStmt(node.location(),
new Call(asmType(node.type()),
transformExpr(node.expr()),
newArgs)));
stmts.add(new ExprStmt(node.location(), call));
return null;
}
else {
DefinedVariable tmp = tmpVar(node.type());
assign(node.location(),
ref(tmp),
new Call(asmType(node.type()),
transformExpr(node.expr()),
newArgs));
assign(node.location(), ref(tmp), call);
return ref(tmp);
}
}
// #@@}
//
// Expressions (no side effects)

View File

@ -460,7 +460,7 @@ class TypeChecker extends Visitor {
error(node, "wrong number of argments: " + node.numArgs());
return null;
}
Iterator<ExprNode> args = node.arguments().iterator();
Iterator<ExprNode> args = node.args().iterator();
List<ExprNode> newArgs = new ArrayList<ExprNode>();
// mandatory args
for (Type param : type.paramTypes()) {

View File

@ -172,7 +172,7 @@ abstract public class Visitor implements ASTVisitor<Void, Void> {
public Void visit(FuncallNode node) {
visitExpr(node.expr());
visitExprs(node.arguments());
visitExprs(node.args());
return null;
}

View File

@ -3,7 +3,6 @@ import net.loveruby.cflat.entity.Function;
import net.loveruby.cflat.entity.Entity;
import net.loveruby.cflat.asm.Type;
import java.util.List;
import java.util.ListIterator;
public class Call extends Expr {
private Expr expr;
@ -16,16 +15,12 @@ public class Call extends Expr {
}
public Expr expr() { return expr; }
public List<Expr> arguments() { return args; }
public List<Expr> args() { return args; }
public long numArgs() {
return args.size();
}
public ListIterator<Expr> finalArg() {
return args.listIterator(args.size());
}
/** Returns true if this funcall is NOT a function pointer call. */
public boolean isStaticCall() {
return (expr.getEntityForce() instanceof Function);

View File

@ -5,6 +5,7 @@ import net.loveruby.cflat.entity.*;
import net.loveruby.cflat.asm.*;
import net.loveruby.cflat.ast.Location;
import net.loveruby.cflat.utils.AsmUtils;
import net.loveruby.cflat.utils.ListUtils;
import net.loveruby.cflat.utils.ErrorHandler;
import java.util.*;
@ -639,28 +640,22 @@ public class CodeGenerator
/**
* Implements cdecl function call:
* * All arguments are on stack.
* * Rewind stack by caller.
* * Caller rewinds stack pointer.
*/
// #@@range/compile_Funcall{
public Void visit(Call node) {
// compile function arguments from right to left.
ListIterator<Expr> args = node.finalArg();
while (args.hasPrevious()) {
compile(args.previous());
for (Expr arg : ListUtils.reverse(node.args())) {
compile(arg);
as.push(ax());
}
// call
if (node.isStaticCall()) {
// call via function name
as.call(node.function().callingSymbol());
}
else {
// call via pointer
compile(node.expr());
as.callAbsolute(ax());
}
// rewind stack
// >4 bytes arguments are not supported.
// rewind stack; >4 bytes arguments are not supported.
rewindStack(as, stackSizeFromWordNum(node.numArgs()));
return null;
}

View File

@ -0,0 +1,15 @@
package net.loveruby.cflat.utils;
import java.util.List;
import java.util.ListIterator;
import java.util.ArrayList;
public abstract class ListUtils {
static public <T> List<T> reverse(List<T> list) {
List<T> result = new ArrayList<T>(list.size());
ListIterator<T> it = list.listIterator(list.size());
while (it.hasPrevious()) {
result.add(it.previous());
}
return result;
}
}

View File

@ -6,7 +6,8 @@ import org.junit.runners.Suite.*;
@RunWith(Suite.class)
@SuiteClasses({
TestCursor.class,
TestTextUtils.class
TestTextUtils.class,
TestListUtils.class
})
public class TestAll {
static public void main(String[] args) {

27
unit/TestListUtils.java Normal file
View File

@ -0,0 +1,27 @@
import org.junit.*;
import org.junit.runner.*;
import static org.junit.Assert.*;
import java.util.List;
import java.util.ArrayList;
import static net.loveruby.cflat.utils.ListUtils.*;
public class TestListUtils {
static public void main(String[] args) {
JUnitCore.main(TestListUtils.class.getName());
}
@Test public void test_reverse() {
assertEquals("reverse #1", list(), reverse(list()));
assertEquals("reverse #2", list(1), reverse(list(1)));
assertEquals("reverse #3", list(2,1), reverse(list(1,2)));
assertEquals("reverse #4", list(3,2,1), reverse(list(1,2,3)));
}
private List<Integer> list(int... values) {
List<Integer> result = new ArrayList<Integer>();
for (int i : values) {
result.add(i);
}
return result;
}
}

View File

@ -10,8 +10,19 @@ public class TestTextUtils {
@Test public void test_dumpString() {
assertEquals("dumpString #1", "\"\"", dumpString(""));
assertEquals("dumpString #2", "\"x\"", dumpString("x"));
assertEquals("dumpString #3", "\"xx\"", dumpString("xx"));
assertEquals("dumpString #4", "\"x\\\"x\"", dumpString("x\"x"));
assertEquals("dumpString #5", "\"x\\nx\"", dumpString("x\nx"));
}
@Test public void test_isPrintable() {
assertEquals(true, isPrintable('a'));
assertEquals(true, isPrintable('A'));
assertEquals(true, isPrintable(' '));
assertEquals(false, isPrintable('\t'));
assertEquals(false, isPrintable('\r'));
assertEquals(false, isPrintable('\n'));
assertEquals(false, isPrintable('\0'));
}
}