diff --git a/ChangeLog b/ChangeLog index b02a142..fab3788 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +Sat May 23 23:31:17 2009 Minero Aoki + + * 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 * net/loveruby/cflat/parser/Parser.jj: now NULL is not a reserved diff --git a/net/loveruby/cflat/ast/FuncallNode.java b/net/loveruby/cflat/ast/FuncallNode.java index 2cbbe58..0917baa 100644 --- a/net/loveruby/cflat/ast/FuncallNode.java +++ b/net/loveruby/cflat/ast/FuncallNode.java @@ -5,11 +5,11 @@ import java.util.*; public class FuncallNode extends ExprNode { protected ExprNode expr; - protected List arguments; + protected List args; - public FuncallNode(ExprNode expr, List arguments) { + public FuncallNode(ExprNode expr, List 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 arguments() { - return arguments; + public List args() { + return args; } // called from TypeChecker public void replaceArgs(List args) { - this.arguments = args; - } - - public ListIterator 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 E accept(ASTVisitor visitor) { diff --git a/net/loveruby/cflat/compiler/IRGenerator.java b/net/loveruby/cflat/compiler/IRGenerator.java index 34aaca7..13a5cea 100644 --- a/net/loveruby/cflat/compiler/IRGenerator.java +++ b/net/loveruby/cflat/compiler/IRGenerator.java @@ -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 { } // #@@} + // #@@range/Funcall{ public Expr visit(FuncallNode node) { - List newArgs = new ArrayList(); - ListIterator args = node.finalArg(); - while (args.hasPrevious()) { - newArgs.add(0, transformExpr(args.previous())); + List args = new ArrayList(); + 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) diff --git a/net/loveruby/cflat/compiler/TypeChecker.java b/net/loveruby/cflat/compiler/TypeChecker.java index f2843b6..51584ea 100644 --- a/net/loveruby/cflat/compiler/TypeChecker.java +++ b/net/loveruby/cflat/compiler/TypeChecker.java @@ -460,7 +460,7 @@ class TypeChecker extends Visitor { error(node, "wrong number of argments: " + node.numArgs()); return null; } - Iterator args = node.arguments().iterator(); + Iterator args = node.args().iterator(); List newArgs = new ArrayList(); // mandatory args for (Type param : type.paramTypes()) { diff --git a/net/loveruby/cflat/compiler/Visitor.java b/net/loveruby/cflat/compiler/Visitor.java index 5b2bdc5..f202b45 100644 --- a/net/loveruby/cflat/compiler/Visitor.java +++ b/net/loveruby/cflat/compiler/Visitor.java @@ -172,7 +172,7 @@ abstract public class Visitor implements ASTVisitor { public Void visit(FuncallNode node) { visitExpr(node.expr()); - visitExprs(node.arguments()); + visitExprs(node.args()); return null; } diff --git a/net/loveruby/cflat/ir/Call.java b/net/loveruby/cflat/ir/Call.java index d865ce2..c963f10 100644 --- a/net/loveruby/cflat/ir/Call.java +++ b/net/loveruby/cflat/ir/Call.java @@ -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 arguments() { return args; } + public List args() { return args; } public long numArgs() { return args.size(); } - public ListIterator 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); diff --git a/net/loveruby/cflat/sysdep/x86/CodeGenerator.java b/net/loveruby/cflat/sysdep/x86/CodeGenerator.java index cefb6ad..980da8c 100644 --- a/net/loveruby/cflat/sysdep/x86/CodeGenerator.java +++ b/net/loveruby/cflat/sysdep/x86/CodeGenerator.java @@ -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 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; } diff --git a/net/loveruby/cflat/utils/ListUtils.java b/net/loveruby/cflat/utils/ListUtils.java new file mode 100644 index 0000000..ff16d74 --- /dev/null +++ b/net/loveruby/cflat/utils/ListUtils.java @@ -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 List reverse(List list) { + List result = new ArrayList(list.size()); + ListIterator it = list.listIterator(list.size()); + while (it.hasPrevious()) { + result.add(it.previous()); + } + return result; + } +} diff --git a/unit/TestAll.java b/unit/TestAll.java index 004e989..9488c6b 100644 --- a/unit/TestAll.java +++ b/unit/TestAll.java @@ -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) { diff --git a/unit/TestListUtils.java b/unit/TestListUtils.java new file mode 100644 index 0000000..fc7c40d --- /dev/null +++ b/unit/TestListUtils.java @@ -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 list(int... values) { + List result = new ArrayList(); + for (int i : values) { + result.add(i); + } + return result; + } +} diff --git a/unit/TestTextUtils.java b/unit/TestTextUtils.java index 1c3c97e..5debe2f 100644 --- a/unit/TestTextUtils.java +++ b/unit/TestTextUtils.java @@ -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')); } }