mirror of https://github.com/aamine/cbc
* 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:
parent
1e4ac4dabf
commit
6e3734fcc0
28
ChangeLog
28
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -15,4 +15,8 @@ abstract public class Node {
|
|||
public AsmEntity address() {
|
||||
throw new Error("Node#address");
|
||||
}
|
||||
|
||||
public boolean isCallable() {
|
||||
return type().isCallable();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,4 +66,8 @@ public abstract class Type {
|
|||
public boolean isCastableTo(Type target) {
|
||||
return equals(target);
|
||||
}
|
||||
|
||||
public boolean isCallable() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue