* net/loveruby/cflat/type/Type.java: make #isCompatible and #isCastable abstract.

* net/loveruby/cflat/type/VoidType.java: define #equals, #isSameType, #isCompatible, #isCastableTo.
* net/loveruby/cflat/type/ComplexType.java: define #isSameType, #isCompatible, #isCastableTo, #memberTypes.
* net/loveruby/cflat/type/ArrayType.java: define #isCompatible, #isCastableTo.
* net/loveruby/cflat/type/PointerType.java (isCompatible): void pointer is compatible with any pointer.
* net/loveruby/cflat/type/FunctionType.java: check parameter types.
* net/loveruby/cflat/ast/Params.java: define #types and #isSameType to be used from FunctionType.
* net/loveruby/cflat/ast/FixedParams.java: ditto.
* net/loveruby/cflat/ast/VarParams.java: ditto.
* net/loveruby/cflat/type/TypeTable.java: new method #voidType.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3818 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-01-12 19:47:28 +00:00
parent 3c73577871
commit a88b9a2bca
11 changed files with 173 additions and 7 deletions

View File

@ -1,3 +1,32 @@
Sun Jan 13 04:47:12 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/type/Type.java: make #isCompatible and
#isCastable abstract.
* net/loveruby/cflat/type/VoidType.java: define #equals,
#isSameType, #isCompatible, #isCastableTo.
* net/loveruby/cflat/type/ComplexType.java: define #isSameType,
#isCompatible, #isCastableTo, #memberTypes.
* net/loveruby/cflat/type/ArrayType.java: define #isCompatible,
#isCastableTo.
* net/loveruby/cflat/type/PointerType.java (isCompatible): void
pointer is compatible with any pointer.
* net/loveruby/cflat/type/FunctionType.java: check parameter
types.
* net/loveruby/cflat/ast/Params.java: define #types and
#isSameType to be used from FunctionType.
* net/loveruby/cflat/ast/FixedParams.java: ditto.
* net/loveruby/cflat/ast/VarParams.java: ditto.
* net/loveruby/cflat/type/TypeTable.java: new method #voidType.
Sun Jan 13 04:34:30 2008 Minero Aoki <aamine@loveruby.net>
* test/unistd.hb: define _exit.

View File

@ -74,4 +74,24 @@ public class FixedParams extends Params {
}
return new FixedParams(location, typerefs);
}
/** parameters is a list of Type when
* this object is hold in FunctionType. */
public Iterator types() {
return parameters.iterator();
}
public boolean isSameType(Params other) {
if (other.isVararg()) return false;
if (other.argc() != argc()) return false;
Iterator types = types();
Iterator otherTypes = other.types();
while (types.hasNext()) {
Type t = (Type)types.next();
Type tt = (Type)otherTypes.next();
if (t.isSameType(t))
return false;
}
return true;
}
}

View File

@ -1,5 +1,5 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.TypeTable;
import net.loveruby.cflat.type.*;
import java.util.*;
abstract public class Params extends Node {
@ -14,6 +14,8 @@ abstract public class Params extends Node {
abstract public boolean equals(Object other);
abstract public Params internTypes(TypeTable table);
abstract public Params typeRefs();
abstract public Iterator types();
abstract public boolean isSameType(Params other);
protected void _dump(Dumper d) {
d.printNodeList("parameters", parameters());

View File

@ -44,6 +44,16 @@ public class VarParams extends Params {
return new VarParams((FixedParams)params.typeRefs());
}
public Iterator types() {
return params.types();
}
public boolean isSameType(Params other) {
if (!other.isVararg()) return false;
VarParams otherParams = (VarParams)other;
return this.fixedParams().isSameType(otherParams.fixedParams());
}
public Location location() {
return params.location();
}

View File

@ -51,6 +51,16 @@ public class ArrayType extends Type {
return baseType.isSameType(other.baseType());
}
public boolean isCompatible(Type target) {
if (! target.isDereferable()) return false;
return baseType.isCompatible(target.baseType())
&& baseType.size() == target.baseType().size();
}
public boolean isCastableTo(Type target) {
return target.isDereferable();
}
public String toString() {
if (length < 0) {
return baseType.toString() + "[]";

View File

@ -3,6 +3,7 @@ import net.loveruby.cflat.ast.Slot;
import net.loveruby.cflat.ast.Location;
import net.loveruby.cflat.exception.*;
import java.util.*;
import java.lang.reflect.*;
abstract public class ComplexType extends NamedType {
protected List members; // List<Slot>
@ -20,6 +21,53 @@ abstract public class ComplexType extends NamedType {
return true;
}
public boolean isSameType(Type other) {
return compareMemberTypes(other, "isSameType");
}
public boolean isCompatible(Type target) {
return compareMemberTypes(target, "isCompatible");
}
public boolean isCastableTo(Type target) {
return compareMemberTypes(target, "isCastableTo");
}
protected boolean compareMemberTypes(Type other, String cmpMethod) {
if (isStruct() && !other.isStruct()) return false;
if (isUnion() && !other.isUnion()) return false;
ComplexType otherType = other.getComplexType();
if (members.size() != other.size()) return false;
Iterator types = memberTypes();
Iterator otherTypes = otherType.memberTypes();
while (types.hasNext()) {
if (! compareTypesBy(cmpMethod,
(Type)types.next(),
(Type)otherTypes.next())) {
return false;
}
}
return true;
}
protected boolean compareTypesBy(String cmpMethod, Type t, Type tt) {
try {
Method cmp = Type.class.getMethod(cmpMethod,
new Class[] { Type.class });
Boolean b = (Boolean)cmp.invoke(t, new Object[] { tt });
return b.booleanValue();
}
catch (NoSuchMethodException ex) {
throw new Error(ex.getMessage());
}
catch (IllegalAccessException ex) {
throw new Error(ex.getMessage());
}
catch (InvocationTargetException ex) {
throw new Error(ex.getMessage());
}
}
public long size() {
if (size == Type.sizeUnknown) {
computeOffsets();
@ -27,10 +75,21 @@ abstract public class ComplexType extends NamedType {
return size;
}
/** Returns a List<Slot> of members. */
public Iterator members() {
return members.iterator();
}
/** Returns a List<Type> of members. */
public Iterator memberTypes() {
Iterator membs = members.iterator();
List result = new ArrayList();
while (membs.hasNext()) {
result.add(((Slot)membs.next()).type());
}
return result.iterator();
}
public boolean hasMember(String name) {
return (get(name) != null);
}

View File

@ -15,7 +15,20 @@ public class FunctionType extends Type {
public boolean isSameType(Type other) {
if (! other.isFunction()) return false;
return equals(other.getFunctionType());
FunctionType t = other.getFunctionType();
return t.returnType.isSameType(returnType)
&& t.paramTypes.isSameType(paramTypes);
}
public boolean isCompatible(Type target) {
if (! target.isFunction()) return false;
FunctionType t = target.getFunctionType();
return t.returnType.isCompatible(returnType)
&& t.paramTypes.isSameType(paramTypes);
}
public boolean isCastableTo(Type target) {
return target.isFunction();
}
public Type returnType() {

View File

@ -32,8 +32,12 @@ public class PointerType extends Type {
return baseType.isSameType(other.baseType());
}
public boolean isComptible(Type other) {
return isSameType(other);
public boolean isCompatible(Type other) {
if (! other.isDereferable()) return false;
if (baseType.isVoid() && ! other.baseType().isPointer()) {
return true;
}
return baseType.isCompatible(other.baseType());
}
public boolean isCastableTo(Type other) {

View File

@ -34,8 +34,8 @@ public abstract class Type {
public boolean isCallable() { return false; }
// Ability methods (binary)
public boolean isCompatible(Type other) { return false; }
public boolean isCastableTo(Type target) { return isCompatible(target); }
abstract public boolean isCompatible(Type other);
abstract public boolean isCastableTo(Type target);
public Type baseType() {
throw new SemanticError("#baseType called for undereferable type");

View File

@ -83,6 +83,10 @@ public class TypeTable {
return table.values().iterator();
}
public VoidType voidType() {
return (VoidType)table.get(new VoidTypeRef());
}
public IntegerType signedChar() {
return (IntegerType)table.get(IntegerTypeRef.charRef());
}

View File

@ -5,12 +5,27 @@ public class VoidType extends Type {
}
public boolean isVoid() { return true; }
public boolean isSameType(Type other) { return other.isVoid(); }
public long size() {
throw new Error("VoidType#size called");
}
public boolean equals(Object other) {
return (other instanceof VoidType);
}
public boolean isSameType(Type other) {
return other.isVoid();
}
public boolean isCompatible(Type other) {
return other.isVoid();
}
public boolean isCastableTo(Type other) {
return other.isVoid();
}
public String toString() {
return "void";
}