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