src/compiler/Symbols.h
author David Anderson <dvander@alliedmods.net>
Mon Dec 24 02:49:20 2012 -0800 (2012-12-24)
changeset 234 26e3035cdffc
parent 233 bbb498ccb4ac
child 256 3c184218462d
permissions -rw-r--r--
Get string literals working again.
dvander@195
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@195
     2
 *
dvander@195
     3
 * Copyright (C) 2012 David Anderson
dvander@195
     4
 *
dvander@195
     5
 * This file is part of SourcePawn.
dvander@195
     6
 *
dvander@195
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
dvander@195
     8
 * the terms of the GNU General Public License as published by the Free
dvander@195
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@195
    10
 * any later version.
dvander@195
    11
 * 
dvander@195
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@195
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@195
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@195
    15
 *
dvander@195
    16
 * You should have received a copy of the GNU General Public License along with
dvander@195
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
dvander@195
    18
 */
dvander@195
    19
#ifndef _include_sp2_symbol_h_
dvander@195
    20
#define _include_sp2_symbol_h_
dvander@195
    21
dvander@195
    22
#include "../PoolAllocator.h"
dvander@195
    23
#include "../Handles.h"
dvander@195
    24
#include "../Opcodes.h"
dvander@195
    25
#include "../Types.h"
dvander@196
    26
#include "../Strings.h"
dvander@195
    27
dvander@195
    28
namespace ke {
dvander@195
    29
dvander@195
    30
class String;
dvander@195
    31
dvander@195
    32
#define SYMBOL_KINDS(_) \
dvander@195
    33
    /* Any kind of variable or argument produces a VariableSymbol. */ \
dvander@195
    34
    _(Variable)         \
dvander@195
    35
    /* A function declaration produces a FunctionSymbol. */ \
dvander@195
    36
    _(Function)         \
dvander@195
    37
    /* A named constant produces a ConstantSymbol. */ \
dvander@195
    38
    _(Constant)         \
dvander@195
    39
    /* A named type (class struct, typedef, etc) produces a TypeSymbol. */ \
dvander@195
    40
    _(Type)             \
dvander@195
    41
    /* // A module import produces a ModuleSymbol. */   \
dvander@195
    42
    _(Module)
dvander@195
    43
dvander@195
    44
#define _(name)     class name##Symbol;
dvander@195
    45
SYMBOL_KINDS(_)
dvander@195
    46
#undef _
dvander@195
    47
dvander@195
    48
class Scope;
dvander@195
    49
dvander@195
    50
// A symbol represents the declaration of a named entity.
dvander@195
    51
class Symbol : public PoolObject
dvander@195
    52
{
dvander@195
    53
  public:
dvander@195
    54
    enum Kind {
dvander@195
    55
#       define _(name) k##name,
dvander@195
    56
        SYMBOL_KINDS(_)
dvander@195
    57
#       undef _
dvander@195
    58
        kTotalSymbolKinds
dvander@195
    59
    };
dvander@195
    60
dvander@195
    61
  public:
dvander@195
    62
    Symbol(Scope *scope, Handle<String> name, const SourcePosition &pos)
dvander@195
    63
      : scope_(scope),
dvander@195
    64
        name_(name),
dvander@195
    65
        pos_(pos)
dvander@195
    66
    {
dvander@195
    67
    }
dvander@195
    68
dvander@195
    69
    virtual Kind kind() const = 0;
dvander@195
    70
dvander@195
    71
    Handle<String> name() const {
dvander@195
    72
        return name_;
dvander@195
    73
    }
dvander@195
    74
    const SourcePosition &pos() const {
dvander@195
    75
        return pos_;
dvander@195
    76
    }
dvander@195
    77
    Handle<Type> type() const {
dvander@195
    78
        return type_;
dvander@195
    79
    }
dvander@195
    80
    Scope *scope() const {
dvander@195
    81
        return scope_;
dvander@195
    82
    }
dvander@195
    83
dvander@195
    84
  public:
dvander@195
    85
#define _(name)                                             \
dvander@195
    86
    bool is##name() const {                                 \
dvander@195
    87
        return (kind() == k##name);                         \
dvander@195
    88
    }                                                       \
dvander@195
    89
    name##Symbol *as##name() {                              \
dvander@195
    90
        if (is##name())                                     \
dvander@195
    91
            return to##name();                              \
dvander@195
    92
        return NULL;                                        \
dvander@195
    93
    }                                                       \
dvander@195
    94
    name##Symbol *to##name() {                              \
dvander@195
    95
        assert(is##name());                                 \
dvander@195
    96
        return reinterpret_cast<name##Symbol *>(this);      \
dvander@195
    97
    }
dvander@195
    98
    SYMBOL_KINDS(_)
dvander@195
    99
#undef _
dvander@195
   100
dvander@195
   101
  private:
dvander@195
   102
    Scope *scope_;
dvander@195
   103
    ScopedRoot<String> name_;
dvander@195
   104
    SourcePosition pos_;
dvander@195
   105
dvander@195
   106
  protected:
dvander@195
   107
    ScopedRoot<Type> type_;
dvander@195
   108
};
dvander@195
   109
dvander@195
   110
class VariableSymbol : public Symbol
dvander@195
   111
{
dvander@195
   112
  public:
dvander@195
   113
    enum Storage {
dvander@195
   114
        Unknown,
dvander@195
   115
        Local,
dvander@220
   116
        Arg,
dvander@195
   117
        Heap
dvander@195
   118
    };
dvander@195
   119
dvander@195
   120
  public:
dvander@195
   121
    VariableSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos)
dvander@195
   122
      : Symbol(scope, name, pos),
dvander@195
   123
        storage_(Unknown)
dvander@195
   124
    {
dvander@195
   125
    }
dvander@195
   126
dvander@195
   127
    VariableSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos, Handle<Type> type)
dvander@195
   128
      : Symbol(scope, name, pos),
dvander@195
   129
        storage_(Unknown)
dvander@195
   130
    {
dvander@195
   131
        type_ = type;
dvander@195
   132
    }
dvander@195
   133
dvander@195
   134
    Kind kind() const {
dvander@195
   135
        return kVariable;
dvander@195
   136
    }
dvander@195
   137
    void setType(Type *type) {
dvander@209
   138
        assert(!type_);
dvander@195
   139
        type_ = type;
dvander@195
   140
    }
dvander@195
   141
    void allocate(Storage storage, unsigned slot) {
dvander@195
   142
        storage_ = storage;
dvander@195
   143
        slot_ = slot;
dvander@195
   144
    }
dvander@195
   145
    Storage storage() const {
dvander@195
   146
        return storage_;
dvander@195
   147
    }
dvander@195
   148
    unsigned slot() const {
dvander@195
   149
        assert(storage() != Unknown);
dvander@195
   150
        return slot_;
dvander@195
   151
    }
dvander@195
   152
dvander@195
   153
  private:
dvander@195
   154
    Storage storage_;
dvander@195
   155
    unsigned slot_;
dvander@195
   156
};
dvander@195
   157
dvander@195
   158
class TypeSymbol : public Symbol
dvander@195
   159
{
dvander@195
   160
  public:
dvander@195
   161
    TypeSymbol(Scope *scope, Handle<String> name, Handle<Type> type)
dvander@195
   162
      : Symbol(scope, name, SourcePosition())
dvander@195
   163
    {
dvander@195
   164
        type_ = type;
dvander@195
   165
    }
dvander@195
   166
dvander@195
   167
    Kind kind() const {
dvander@195
   168
        return kType;
dvander@195
   169
    }
dvander@195
   170
};
dvander@195
   171
dvander@195
   172
class FunctionSymbol : public Symbol
dvander@195
   173
{
dvander@195
   174
  public:
dvander@195
   175
    FunctionSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos, Handle<FunctionType> type)
dvander@195
   176
      : Symbol(scope, name, pos)
dvander@195
   177
    {
dvander@195
   178
        type_ = type;
dvander@195
   179
    }
dvander@195
   180
dvander@195
   181
    Kind kind() const {
dvander@195
   182
        return kFunction;
dvander@195
   183
    }
dvander@195
   184
    FunctionType *type() const {
dvander@195
   185
        return FunctionType::cast(type_);
dvander@195
   186
    }
dvander@195
   187
};
dvander@195
   188
dvander@233
   189
class ConstantSymbol : public Symbol
dvander@233
   190
{
dvander@233
   191
  public:
dvander@233
   192
    ConstantSymbol(Scope *scope, Handle<String> name, const SourcePosition &pos, Handle<Type> type,
dvander@233
   193
                   const BoxedPrimitive &prim)
dvander@233
   194
      : Symbol(scope, name, pos),
dvander@233
   195
        value_(prim)
dvander@233
   196
    {
dvander@233
   197
        type_ = type;
dvander@233
   198
    }
dvander@233
   199
dvander@233
   200
    Kind kind() const {
dvander@233
   201
        return kConstant;
dvander@233
   202
    }
dvander@233
   203
    const BoxedPrimitive &value() const {
dvander@233
   204
        return value_;
dvander@233
   205
    }
dvander@233
   206
dvander@233
   207
  private:
dvander@233
   208
    BoxedPrimitive value_;
dvander@233
   209
};
dvander@233
   210
dvander@195
   211
}
dvander@195
   212
dvander@195
   213
#endif // _include_sp2_symbol_h_