src/Types.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jul 30 12:13:22 2012 -0700 (2012-07-30)
changeset 142 a000bafece09
parent 124 0d7ac9ba25c2
child 143 393f1b8ac8c3
permissions -rw-r--r--
Implement re-tag unary expression.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #include <string.h>
    19 #include "Types.h"
    20 #include "Zone.h"
    21 #include "Strings.h"
    22 #include "Heap-inl.h"
    23 
    24 using namespace ke;
    25 
    26 Type *
    27 Type::NewVoid(Zone *zone)
    28 {
    29     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    30     if (!type)
    31         return NULL;
    32 
    33     type->kind_ = VOID;
    34     type->tag_ = NULL;
    35     type->contained_ = NULL;
    36     type->returnType_ = NULL;
    37     type->parameters_ = NULL;
    38     return type;
    39 }
    40 
    41 Type *
    42 Type::NewPrimitive(Zone *zone, Handle<String> tag)
    43 {
    44     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    45     if (!type)
    46         return NULL;
    47 
    48     assert(!tag || strcmp(tag->chars(), "_"));
    49 
    50     type->kind_ = PRIMITIVE;
    51     type->tag_ = tag;
    52     type->contained_ = NULL;
    53     type->returnType_ = NULL;
    54     type->parameters_ = NULL;
    55 
    56     if (tag && strcmp(tag->chars(), "Float") == 0)
    57         type->primitive_ = PrimitiveType_Float;
    58     else if (tag && strcmp(tag->chars(), "String") == 0)
    59         type->primitive_ = PrimitiveType_Char;
    60     else
    61         type->primitive_ = PrimitiveType_Int32;
    62     return type;
    63 }
    64 
    65 Type *
    66 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
    67 {
    68     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    69     if (!type)
    70         return NULL;
    71 
    72     type->kind_ = PRIMITIVE;
    73     type->tag_ = NULL;
    74     type->contained_ = NULL;
    75     type->returnType_ = NULL;
    76     type->parameters_ = NULL;
    77     type->primitive_ = prim;
    78     return type;
    79 }
    80 
    81 Type *
    82 Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
    83 {
    84     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    85     if (!type)
    86         return NULL;
    87 
    88     type->kind_ = ARRAY;
    89     type->tag_ = NULL;
    90     type->contained_ = contained;
    91     type->returnType_ = NULL;
    92     type->parameters_ = NULL;
    93     type->elements_ = elements;
    94     if (contained->isPrimitive())
    95         type->levels_ = 1;
    96     else
    97         type->levels_ = contained->levels() + 1;
    98     type->const_ = isConst;
    99     return type;
   100 }
   101 
   102 Type *
   103 Type::NewReference(Zone *zone, Handle<Type> contained, bool isConst)
   104 {
   105     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   106     if (!type)
   107         return NULL;
   108 
   109     type->kind_ = REFERENCE;
   110     type->tag_ = NULL;
   111     type->contained_ = contained;
   112     type->returnType_ = NULL;
   113     type->parameters_ = NULL;
   114     type->const_ = isConst;
   115     return type;
   116 }
   117 
   118 Type *
   119 Type::NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters)
   120 {
   121     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   122     if (!type)
   123         return NULL;
   124 
   125     type->kind_ = FUNCTION;
   126     type->contained_ = NULL;
   127     type->returnType_ = returnType;
   128     type->parameters_ = parameters;
   129     return type;
   130 }
   131 
   132 Type *
   133 Type::NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool variadic)
   134 {
   135     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   136     if (!type)
   137         return NULL;
   138 
   139     type->kind_ = NATIVE;
   140     type->contained_ = NULL;
   141     type->returnType_ = returnType;
   142     type->parameters_ = parameters;
   143     type->variadicNative_ = variadic;
   144     return type;
   145 }
   146 
   147 bool
   148 Type::Compare(Type *left, Type *right)
   149 {
   150     if (left->kind() != right->kind())
   151         return false;
   152 
   153     switch (left->kind()) {
   154       case Type::PRIMITIVE:
   155         return (left->primitive() == right->primitive() &&
   156                 left->tag() == right->tag());
   157 
   158       case Type::ARRAY:
   159       {
   160         if (left->levels() != right->levels())
   161           return false;
   162         if (left->elements() != right->elements())
   163           return false;
   164         return Compare(left->contained(), right->contained());
   165       }
   166 
   167       case Type::FUNCTION:
   168       {
   169         if (!Compare(left->returnType(), right->returnType()))
   170             return false;
   171         if (left->parameters()->length() != right->parameters()->length())
   172             return false;
   173         if (left->isNative() != right->isNative())
   174             return false;
   175         if (left->isNative() && (left->isNativeVariadic() != right->isNativeVariadic()))
   176             return false;
   177         for (unsigned i = 0; i < left->parameters()->length(); i++) {
   178             Type *leftparam = left->parameterAt(i);
   179             Type *rightparam = right->parameterAt(i);
   180             if (!Compare(leftparam, rightparam))
   181                 return false;
   182         }
   183         return true;
   184       }
   185 
   186       case Type::VOID:
   187       	return true;
   188 
   189       default:
   190         assert(left->kind() == Type::REFERENCE);
   191         return Compare(left->contained(), right->contained());
   192     }
   193 }