src/Types.cpp
changeset 86 32ad0523b309
parent 71 f7e573226c2b
child 91 5f4402180204
     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 +}