1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/Types.cpp Tue Jul 24 23:53:34 2012 -0700
1.3 @@ -0,0 +1,187 @@
1.4 +/*
1.5 + * Copyright (C) 2012 David Anderson
1.6 + *
1.7 + * This file is part of JITCraft.
1.8 + *
1.9 + * JITCraft is free software: you can redistribute it and/or modify it under
1.10 + * the terms of the GNU General Public License as published by the Free
1.11 + * Software Foundation, either version 3 of the License, or (at your option)
1.12 + * any later version.
1.13 + *
1.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License along with
1.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.20 + */
1.21 +#include "Types.h"
1.22 +#include "Zone.h"
1.23 +#include "Strings.h"
1.24 +#include "Heap-inl.h"
1.25 +
1.26 +using namespace ke;
1.27 +
1.28 +Type *
1.29 +Type::NewVoid(Zone *zone)
1.30 +{
1.31 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.32 + if (!type)
1.33 + return NULL;
1.34 +
1.35 + type->kind_ = VOID;
1.36 + type->tag_ = NULL;
1.37 + type->contained_ = NULL;
1.38 + type->returnType_ = NULL;
1.39 + type->parameters_ = NULL;
1.40 + return type;
1.41 +}
1.42 +
1.43 +Type *
1.44 +Type::NewPrimitive(Zone *zone, Handle<String> tag)
1.45 +{
1.46 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.47 + if (!type)
1.48 + return NULL;
1.49 +
1.50 + type->kind_ = PRIMITIVE;
1.51 + type->tag_ = tag;
1.52 + type->contained_ = NULL;
1.53 + type->returnType_ = NULL;
1.54 + type->parameters_ = NULL;
1.55 +
1.56 + if (tag && strcmp(tag->chars(), "Float") == 0)
1.57 + type->primitive_ = PrimitiveType_Float;
1.58 + else if (tag && strcmp(tag->chars(), "String") == 0)
1.59 + type->primitive_ = PrimitiveType_Char;
1.60 + else
1.61 + type->primitive_ = PrimitiveType_Int32;
1.62 + return type;
1.63 +}
1.64 +
1.65 +Type *
1.66 +Type::NewPrimitive(Zone *zone, PrimitiveType prim)
1.67 +{
1.68 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.69 + if (!type)
1.70 + return NULL;
1.71 +
1.72 + type->kind_ = PRIMITIVE;
1.73 + type->tag_ = NULL;
1.74 + type->contained_ = NULL;
1.75 + type->returnType_ = NULL;
1.76 + type->parameters_ = NULL;
1.77 + type->primitive_ = prim;
1.78 + return type;
1.79 +}
1.80 +
1.81 +Type *
1.82 +Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
1.83 +{
1.84 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.85 + if (!type)
1.86 + return NULL;
1.87 +
1.88 + type->kind_ = ARRAY;
1.89 + type->tag_ = NULL;
1.90 + type->contained_ = contained;
1.91 + type->returnType_ = NULL;
1.92 + type->parameters_ = NULL;
1.93 + type->elements_ = elements;
1.94 + if (contained->isPrimitive())
1.95 + type->levels_ = 1;
1.96 + else
1.97 + type->levels_ = contained->levels() + 1;
1.98 + type->const_ = isConst;
1.99 + return type;
1.100 +}
1.101 +
1.102 +Type *
1.103 +Type::NewReference(Zone *zone, Handle<Type> contained, bool isConst)
1.104 +{
1.105 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.106 + if (!type)
1.107 + return NULL;
1.108 +
1.109 + type->kind_ = REFERENCE;
1.110 + type->tag_ = NULL;
1.111 + type->contained_ = contained;
1.112 + type->returnType_ = NULL;
1.113 + type->parameters_ = NULL;
1.114 + type->const_ = isConst;
1.115 + return type;
1.116 +}
1.117 +
1.118 +Type *
1.119 +Type::NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters)
1.120 +{
1.121 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.122 + if (!type)
1.123 + return NULL;
1.124 +
1.125 + type->kind_ = FUNCTION;
1.126 + type->contained_ = NULL;
1.127 + type->returnType_ = returnType;
1.128 + type->parameters_ = parameters;
1.129 + return type;
1.130 +}
1.131 +
1.132 +Type *
1.133 +Type::NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool variadic)
1.134 +{
1.135 + Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
1.136 + if (!type)
1.137 + return NULL;
1.138 +
1.139 + type->kind_ = NATIVE;
1.140 + type->contained_ = NULL;
1.141 + type->returnType_ = returnType;
1.142 + type->parameters_ = parameters;
1.143 + type->variadicNative_ = variadic;
1.144 + return type;
1.145 +}
1.146 +
1.147 +bool
1.148 +Type::Compare(Type *left, Type *right)
1.149 +{
1.150 + if (left->kind() != right->kind())
1.151 + return false;
1.152 +
1.153 + switch (left->kind()) {
1.154 + case Type::PRIMITIVE:
1.155 + return (left->primitive() == right->primitive() &&
1.156 + left->tag() == right->tag());
1.157 +
1.158 + case Type::ARRAY:
1.159 + {
1.160 + if (left->levels() != right->levels())
1.161 + return false;
1.162 + if (left->elements() != right->elements())
1.163 + return false;
1.164 + return Compare(left->contained(), right->contained());
1.165 + }
1.166 +
1.167 + case Type::FUNCTION:
1.168 + {
1.169 + if (!Compare(left->returnType(), right->returnType()))
1.170 + return false;
1.171 + if (left->parameters()->length() != right->parameters()->length())
1.172 + return false;
1.173 + if (left->isNative() != right->isNative())
1.174 + return false;
1.175 + if (left->isNative() && (left->isNativeVariadic() != right->isNativeVariadic()))
1.176 + return false;
1.177 + for (unsigned i = 0; i < left->parameters()->length(); i++) {
1.178 + Type *leftparam = left->parameterAt(i);
1.179 + Type *rightparam = right->parameterAt(i);
1.180 + if (!Compare(leftparam, rightparam))
1.181 + return false;
1.182 + }
1.183 + return true;
1.184 + }
1.185 +
1.186 + default:
1.187 + assert(left->kind() == Type::REFERENCE);
1.188 + return Compare(left->contained(), right->contained());
1.189 + }
1.190 +}