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