mirror of https://github.com/aamine/cbc
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:
parent
e002c1089a
commit
a54e95aa16
20
ChangeLog
20
ChangeLog
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue