* net/loveruby/cflat/compiler/TypeChecker.java: check function arguments.

* net/loveruby/cflat/ast/FuncallNode.java: rename method: #args -> #argument.
* net/loveruby/cflat/compiler/Visitor.java: ditto.
* net/loveruby/cflat/ast/Params.java: new method #argc, #minArgc.
* net/loveruby/cflat/ast/FixedParams.java: ditto.
* net/loveruby/cflat/ast/VarParams.java: ditto.
* net/loveruby/cflat/ast/Node.java: new method #isCallable.
* net/loveruby/cflat/type/FunctionType.java: new method #acceptsArgc.
* net/loveruby/cflat/type/FunctionType.java: new method #paramTypes.
* net/loveruby/cflat/type/Type.java: new method #isCallable.
* net/loveruby/cflat/type/PointerType.java: ditto.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3764 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-01-01 15:22:54 +00:00
parent 1e4ac4dabf
commit 6e3734fcc0
11 changed files with 138 additions and 24 deletions

View File

@ -1,3 +1,31 @@
Wed Jan 2 00:22:51 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/TypeChecker.java: check function
arguments.
* net/loveruby/cflat/ast/FuncallNode.java: rename method: #args ->
#argument.
* net/loveruby/cflat/compiler/Visitor.java: ditto.
* net/loveruby/cflat/ast/Params.java: new method #argc, #minArgc.
* net/loveruby/cflat/ast/FixedParams.java: ditto.
* net/loveruby/cflat/ast/VarParams.java: ditto.
* net/loveruby/cflat/ast/Node.java: new method #isCallable.
* net/loveruby/cflat/type/FunctionType.java: new method
#acceptsArgc.
* net/loveruby/cflat/type/FunctionType.java: new method
#paramTypes.
* net/loveruby/cflat/type/Type.java: new method #isCallable.
* net/loveruby/cflat/type/PointerType.java: ditto.
Tue Jan 1 23:21:22 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/Compiler.java: create TypeTable

View File

@ -13,6 +13,14 @@ public class FixedParams extends Params {
return parameters.iterator();
}
public int argc() {
return parameters.size();
}
public int minArgc() {
return parameters.size();
}
protected List parametersList() {
return parameters;
}

View File

@ -4,11 +4,11 @@ import java.util.*;
public class FuncallNode extends Node {
protected Node expr;
protected List args;
protected List arguments;
public FuncallNode(Node expr, List args) {
public FuncallNode(Node expr, List arguments) {
this.expr = expr;
this.args = args;
this.arguments = arguments;
}
public Node expr() {
@ -26,6 +26,10 @@ public class FuncallNode extends Node {
}
public Type type() {
return functionType().returnType();
}
public FunctionType functionType() {
Type t = expr().type();
if (! (t instanceof PointerType)) {
throw new Error("calling non-function");
@ -34,19 +38,24 @@ public class FuncallNode extends Node {
if (! (f instanceof FunctionType)) {
throw new Error("calling non-function");
}
return ((FunctionType)f).returnType();
return (FunctionType)f;
}
public long numArgs() {
return args.size();
return arguments.size();
}
public Iterator args() {
return args.iterator();
public Iterator arguments() {
return arguments.iterator();
}
/** called from TypeChecker */
public void replaceArgs(List args) {
this.arguments = args;
}
public ListIterator finalArg() {
return args.listIterator(args.size());
return arguments.listIterator(arguments.size());
}
public void accept(ASTVisitor visitor) {

View File

@ -15,4 +15,8 @@ abstract public class Node {
public AsmEntity address() {
throw new Error("Node#address");
}
public boolean isCallable() {
return type().isCallable();
}
}

View File

@ -9,6 +9,8 @@ abstract public class Params extends Node {
abstract public Iterator parameters();
abstract public boolean isVararg();
abstract public int argc();
abstract public int minArgc();
abstract public boolean equals(Object other);
abstract public Params internTypes(TypeTable table);
abstract public Params typeRefs();

View File

@ -13,6 +13,14 @@ public class VarParams extends Params {
return params.parameters();
}
public int argc() {
throw new Error("VarParams#argc");
}
public int minArgc() {
return params.minArgc();
}
public boolean isVararg() {
return true;
}

View File

@ -11,11 +11,11 @@ class TypeChecker extends Visitor {
}
protected TypeTable typeTable;
protected ErrorHandler handler;
protected ErrorHandler errorHandler;
public TypeChecker(TypeTable typeTable, ErrorHandler handler) {
public TypeChecker(TypeTable typeTable, ErrorHandler errorHandler) {
this.typeTable = typeTable;
this.handler = handler;
this.errorHandler = errorHandler;
}
public void visit(AST ast) throws SemanticException {
@ -24,7 +24,7 @@ class TypeChecker extends Visitor {
DefinedFunction f = (DefinedFunction)funcs.next();
resolve(f.body());
}
if (handler.errorOccured()) {
if (errorHandler.errorOccured()) {
throw new SemanticException("compile error");
}
}
@ -118,7 +118,7 @@ class TypeChecker extends Visitor {
}
else if (r.isCastableTo(l)) { // insert cast on RHS
if (! r.isCompatible(l)) {
handler.warn("incompatible cast from " +
errorHandler.warn("incompatible cast from " +
r.textize() + " to " + l.textize());
}
node.setRHS(newCastNode(l, node.rhs()));
@ -271,10 +271,41 @@ class TypeChecker extends Visitor {
}
public void visit(FuncallNode node) {
super.visit(node);
// FIXME: check types
// FIXME: check if callable
// FIXME: check argument types
resolve(node.expr());
if (! node.expr().isCallable()) {
errorHandler.error("called object is not a function");
return;
}
FunctionType type = node.functionType();
if (! type.acceptsArgc(node.numArgs())) {
errorHandler.error("wrong number of argments: " + node.numArgs());
return;
}
// Check only mandatory parameters
Iterator params = type.paramTypes();
Iterator args = node.arguments();
List newArgs = new ArrayList();
while (params.hasNext()) {
Type param = (Type)params.next();
Node arg = (Node)args.next();
resolve(arg);
if (arg.type().equals(param)) {
newArgs.add(arg);
}
else if (arg.type().isCompatible(param)) {
newArgs.add(newCastNode(param, arg));
}
else {
incompatibleTypeError(arg.type(), param);
newArgs.add(arg);
}
}
while (args.hasNext()) {
Node arg = (Node)args.next();
resolve(arg);
newArgs.add(arg);
}
node.replaceArgs(newArgs);
}
public void visit(ArefNode node) {
@ -311,7 +342,7 @@ class TypeChecker extends Visitor {
incompatibleTypeError(node.expr().type(), node.type());
}
else if (! node.expr().type().isCompatible(node.type())) {
handler.warn("incompatible cast from " +
errorHandler.warn("incompatible cast from " +
node.expr().type().textize() +
" to " + node.type().textize());
}
@ -337,15 +368,16 @@ class TypeChecker extends Visitor {
}
protected void incompatibleTypeError(Type l, Type r) {
handler.error("incompatible type: " +
errorHandler.error("incompatible type: " +
l.textize() + " and " + r.textize());
}
protected void notIntegerError(Type type) {
handler.error("non-integer argument for ++/--: " + type.textize());
errorHandler.error("non-integer argument for unary op: " +
type.textize());
}
protected void notPointerError(Type type) {
handler.error("non-pointer argument: " + type.textize());
errorHandler.error("non-pointer argument: " + type.textize());
}
}

View File

@ -233,7 +233,7 @@ public class Visitor implements ASTVisitor {
public void visit(FuncallNode node) {
resolve(node.expr());
resolveNodeList(node.args());
resolveNodeList(node.arguments());
}
public void visit(VariableNode node) {

View File

@ -23,6 +23,23 @@ public class FunctionType extends Type {
return true;
}
public boolean acceptsArgc(long numArgs) {
if (paramTypes.isVararg()) {
return (numArgs >= paramTypes.minArgc());
}
else {
return (numArgs == paramTypes.argc());
}
}
/**
* Returns iterator of mandatory parameter types.
* This method does NOT include types for varargs.
*/
public Iterator paramTypes() {
return paramTypes.parameters();
}
public long alignment() {
throw new Error("FunctionType#alignment called");
}

View File

@ -37,8 +37,6 @@ public class PointerType extends Type {
return true;
}
//public boolean isArray() { return true; }
public boolean equals(Object other) {
if (! (other instanceof PointerType)) return false;
PointerType otherptr = (PointerType)other;
@ -48,4 +46,8 @@ public class PointerType extends Type {
public String textize() {
return base.textize() + "*";
}
public boolean isCallable() {
return base.isFunction();
}
}

View File

@ -66,4 +66,8 @@ public abstract class Type {
public boolean isCastableTo(Type target) {
return equals(target);
}
public boolean isCallable() {
return false;
}
}