src/Types.h
author David Anderson <dvander@alliedmods.net>
Sun Jan 27 17:34:30 2013 -0800 (2013-01-27)
changeset 261 219b49bf4a03
parent 258 241d082d6d89
permissions -rw-r--r--
Add support for importing enum types and enum values (as constexprs).
dvander@238
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@238
     2
 *
dvander@238
     3
 * Copyright (C) 2012 David Anderson
dvander@238
     4
 *
dvander@238
     5
 * This file is part of JITCraft.
dvander@238
     6
 *
dvander@238
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@238
     8
 * the terms of the GNU General Public License as published by the Free
dvander@238
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@238
    10
 * any later version.
dvander@238
    11
 * 
dvander@238
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@238
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@238
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@238
    15
 *
dvander@238
    16
 * You should have received a copy of the GNU General Public License along with
dvander@238
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@238
    18
 */
dvander@238
    19
#ifndef _include_jc_types_h_
dvander@238
    20
#define _include_jc_types_h_
dvander@238
    21
dvander@238
    22
#include "Heap.h"
dvander@238
    23
#include "Barriers.h"
dvander@238
    24
#include "FixedArray.h"
dvander@238
    25
#include "compiler/Token.h"
dvander@238
    26
dvander@238
    27
namespace ke {
dvander@238
    28
dvander@238
    29
class String;
dvander@238
    30
class Descriptor;
dvander@238
    31
class StructMap;
dvander@238
    32
class ArrayMap;
dvander@238
    33
dvander@238
    34
#define MAX_ARRAY_DEPTH     5
dvander@238
    35
dvander@238
    36
enum PrimitiveType
dvander@238
    37
{
dvander@238
    38
    // A boolean type semantically represents 0 or 1. As an optimization, its
dvander@238
    39
    // internal storage type is the same as int32, and any non-zero value
dvander@238
    40
    // compares positively to "true".
dvander@238
    41
    PrimitiveType_Bool,
dvander@238
    42
dvander@238
    43
    // A character is an arbitrary 8-bit value. Characters are not supported
dvander@238
    44
    // as a normal storage class; they may only be used for arrays. When read
dvander@238
    45
    // from an array, they are immediately sign extended to 32 bits. Integers
dvander@238
    46
    // stored into an char array are truncated to 8 bits.
dvander@238
    47
    PrimitiveType_Char,         // signed, 8-bit character
dvander@238
    48
dvander@238
    49
    // Enumerations and untyped variables are stored as signed, 32-bit integers.
dvander@238
    50
    PrimitiveType_Int32,
dvander@238
    51
dvander@238
    52
    // Floating point values are 32-bit IEEE-754 floats. This is required ro
dvander@238
    53
    // SourcePawn 1 compatibility.
dvander@238
    54
    PrimitiveType_Float,
dvander@238
    55
dvander@238
    56
    // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
dvander@238
    57
    // on 64-bit systems), and does not exist in language semantics.
dvander@238
    58
    PrimitiveType_Native,
dvander@238
    59
dvander@238
    60
    PrimitiveTypes_Total
dvander@238
    61
};
dvander@238
    62
dvander@238
    63
enum TypeQualifiers
dvander@238
    64
{
dvander@238
    65
    TypeQual_None           = 0,
dvander@238
    66
dvander@241
    67
    // Values of this type cannot be modified.
dvander@261
    68
    TypeQual_Const       = (1 << 0),
dvander@261
    69
dvander@261
    70
    // Values of this type can be treated as constant expressions. This allows
dvander@261
    71
    // us to export compile-time constants from modules.
dvander@261
    72
    TypeQual_ConstExpr   = (1 << 1)
dvander@238
    73
};
dvander@238
    74
dvander@238
    75
class Type : public Object
dvander@238
    76
{
dvander@238
    77
  protected:
dvander@238
    78
    enum Kind {
dvander@238
    79
        // A primitive is a plain-old-data type.
dvander@238
    80
        PRIMITIVE,
dvander@238
    81
dvander@238
    82
        // Void is an internal type used to specify that a function returns no
dvander@238
    83
        // value.
dvander@238
    84
        VOID,
dvander@238
    85
dvander@238
    86
        // Enums are plain-old-data with int32 storage. They allow for extra
dvander@238
    87
        // type checking that would not be possible with integers.
dvander@238
    88
        ENUM,
dvander@238
    89
dvander@238
    90
        // Unchecked is a magic type that has implicit, bitwise coercion to
dvander@238
    91
        // int32, float, bool, or an enum.
dvander@238
    92
        UNCHECKED,
dvander@238
    93
dvander@239
    94
        // Contains type qualifiers, and a back pointer to the actual
dvander@239
    95
        // unqualified type.
dvander@239
    96
        QUALTYPE,
dvander@239
    97
dvander@239
    98
        // ------ Add traceable types below (STRING FIRST!) -------
dvander@238
    99
dvander@238
   100
        // An immutable type that is a primitive in terms of language
dvander@238
   101
        // semantics, but gets a special type here to make internal
dvander@238
   102
        // logic easier.
dvander@238
   103
        STRING,
dvander@238
   104
dvander@238
   105
        // An array is a fixed-length vector of any other type.
dvander@238
   106
        ARRAY,
dvander@238
   107
        EXTERNAL_ARRAY,
dvander@238
   108
dvander@238
   109
        // A reference type may only be specified on parameters, and
dvander@238
   110
        // references may only be computed to primitives or enums.
dvander@238
   111
        REFERENCE,
dvander@238
   112
dvander@238
   113
        // A function type encapsulates a function signature.
dvander@238
   114
        FUNCTION,
dvander@238
   115
dvander@238
   116
        // Structs are composite records that may contain primitives, arrays,
dvander@238
   117
        // functions, enums, and other structs.
dvander@256
   118
        STRUCT,
dvander@256
   119
dvander@256
   120
        // Importable types are mainly used during the compilation process
dvander@256
   121
        // to distinguish between normal names and static imports.
dvander@261
   122
        IMPORTABLE,
dvander@261
   123
dvander@261
   124
        // The type of types.
dvander@261
   125
        TYPE
dvander@238
   126
    };
dvander@238
   127
dvander@240
   128
    void init(Kind kind, Type *root = NULL);
dvander@238
   129
dvander@238
   130
  private:
dvander@238
   131
    Kind kind() {
dvander@238
   132
        return root_->kind_;
dvander@238
   133
    }
dvander@238
   134
dvander@238
   135
  public:   
dvander@238
   136
    static Type *NewVoid(Zone *zone);
dvander@238
   137
    static Type *NewUnchecked(Zone *zone);
dvander@261
   138
    static Type *NewType(Zone *zone);
dvander@238
   139
    static Type *NewPrimitive(Zone *zone, PrimitiveType type);
dvander@238
   140
    static Type *NewString(Zone *zone);
dvander@240
   141
    static Type *NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> type);
dvander@256
   142
    static Type *NewImportable(Zone *zone);
dvander@238
   143
dvander@238
   144
    static Type *cast(Object *obj) {
dvander@238
   145
        assert(!obj ||
dvander@238
   146
               obj->is(MapKind_Type) ||
dvander@238
   147
               obj->is(MapKind_FunctionType) ||
dvander@238
   148
               obj->is(MapKind_StructType) ||
dvander@238
   149
               obj->is(MapKind_ArrayType) ||
dvander@238
   150
               obj->is(MapKind_ReferenceType) ||
dvander@238
   151
               obj->is(MapKind_EnumType));
dvander@238
   152
        return (Type *)obj;
dvander@238
   153
    }
dvander@238
   154
dvander@238
   155
    bool isPrimitive() {
dvander@238
   156
        return kind() == PRIMITIVE;
dvander@238
   157
    }
dvander@238
   158
    bool isArray() {
dvander@238
   159
        return kind() == ARRAY || kind() == EXTERNAL_ARRAY;
dvander@238
   160
    }
dvander@238
   161
    bool isReference() {
dvander@238
   162
        return kind() == REFERENCE;
dvander@238
   163
    }
dvander@238
   164
    bool isFunction() {
dvander@238
   165
        return kind() == FUNCTION;
dvander@238
   166
    }
dvander@238
   167
    bool isVoid() {
dvander@238
   168
        return kind() == VOID;
dvander@238
   169
    }
dvander@238
   170
    bool isUnchecked() {
dvander@238
   171
        return kind() == UNCHECKED;
dvander@238
   172
    }
dvander@238
   173
    bool isStruct() {
dvander@238
   174
        return kind() == STRUCT;
dvander@238
   175
    }
dvander@256
   176
    bool isImportable() {
dvander@256
   177
        return kind() == IMPORTABLE;
dvander@256
   178
    }
dvander@238
   179
    PrimitiveType primitive() {
dvander@238
   180
        assert(isPrimitive());
dvander@238
   181
        return root_->primitive_;
dvander@238
   182
    }
dvander@238
   183
    bool isPod() {
dvander@238
   184
        return (isPrimitive() && !isString()) || isEnum() || isUnchecked();
dvander@238
   185
    }
dvander@238
   186
    PrimitiveType pod() {
dvander@238
   187
        assert(isPod());
dvander@238
   188
        return isPrimitive()
dvander@238
   189
               ? (primitive() == PrimitiveType_Bool)
dvander@238
   190
                 ? PrimitiveType_Int32
dvander@238
   191
                 : primitive()
dvander@238
   192
               : PrimitiveType_Int32;
dvander@238
   193
    }
dvander@238
   194
    bool isChar() {
dvander@238
   195
        return isPrimitive() && primitive() == PrimitiveType_Char;
dvander@238
   196
    }
dvander@238
   197
    bool isFloat() {
dvander@238
   198
        return isPrimitive() && primitive() == PrimitiveType_Float;
dvander@238
   199
    }
dvander@238
   200
    bool isInt32() {
dvander@238
   201
        return isPrimitive() && primitive() == PrimitiveType_Int32;
dvander@238
   202
    }
dvander@238
   203
    bool isInt32OrEnum() {
dvander@238
   204
        return isInt32() || isEnum();
dvander@238
   205
    }
dvander@238
   206
    bool isBool() {
dvander@238
   207
        return isPrimitive() && primitive() == PrimitiveType_Bool;
dvander@238
   208
    }
dvander@238
   209
    bool isString() {
dvander@238
   210
        return kind() == STRING;
dvander@238
   211
    }
dvander@238
   212
    bool isExternalArray() {
dvander@238
   213
        return kind() == EXTERNAL_ARRAY;
dvander@238
   214
    }
dvander@238
   215
    bool isTraceable() {
dvander@238
   216
        return kind() >= STRING;
dvander@238
   217
    }
dvander@238
   218
    bool isEnum() {
dvander@238
   219
        return kind() == ENUM;
dvander@238
   220
    }
dvander@261
   221
    bool isType() {
dvander@261
   222
        return kind() == TYPE;
dvander@261
   223
    }
dvander@238
   224
    bool hasTypeQualifiers() {
dvander@238
   225
        return kind_ == QUALTYPE;
dvander@238
   226
    }
dvander@238
   227
dvander@238
   228
    TypeQualifiers quals() {
dvander@241
   229
        if (!hasTypeQualifiers())
dvander@238
   230
            return TypeQual_None;
dvander@238
   231
        return quals_;
dvander@238
   232
    }
dvander@239
   233
    Type *unqualified() {
dvander@239
   234
        return root_;
dvander@239
   235
    }
dvander@238
   236
dvander@238
   237
    // GC Descriptor.
dvander@238
   238
    static inline size_t offsetOfRoot() {
dvander@238
   239
        return OFFSETOF(Type, root_);
dvander@238
   240
    }
dvander@238
   241
    // End GC Descriptor.
dvander@238
   242
dvander@238
   243
  protected:
dvander@238
   244
    Kind kind_;
dvander@238
   245
    PrimitiveType primitive_;
dvander@238
   246
    TypeQualifiers quals_;
dvander@238
   247
dvander@238
   248
    // For unqualified types, this points to |this|. For qualified types, it
dvander@238
   249
    // points to the unqualified original type.
dvander@238
   250
    Barriered<Type> root_;
dvander@238
   251
};
dvander@238
   252
dvander@238
   253
class EnumType : public Type
dvander@238
   254
{
dvander@238
   255
  public:
dvander@238
   256
    static EnumType *New(Zone *Zone, Handle<String> name);
dvander@238
   257
dvander@238
   258
    String *name() {
dvander@238
   259
        return name_;
dvander@238
   260
    }
dvander@238
   261
dvander@238
   262
    // GC Descriptor.
dvander@238
   263
    static inline size_t offsetOfName() {
dvander@238
   264
        return OFFSETOF(EnumType, name_);
dvander@238
   265
    }
dvander@261
   266
    static inline size_t offsetOfFields() {
dvander@261
   267
        return OFFSETOF(EnumType, fields_);
dvander@261
   268
    }
dvander@238
   269
    // End GC Descriptor.
dvander@238
   270
dvander@238
   271
    static EnumType *cast(Object *obj) {
dvander@238
   272
        assert(!obj || obj->is(MapKind_EnumType));
dvander@238
   273
        return (EnumType *)obj;
dvander@238
   274
    }
dvander@238
   275
dvander@238
   276
  private:
dvander@238
   277
    Barriered<String> name_;
dvander@261
   278
    Barriered<FixedArray> fields_;
dvander@238
   279
};
dvander@238
   280
dvander@238
   281
class ReferenceType : public Type
dvander@238
   282
{
dvander@238
   283
  public:
dvander@238
   284
    static ReferenceType *New(Zone *zone, Handle<Type> contained);
dvander@238
   285
    
dvander@238
   286
    Type *contained() {
dvander@238
   287
        return contained_;
dvander@238
   288
    }
dvander@238
   289
dvander@238
   290
    // GC Descriptor.
dvander@238
   291
    static inline size_t offsetOfContained() {
dvander@238
   292
        return OFFSETOF(ReferenceType, contained_);
dvander@238
   293
    }
dvander@238
   294
    // End GC Descriptor.
dvander@238
   295
dvander@239
   296
    static ReferenceType *cast(Type *obj) {
dvander@239
   297
        if (!obj)
dvander@239
   298
            return NULL;
dvander@239
   299
        obj = obj->unqualified();
dvander@239
   300
        assert(obj->is(MapKind_ReferenceType));
dvander@238
   301
        return (ReferenceType *)obj;
dvander@238
   302
    }
dvander@238
   303
dvander@238
   304
  private:
dvander@238
   305
    Barriered<Type> contained_;
dvander@238
   306
};
dvander@238
   307
dvander@238
   308
class ArrayType : public Type
dvander@238
   309
{
dvander@238
   310
  public:
dvander@238
   311
    static const int DYNAMIC_ARRAY_SIZE = -1;
dvander@238
   312
dvander@238
   313
    static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
dvander@238
   314
    static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
dvander@238
   315
dvander@238
   316
    Type *innermost() {
dvander@238
   317
        Type *temp = contained();
dvander@238
   318
        while (temp->isArray())
dvander@238
   319
            temp = ArrayType::cast(temp)->contained();
dvander@238
   320
        return temp;
dvander@238
   321
    }
dvander@238
   322
dvander@247
   323
    bool isDynamic() {
dvander@247
   324
        return elements_ == DYNAMIC_ARRAY_SIZE;
dvander@247
   325
    }
dvander@247
   326
    bool isExtensible() {
dvander@247
   327
        return isDynamic() && !(quals_ & TypeQual_Const);
dvander@247
   328
    }
dvander@238
   329
    Type *contained() {
dvander@238
   330
        return contained_;
dvander@238
   331
    }
dvander@238
   332
    bool isFixedLength() {
dvander@238
   333
        return elements_ > 0;
dvander@238
   334
    }
dvander@238
   335
    bool isCharArray() {
dvander@238
   336
        return contained()->isPrimitive() &&
dvander@238
   337
               contained()->primitive() == PrimitiveType_Char;
dvander@238
   338
    }
dvander@238
   339
    unsigned fixedLength() {
dvander@238
   340
        assert(isFixedLength());
dvander@238
   341
        return elements_;
dvander@238
   342
    }
dvander@238
   343
    unsigned levels() {
dvander@238
   344
        return levels_;
dvander@238
   345
    }
dvander@238
   346
    bool hasInlineElements() {
dvander@238
   347
        // We don't allocate traceable elements inline, since there's no
dvander@238
   348
        // point to the optimization; we're going to be allocating lots of
dvander@238
   349
        // objects anyway (in theory).
dvander@238
   350
        return isFixedLength() && !contained()->isTraceable();
dvander@238
   351
    }
dvander@238
   352
dvander@238
   353
    // Arrays of this type can be created with this cached map.
dvander@238
   354
    ArrayMap *newMap() {
dvander@238
   355
        return newMap_;
dvander@238
   356
    }
dvander@238
   357
    void setNewMap(ArrayMap *map) {
dvander@238
   358
        assert(!newMap());
dvander@238
   359
        newMap_ = map;
dvander@238
   360
    }
dvander@238
   361
dvander@238
   362
    // GC Descriptor.
dvander@238
   363
    static inline size_t offsetOfContained() {
dvander@238
   364
        return OFFSETOF(ArrayType, contained_);
dvander@238
   365
    }
dvander@238
   366
    static inline size_t offsetOfNewMap() {
dvander@238
   367
        return OFFSETOF(ArrayType, newMap_);
dvander@238
   368
    }
dvander@238
   369
    // End GC Descriptor.
dvander@238
   370
dvander@239
   371
    static ArrayType *cast(Type *obj) {
dvander@239
   372
        if (!obj)
dvander@239
   373
            return NULL;
dvander@239
   374
        obj = obj->unqualified();
dvander@239
   375
        assert(obj->is(MapKind_ArrayType));
dvander@238
   376
        return (ArrayType *)obj;
dvander@238
   377
    }
dvander@238
   378
dvander@238
   379
  private:
dvander@238
   380
    int32 elements_;
dvander@238
   381
    unsigned levels_;
dvander@238
   382
    Barriered<Type> contained_;
dvander@238
   383
    Barriered<ArrayMap> newMap_;
dvander@238
   384
};
dvander@238
   385
dvander@238
   386
class StructType : public Type
dvander@238
   387
{
dvander@238
   388
  public:
dvander@238
   389
    static StructType *New(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
dvander@238
   390
dvander@238
   391
    FixedArray *fields() {
dvander@238
   392
        assert(isStruct());
dvander@238
   393
        return fields_;
dvander@238
   394
    }
dvander@258
   395
    Descriptor *lookupField(String *name, unsigned *index = NULL);
dvander@238
   396
dvander@238
   397
    // Objects of this type can be created with this cached map.
dvander@238
   398
    StructMap *newMap() {
dvander@238
   399
        return newMap_;
dvander@238
   400
    }
dvander@238
   401
    void setNewMap(StructMap *map) {
dvander@238
   402
        assert(!newMap());
dvander@238
   403
        newMap_ = map;
dvander@238
   404
    }
dvander@238
   405
dvander@238
   406
    String *name() {
dvander@238
   407
        return name_;
dvander@238
   408
    }
dvander@238
   409
dvander@238
   410
    // GC Descriptor.
dvander@238
   411
    static inline size_t offsetOfFields() {
dvander@238
   412
        return OFFSETOF(StructType, fields_);
dvander@238
   413
    }
dvander@238
   414
    static inline size_t offsetOfNewMap() {
dvander@238
   415
        return OFFSETOF(StructType, newMap_);
dvander@238
   416
    }
dvander@238
   417
    static inline size_t offsetOfName() {
dvander@238
   418
        return OFFSETOF(StructType, name_);
dvander@238
   419
    }
dvander@238
   420
    // End GC Descriptor.
dvander@238
   421
dvander@239
   422
    static StructType *cast(Type *obj) {
dvander@239
   423
        if (!obj)
dvander@239
   424
            return NULL;
dvander@239
   425
        obj = obj->unqualified();
dvander@239
   426
        assert(obj->is(MapKind_StructType));
dvander@238
   427
        return (StructType *)obj;
dvander@238
   428
    }
dvander@238
   429
dvander@238
   430
  private:
dvander@238
   431
    // Structs only.
dvander@238
   432
    Barriered<FixedArray> fields_;
dvander@238
   433
    Barriered<StructMap> newMap_;
dvander@238
   434
    Barriered<String> name_;
dvander@238
   435
};
dvander@238
   436
dvander@238
   437
class FunctionType : public Type
dvander@238
   438
{
dvander@238
   439
  public:
dvander@238
   440
    static FunctionType *New(Zone *zone, Handle<String> name, TokenKind kind);
dvander@238
   441
dvander@238
   442
    Type *parameterAt(size_t i) {
dvander@238
   443
        return Type::cast(parameters()->at(i));
dvander@238
   444
    }
dvander@238
   445
    Type *returnType() {
dvander@238
   446
        assert(isFunction());
dvander@238
   447
        return returnType_;
dvander@238
   448
    }
dvander@238
   449
    FixedArray *parameters() {
dvander@238
   450
        assert(isFunction());
dvander@238
   451
        return parameters_;
dvander@238
   452
    }
dvander@238
   453
    FixedArray *defaults() {
dvander@238
   454
        assert(isFunction());
dvander@238
   455
        return defaults_;
dvander@238
   456
    }
dvander@238
   457
    bool isNative() {
dvander@238
   458
        return token_ == TOK_NATIVE;
dvander@238
   459
    }
dvander@238
   460
    bool isForward() {
dvander@238
   461
        return token_ == TOK_FORWARD;
dvander@238
   462
    }
dvander@238
   463
    bool isNativeVariadic() {
dvander@238
   464
        assert(isNative());
dvander@238
   465
        return variadicNative_;
dvander@238
   466
    }
dvander@247
   467
    void setVariadic() {
dvander@247
   468
        assert(isNative());
dvander@247
   469
        variadicNative_ = true;
dvander@247
   470
    }
dvander@238
   471
    void setReturnType(Handle<Type> returnType) {
dvander@238
   472
        assert(!returnType_);
dvander@238
   473
        returnType_ = returnType;
dvander@238
   474
    }
dvander@238
   475
    void setParameterTypes(Handle<FixedArray> types) {
dvander@238
   476
        assert(!parameters_);
dvander@238
   477
        parameters_ = types;
dvander@238
   478
    }
dvander@238
   479
    TokenKind token() {
dvander@238
   480
        return token_;
dvander@238
   481
    }
dvander@238
   482
    String *name() {
dvander@238
   483
        return name_;
dvander@238
   484
    }
dvander@238
   485
dvander@238
   486
    // GC Descriptor.
dvander@238
   487
    static inline size_t offsetOfReturnType() {
dvander@238
   488
        return OFFSETOF(FunctionType, returnType_);
dvander@238
   489
    }
dvander@238
   490
    static inline size_t offsetOfParameters() {
dvander@238
   491
        return OFFSETOF(FunctionType, parameters_);
dvander@238
   492
    }
dvander@238
   493
    static inline size_t offsetOfDefaults() {
dvander@238
   494
        return OFFSETOF(FunctionType, defaults_);
dvander@238
   495
    }
dvander@238
   496
    static inline size_t offsetOfName() {
dvander@238
   497
        return OFFSETOF(FunctionType, name_);
dvander@238
   498
    }
dvander@238
   499
    // End GC Descriptor.
dvander@238
   500
dvander@239
   501
    static FunctionType *cast(Type *obj) {
dvander@239
   502
        if (!obj)
dvander@239
   503
            return NULL;
dvander@239
   504
        obj = obj->unqualified();
dvander@239
   505
        assert(obj->is(MapKind_FunctionType));
dvander@238
   506
        return (FunctionType *)obj;
dvander@238
   507
    }
dvander@238
   508
dvander@238
   509
  private:
dvander@238
   510
    // Functions only.
dvander@238
   511
    Barriered<Type> returnType_;
dvander@238
   512
    Barriered<FixedArray> parameters_;
dvander@238
   513
    Barriered<FixedArray> defaults_;
dvander@238
   514
    Barriered<String> name_;
dvander@238
   515
    TokenKind token_;
dvander@238
   516
    bool variadicNative_;
dvander@238
   517
};
dvander@238
   518
dvander@238
   519
class BoxedPrimitive
dvander@238
   520
{
dvander@238
   521
    PrimitiveType type_;
dvander@238
   522
    union {
dvander@238
   523
        int i_;
dvander@238
   524
        float f_;
dvander@238
   525
    };
dvander@238
   526
dvander@238
   527
  public:
dvander@238
   528
    static BoxedPrimitive Int(int i) {
dvander@238
   529
        BoxedPrimitive b;
dvander@238
   530
        b.type_ = PrimitiveType_Int32;
dvander@238
   531
        b.i_ = i;
dvander@238
   532
        return b;
dvander@238
   533
    }
dvander@238
   534
    static BoxedPrimitive Float(float f) {
dvander@238
   535
        BoxedPrimitive b;
dvander@238
   536
        b.type_ = PrimitiveType_Float;
dvander@238
   537
        b.f_ = f;
dvander@238
   538
        return b;
dvander@238
   539
    }
dvander@238
   540
dvander@238
   541
    PrimitiveType type() const {
dvander@238
   542
        return type_;
dvander@238
   543
    }
dvander@238
   544
    int toInt() const {
dvander@238
   545
        assert(type() == PrimitiveType_Int32);
dvander@238
   546
        return i_;
dvander@238
   547
    }
dvander@238
   548
    float toFloat() const {
dvander@238
   549
        assert(type() == PrimitiveType_Float);
dvander@238
   550
        return f_;
dvander@238
   551
    }
dvander@238
   552
};
dvander@238
   553
dvander@241
   554
const char *GetTypeName(Type *type, char *buffer, size_t maxlen);
dvander@238
   555
dvander@238
   556
}
dvander@238
   557
dvander@238
   558
#endif // _include_jc_types_h_