diff -r 06a0015b6a5c -r 32ad0523b309 src/Types.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/Types.cpp Tue Jul 24 23:53:34 2012 -0700 @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2012 David Anderson + * + * This file is part of JITCraft. + * + * JITCraft is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * JITCraft. If not, see http://www.gnu.org/licenses/. + */ +#include "Types.h" +#include "Zone.h" +#include "Strings.h" +#include "Heap-inl.h" + +using namespace ke; + +Type * +Type::NewVoid(Zone *zone) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = VOID; + type->tag_ = NULL; + type->contained_ = NULL; + type->returnType_ = NULL; + type->parameters_ = NULL; + return type; +} + +Type * +Type::NewPrimitive(Zone *zone, Handle tag) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = PRIMITIVE; + type->tag_ = tag; + type->contained_ = NULL; + type->returnType_ = NULL; + type->parameters_ = NULL; + + if (tag && strcmp(tag->chars(), "Float") == 0) + type->primitive_ = PrimitiveType_Float; + else if (tag && strcmp(tag->chars(), "String") == 0) + type->primitive_ = PrimitiveType_Char; + else + type->primitive_ = PrimitiveType_Int32; + return type; +} + +Type * +Type::NewPrimitive(Zone *zone, PrimitiveType prim) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = PRIMITIVE; + type->tag_ = NULL; + type->contained_ = NULL; + type->returnType_ = NULL; + type->parameters_ = NULL; + type->primitive_ = prim; + return type; +} + +Type * +Type::NewArray(Zone *zone, Handle contained, int elements, bool isConst) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = ARRAY; + type->tag_ = NULL; + type->contained_ = contained; + type->returnType_ = NULL; + type->parameters_ = NULL; + type->elements_ = elements; + if (contained->isPrimitive()) + type->levels_ = 1; + else + type->levels_ = contained->levels() + 1; + type->const_ = isConst; + return type; +} + +Type * +Type::NewReference(Zone *zone, Handle contained, bool isConst) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = REFERENCE; + type->tag_ = NULL; + type->contained_ = contained; + type->returnType_ = NULL; + type->parameters_ = NULL; + type->const_ = isConst; + return type; +} + +Type * +Type::NewFunction(Zone *zone, Handle returnType, Handle parameters) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = FUNCTION; + type->contained_ = NULL; + type->returnType_ = returnType; + type->parameters_ = parameters; + return type; +} + +Type * +Type::NewNative(Zone *zone, Handle returnType, Handle parameters, bool variadic) +{ + Local type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old))); + if (!type) + return NULL; + + type->kind_ = NATIVE; + type->contained_ = NULL; + type->returnType_ = returnType; + type->parameters_ = parameters; + type->variadicNative_ = variadic; + return type; +} + +bool +Type::Compare(Type *left, Type *right) +{ + if (left->kind() != right->kind()) + return false; + + switch (left->kind()) { + case Type::PRIMITIVE: + return (left->primitive() == right->primitive() && + left->tag() == right->tag()); + + case Type::ARRAY: + { + if (left->levels() != right->levels()) + return false; + if (left->elements() != right->elements()) + return false; + return Compare(left->contained(), right->contained()); + } + + case Type::FUNCTION: + { + if (!Compare(left->returnType(), right->returnType())) + return false; + if (left->parameters()->length() != right->parameters()->length()) + return false; + if (left->isNative() != right->isNative()) + return false; + if (left->isNative() && (left->isNativeVariadic() != right->isNativeVariadic())) + return false; + for (unsigned i = 0; i < left->parameters()->length(); i++) { + Type *leftparam = left->parameterAt(i); + Type *rightparam = right->parameterAt(i); + if (!Compare(leftparam, rightparam)) + return false; + } + return true; + } + + default: + assert(left->kind() == Type::REFERENCE); + return Compare(left->contained(), right->contained()); + } +}