src/Types.h
author David Anderson <dvander@alliedmods.net>
Sat Jan 12 16:13:46 2013 -0800 (2013-01-12)
changeset 258 241d082d6d89
parent 256 3c184218462d
child 261 219b49bf4a03
permissions -rw-r--r--
Implement |from x import *| syntax for modules.
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@241
    68
    TypeQual_Const       = (1 << 2)
dvander@238
    69
};
dvander@238
    70
dvander@238
    71
class Type : public Object
dvander@238
    72
{
dvander@238
    73
  protected:
dvander@238
    74
    enum Kind {
dvander@238
    75
        // A primitive is a plain-old-data type.
dvander@238
    76
        PRIMITIVE,
dvander@238
    77
dvander@238
    78
        // Void is an internal type used to specify that a function returns no
dvander@238
    79
        // value.
dvander@238
    80
        VOID,
dvander@238
    81
dvander@238
    82
        // Enums are plain-old-data with int32 storage. They allow for extra
dvander@238
    83
        // type checking that would not be possible with integers.
dvander@238
    84
        ENUM,
dvander@238
    85
dvander@238
    86
        // Unchecked is a magic type that has implicit, bitwise coercion to
dvander@238
    87
        // int32, float, bool, or an enum.
dvander@238
    88
        UNCHECKED,
dvander@238
    89
dvander@239
    90
        // Contains type qualifiers, and a back pointer to the actual
dvander@239
    91
        // unqualified type.
dvander@239
    92
        QUALTYPE,
dvander@239
    93
dvander@239
    94
        // ------ Add traceable types below (STRING FIRST!) -------
dvander@238
    95
dvander@238
    96
        // An immutable type that is a primitive in terms of language
dvander@238
    97
        // semantics, but gets a special type here to make internal
dvander@238
    98
        // logic easier.
dvander@238
    99
        STRING,
dvander@238
   100
dvander@238
   101
        // An array is a fixed-length vector of any other type.
dvander@238
   102
        ARRAY,
dvander@238
   103
        EXTERNAL_ARRAY,
dvander@238
   104
dvander@238
   105
        // A reference type may only be specified on parameters, and
dvander@238
   106
        // references may only be computed to primitives or enums.
dvander@238
   107
        REFERENCE,
dvander@238
   108
dvander@238
   109
        // A function type encapsulates a function signature.
dvander@238
   110
        FUNCTION,
dvander@238
   111
dvander@238
   112
        // Structs are composite records that may contain primitives, arrays,
dvander@238
   113
        // functions, enums, and other structs.
dvander@256
   114
        STRUCT,
dvander@256
   115
dvander@256
   116
        // Importable types are mainly used during the compilation process
dvander@256
   117
        // to distinguish between normal names and static imports.
dvander@256
   118
        IMPORTABLE
dvander@238
   119
    };
dvander@238
   120
dvander@240
   121
    void init(Kind kind, Type *root = NULL);
dvander@238
   122
dvander@238
   123
  private:
dvander@238
   124
    Kind kind() {
dvander@238
   125
        return root_->kind_;
dvander@238
   126
    }
dvander@238
   127
dvander@238
   128
  public:   
dvander@238
   129
    static Type *NewVoid(Zone *zone);
dvander@238
   130
    static Type *NewUnchecked(Zone *zone);
dvander@238
   131
    static Type *NewPrimitive(Zone *zone, PrimitiveType type);
dvander@238
   132
    static Type *NewString(Zone *zone);
dvander@240
   133
    static Type *NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> type);
dvander@256
   134
    static Type *NewImportable(Zone *zone);
dvander@238
   135
dvander@238
   136
    static Type *cast(Object *obj) {
dvander@238
   137
        assert(!obj ||
dvander@238
   138
               obj->is(MapKind_Type) ||
dvander@238
   139
               obj->is(MapKind_FunctionType) ||
dvander@238
   140
               obj->is(MapKind_StructType) ||
dvander@238
   141
               obj->is(MapKind_ArrayType) ||
dvander@238
   142
               obj->is(MapKind_ReferenceType) ||
dvander@238
   143
               obj->is(MapKind_EnumType));
dvander@238
   144
        return (Type *)obj;
dvander@238
   145
    }
dvander@238
   146
dvander@238
   147
    bool isPrimitive() {
dvander@238
   148
        return kind() == PRIMITIVE;
dvander@238
   149
    }
dvander@238
   150
    bool isArray() {
dvander@238
   151
        return kind() == ARRAY || kind() == EXTERNAL_ARRAY;
dvander@238
   152
    }
dvander@238
   153
    bool isReference() {
dvander@238
   154
        return kind() == REFERENCE;
dvander@238
   155
    }
dvander@238
   156
    bool isFunction() {
dvander@238
   157
        return kind() == FUNCTION;
dvander@238
   158
    }
dvander@238
   159
    bool isVoid() {
dvander@238
   160
        return kind() == VOID;
dvander@238
   161
    }
dvander@238
   162
    bool isUnchecked() {
dvander@238
   163
        return kind() == UNCHECKED;
dvander@238
   164
    }
dvander@238
   165
    bool isStruct() {
dvander@238
   166
        return kind() == STRUCT;
dvander@238
   167
    }
dvander@256
   168
    bool isImportable() {
dvander@256
   169
        return kind() == IMPORTABLE;
dvander@256
   170
    }
dvander@238
   171
    PrimitiveType primitive() {
dvander@238
   172
        assert(isPrimitive());
dvander@238
   173
        return root_->primitive_;
dvander@238
   174
    }
dvander@238
   175
    bool isPod() {
dvander@238
   176
        return (isPrimitive() && !isString()) || isEnum() || isUnchecked();
dvander@238
   177
    }
dvander@238
   178
    PrimitiveType pod() {
dvander@238
   179
        assert(isPod());
dvander@238
   180
        return isPrimitive()
dvander@238
   181
               ? (primitive() == PrimitiveType_Bool)
dvander@238
   182
                 ? PrimitiveType_Int32
dvander@238
   183
                 : primitive()
dvander@238
   184
               : PrimitiveType_Int32;
dvander@238
   185
    }
dvander@238
   186
    bool isChar() {
dvander@238
   187
        return isPrimitive() && primitive() == PrimitiveType_Char;
dvander@238
   188
    }
dvander@238
   189
    bool isFloat() {
dvander@238
   190
        return isPrimitive() && primitive() == PrimitiveType_Float;
dvander@238
   191
    }
dvander@238
   192
    bool isInt32() {
dvander@238
   193
        return isPrimitive() && primitive() == PrimitiveType_Int32;
dvander@238
   194
    }
dvander@238
   195
    bool isInt32OrEnum() {
dvander@238
   196
        return isInt32() || isEnum();
dvander@238
   197
    }
dvander@238
   198
    bool isBool() {
dvander@238
   199
        return isPrimitive() && primitive() == PrimitiveType_Bool;
dvander@238
   200
    }
dvander@238
   201
    bool isString() {
dvander@238
   202
        return kind() == STRING;
dvander@238
   203
    }
dvander@238
   204
    bool isExternalArray() {
dvander@238
   205
        return kind() == EXTERNAL_ARRAY;
dvander@238
   206
    }
dvander@238
   207
    bool isTraceable() {
dvander@238
   208
        return kind() >= STRING;
dvander@238
   209
    }
dvander@238
   210
    bool isEnum() {
dvander@238
   211
        return kind() == ENUM;
dvander@238
   212
    }
dvander@238
   213
    bool hasTypeQualifiers() {
dvander@238
   214
        return kind_ == QUALTYPE;
dvander@238
   215
    }
dvander@238
   216
dvander@238
   217
    TypeQualifiers quals() {
dvander@241
   218
        if (!hasTypeQualifiers())
dvander@238
   219
            return TypeQual_None;
dvander@238
   220
        return quals_;
dvander@238
   221
    }
dvander@239
   222
    Type *unqualified() {
dvander@239
   223
        return root_;
dvander@239
   224
    }
dvander@238
   225
dvander@238
   226
    // GC Descriptor.
dvander@238
   227
    static inline size_t offsetOfRoot() {
dvander@238
   228
        return OFFSETOF(Type, root_);
dvander@238
   229
    }
dvander@238
   230
    // End GC Descriptor.
dvander@238
   231
dvander@238
   232
  protected:
dvander@238
   233
    Kind kind_;
dvander@238
   234
    PrimitiveType primitive_;
dvander@238
   235
    TypeQualifiers quals_;
dvander@238
   236
dvander@238
   237
    // For unqualified types, this points to |this|. For qualified types, it
dvander@238
   238
    // points to the unqualified original type.
dvander@238
   239
    Barriered<Type> root_;
dvander@238
   240
};
dvander@238
   241
dvander@238
   242
class EnumType : public Type
dvander@238
   243
{
dvander@238
   244
  public:
dvander@238
   245
    static EnumType *New(Zone *Zone, Handle<String> name);
dvander@238
   246
dvander@238
   247
    String *name() {
dvander@238
   248
        return name_;
dvander@238
   249
    }
dvander@238
   250
dvander@238
   251
    // GC Descriptor.
dvander@238
   252
    static inline size_t offsetOfName() {
dvander@238
   253
        return OFFSETOF(EnumType, name_);
dvander@238
   254
    }
dvander@238
   255
    // End GC Descriptor.
dvander@238
   256
dvander@238
   257
    static EnumType *cast(Object *obj) {
dvander@238
   258
        assert(!obj || obj->is(MapKind_EnumType));
dvander@238
   259
        return (EnumType *)obj;
dvander@238
   260
    }
dvander@238
   261
dvander@238
   262
  private:
dvander@238
   263
    Barriered<String> name_;
dvander@238
   264
};
dvander@238
   265
dvander@238
   266
class ReferenceType : public Type
dvander@238
   267
{
dvander@238
   268
  public:
dvander@238
   269
    static ReferenceType *New(Zone *zone, Handle<Type> contained);
dvander@238
   270
    
dvander@238
   271
    Type *contained() {
dvander@238
   272
        return contained_;
dvander@238
   273
    }
dvander@238
   274
dvander@238
   275
    // GC Descriptor.
dvander@238
   276
    static inline size_t offsetOfContained() {
dvander@238
   277
        return OFFSETOF(ReferenceType, contained_);
dvander@238
   278
    }
dvander@238
   279
    // End GC Descriptor.
dvander@238
   280
dvander@239
   281
    static ReferenceType *cast(Type *obj) {
dvander@239
   282
        if (!obj)
dvander@239
   283
            return NULL;
dvander@239
   284
        obj = obj->unqualified();
dvander@239
   285
        assert(obj->is(MapKind_ReferenceType));
dvander@238
   286
        return (ReferenceType *)obj;
dvander@238
   287
    }
dvander@238
   288
dvander@238
   289
  private:
dvander@238
   290
    Barriered<Type> contained_;
dvander@238
   291
};
dvander@238
   292
dvander@238
   293
class ArrayType : public Type
dvander@238
   294
{
dvander@238
   295
  public:
dvander@238
   296
    static const int DYNAMIC_ARRAY_SIZE = -1;
dvander@238
   297
dvander@238
   298
    static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
dvander@238
   299
    static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
dvander@238
   300
dvander@238
   301
    Type *innermost() {
dvander@238
   302
        Type *temp = contained();
dvander@238
   303
        while (temp->isArray())
dvander@238
   304
            temp = ArrayType::cast(temp)->contained();
dvander@238
   305
        return temp;
dvander@238
   306
    }
dvander@238
   307
dvander@247
   308
    bool isDynamic() {
dvander@247
   309
        return elements_ == DYNAMIC_ARRAY_SIZE;
dvander@247
   310
    }
dvander@247
   311
    bool isExtensible() {
dvander@247
   312
        return isDynamic() && !(quals_ & TypeQual_Const);
dvander@247
   313
    }
dvander@238
   314
    Type *contained() {
dvander@238
   315
        return contained_;
dvander@238
   316
    }
dvander@238
   317
    bool isFixedLength() {
dvander@238
   318
        return elements_ > 0;
dvander@238
   319
    }
dvander@238
   320
    bool isCharArray() {
dvander@238
   321
        return contained()->isPrimitive() &&
dvander@238
   322
               contained()->primitive() == PrimitiveType_Char;
dvander@238
   323
    }
dvander@238
   324
    unsigned fixedLength() {
dvander@238
   325
        assert(isFixedLength());
dvander@238
   326
        return elements_;
dvander@238
   327
    }
dvander@238
   328
    unsigned levels() {
dvander@238
   329
        return levels_;
dvander@238
   330
    }
dvander@238
   331
    bool hasInlineElements() {
dvander@238
   332
        // We don't allocate traceable elements inline, since there's no
dvander@238
   333
        // point to the optimization; we're going to be allocating lots of
dvander@238
   334
        // objects anyway (in theory).
dvander@238
   335
        return isFixedLength() && !contained()->isTraceable();
dvander@238
   336
    }
dvander@238
   337
dvander@238
   338
    // Arrays of this type can be created with this cached map.
dvander@238
   339
    ArrayMap *newMap() {
dvander@238
   340
        return newMap_;
dvander@238
   341
    }
dvander@238
   342
    void setNewMap(ArrayMap *map) {
dvander@238
   343
        assert(!newMap());
dvander@238
   344
        newMap_ = map;
dvander@238
   345
    }
dvander@238
   346
dvander@238
   347
    // GC Descriptor.
dvander@238
   348
    static inline size_t offsetOfContained() {
dvander@238
   349
        return OFFSETOF(ArrayType, contained_);
dvander@238
   350
    }
dvander@238
   351
    static inline size_t offsetOfNewMap() {
dvander@238
   352
        return OFFSETOF(ArrayType, newMap_);
dvander@238
   353
    }
dvander@238
   354
    // End GC Descriptor.
dvander@238
   355
dvander@239
   356
    static ArrayType *cast(Type *obj) {
dvander@239
   357
        if (!obj)
dvander@239
   358
            return NULL;
dvander@239
   359
        obj = obj->unqualified();
dvander@239
   360
        assert(obj->is(MapKind_ArrayType));
dvander@238
   361
        return (ArrayType *)obj;
dvander@238
   362
    }
dvander@238
   363
dvander@238
   364
  private:
dvander@238
   365
    int32 elements_;
dvander@238
   366
    unsigned levels_;
dvander@238
   367
    Barriered<Type> contained_;
dvander@238
   368
    Barriered<ArrayMap> newMap_;
dvander@238
   369
};
dvander@238
   370
dvander@238
   371
class StructType : public Type
dvander@238
   372
{
dvander@238
   373
  public:
dvander@238
   374
    static StructType *New(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
dvander@238
   375
dvander@238
   376
    FixedArray *fields() {
dvander@238
   377
        assert(isStruct());
dvander@238
   378
        return fields_;
dvander@238
   379
    }
dvander@258
   380
    Descriptor *lookupField(String *name, unsigned *index = NULL);
dvander@238
   381
dvander@238
   382
    // Objects of this type can be created with this cached map.
dvander@238
   383
    StructMap *newMap() {
dvander@238
   384
        return newMap_;
dvander@238
   385
    }
dvander@238
   386
    void setNewMap(StructMap *map) {
dvander@238
   387
        assert(!newMap());
dvander@238
   388
        newMap_ = map;
dvander@238
   389
    }
dvander@238
   390
dvander@238
   391
    String *name() {
dvander@238
   392
        return name_;
dvander@238
   393
    }
dvander@238
   394
dvander@238
   395
    // GC Descriptor.
dvander@238
   396
    static inline size_t offsetOfFields() {
dvander@238
   397
        return OFFSETOF(StructType, fields_);
dvander@238
   398
    }
dvander@238
   399
    static inline size_t offsetOfNewMap() {
dvander@238
   400
        return OFFSETOF(StructType, newMap_);
dvander@238
   401
    }
dvander@238
   402
    static inline size_t offsetOfName() {
dvander@238
   403
        return OFFSETOF(StructType, name_);
dvander@238
   404
    }
dvander@238
   405
    // End GC Descriptor.
dvander@238
   406
dvander@239
   407
    static StructType *cast(Type *obj) {
dvander@239
   408
        if (!obj)
dvander@239
   409
            return NULL;
dvander@239
   410
        obj = obj->unqualified();
dvander@239
   411
        assert(obj->is(MapKind_StructType));
dvander@238
   412
        return (StructType *)obj;
dvander@238
   413
    }
dvander@238
   414
dvander@238
   415
  private:
dvander@238
   416
    // Structs only.
dvander@238
   417
    Barriered<FixedArray> fields_;
dvander@238
   418
    Barriered<StructMap> newMap_;
dvander@238
   419
    Barriered<String> name_;
dvander@238
   420
};
dvander@238
   421
dvander@238
   422
class FunctionType : public Type
dvander@238
   423
{
dvander@238
   424
  public:
dvander@238
   425
    static FunctionType *New(Zone *zone, Handle<String> name, TokenKind kind);
dvander@238
   426
dvander@238
   427
    Type *parameterAt(size_t i) {
dvander@238
   428
        return Type::cast(parameters()->at(i));
dvander@238
   429
    }
dvander@238
   430
    Type *returnType() {
dvander@238
   431
        assert(isFunction());
dvander@238
   432
        return returnType_;
dvander@238
   433
    }
dvander@238
   434
    FixedArray *parameters() {
dvander@238
   435
        assert(isFunction());
dvander@238
   436
        return parameters_;
dvander@238
   437
    }
dvander@238
   438
    FixedArray *defaults() {
dvander@238
   439
        assert(isFunction());
dvander@238
   440
        return defaults_;
dvander@238
   441
    }
dvander@238
   442
    bool isNative() {
dvander@238
   443
        return token_ == TOK_NATIVE;
dvander@238
   444
    }
dvander@238
   445
    bool isForward() {
dvander@238
   446
        return token_ == TOK_FORWARD;
dvander@238
   447
    }
dvander@238
   448
    bool isNativeVariadic() {
dvander@238
   449
        assert(isNative());
dvander@238
   450
        return variadicNative_;
dvander@238
   451
    }
dvander@247
   452
    void setVariadic() {
dvander@247
   453
        assert(isNative());
dvander@247
   454
        variadicNative_ = true;
dvander@247
   455
    }
dvander@238
   456
    void setReturnType(Handle<Type> returnType) {
dvander@238
   457
        assert(!returnType_);
dvander@238
   458
        returnType_ = returnType;
dvander@238
   459
    }
dvander@238
   460
    void setParameterTypes(Handle<FixedArray> types) {
dvander@238
   461
        assert(!parameters_);
dvander@238
   462
        parameters_ = types;
dvander@238
   463
    }
dvander@238
   464
    TokenKind token() {
dvander@238
   465
        return token_;
dvander@238
   466
    }
dvander@238
   467
    String *name() {
dvander@238
   468
        return name_;
dvander@238
   469
    }
dvander@238
   470
dvander@238
   471
    // GC Descriptor.
dvander@238
   472
    static inline size_t offsetOfReturnType() {
dvander@238
   473
        return OFFSETOF(FunctionType, returnType_);
dvander@238
   474
    }
dvander@238
   475
    static inline size_t offsetOfParameters() {
dvander@238
   476
        return OFFSETOF(FunctionType, parameters_);
dvander@238
   477
    }
dvander@238
   478
    static inline size_t offsetOfDefaults() {
dvander@238
   479
        return OFFSETOF(FunctionType, defaults_);
dvander@238
   480
    }
dvander@238
   481
    static inline size_t offsetOfName() {
dvander@238
   482
        return OFFSETOF(FunctionType, name_);
dvander@238
   483
    }
dvander@238
   484
    // End GC Descriptor.
dvander@238
   485
dvander@239
   486
    static FunctionType *cast(Type *obj) {
dvander@239
   487
        if (!obj)
dvander@239
   488
            return NULL;
dvander@239
   489
        obj = obj->unqualified();
dvander@239
   490
        assert(obj->is(MapKind_FunctionType));
dvander@238
   491
        return (FunctionType *)obj;
dvander@238
   492
    }
dvander@238
   493
dvander@238
   494
  private:
dvander@238
   495
    // Functions only.
dvander@238
   496
    Barriered<Type> returnType_;
dvander@238
   497
    Barriered<FixedArray> parameters_;
dvander@238
   498
    Barriered<FixedArray> defaults_;
dvander@238
   499
    Barriered<String> name_;
dvander@238
   500
    TokenKind token_;
dvander@238
   501
    bool variadicNative_;
dvander@238
   502
};
dvander@238
   503
dvander@238
   504
class BoxedPrimitive
dvander@238
   505
{
dvander@238
   506
    PrimitiveType type_;
dvander@238
   507
    union {
dvander@238
   508
        int i_;
dvander@238
   509
        float f_;
dvander@238
   510
    };
dvander@238
   511
dvander@238
   512
  public:
dvander@238
   513
    static BoxedPrimitive Int(int i) {
dvander@238
   514
        BoxedPrimitive b;
dvander@238
   515
        b.type_ = PrimitiveType_Int32;
dvander@238
   516
        b.i_ = i;
dvander@238
   517
        return b;
dvander@238
   518
    }
dvander@238
   519
    static BoxedPrimitive Float(float f) {
dvander@238
   520
        BoxedPrimitive b;
dvander@238
   521
        b.type_ = PrimitiveType_Float;
dvander@238
   522
        b.f_ = f;
dvander@238
   523
        return b;
dvander@238
   524
    }
dvander@238
   525
dvander@238
   526
    PrimitiveType type() const {
dvander@238
   527
        return type_;
dvander@238
   528
    }
dvander@238
   529
    int toInt() const {
dvander@238
   530
        assert(type() == PrimitiveType_Int32);
dvander@238
   531
        return i_;
dvander@238
   532
    }
dvander@238
   533
    float toFloat() const {
dvander@238
   534
        assert(type() == PrimitiveType_Float);
dvander@238
   535
        return f_;
dvander@238
   536
    }
dvander@238
   537
};
dvander@238
   538
dvander@241
   539
const char *GetTypeName(Type *type, char *buffer, size_t maxlen);
dvander@238
   540
dvander@238
   541
}
dvander@238
   542
dvander@238
   543
#endif // _include_jc_types_h_