src/NameBinding.h
author David Anderson <dvander@alliedmods.net>
Wed Aug 01 22:32:59 2012 -0700 (2012-08-01)
changeset 145 e9d804821c48
parent 137 be919b22085b
child 170 5e4570966ece
permissions -rw-r--r--
Introduced type semantics, completely replacing tag semantics.
dvander@137
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@137
     2
 *
dvander@0
     3
 * Copyright (C) 2012 David Anderson
dvander@0
     4
 *
dvander@137
     5
 * This file is part of SourcePawn.
dvander@0
     6
 *
dvander@137
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
dvander@0
     8
 * the terms of the GNU General Public License as published by the Free
dvander@0
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@0
    10
 * any later version.
dvander@0
    11
 * 
dvander@137
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@0
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@0
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@0
    15
 *
dvander@0
    16
 * You should have received a copy of the GNU General Public License along with
dvander@137
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
dvander@0
    18
 */
dvander@0
    19
#ifndef _include_name_binding_h_
dvander@0
    20
#define _include_name_binding_h_
dvander@0
    21
dvander@0
    22
#include "PoolAllocator.h"
dvander@2
    23
#include "Types.h"
dvander@25
    24
#include "Scanner.h"
dvander@0
    25
dvander@59
    26
namespace ke {
dvander@0
    27
dvander@0
    28
class Variable;
dvander@0
    29
class NamedFunction;
dvander@0
    30
class Scope;
dvander@0
    31
class Type;
dvander@2
    32
class NamedConstant;
dvander@145
    33
class NamedType;
dvander@145
    34
class UnboundName;
dvander@54
    35
class String;
dvander@0
    36
dvander@0
    37
class BoundName : public PoolObject
dvander@0
    38
{
dvander@28
    39
    Scope *scope_;
dvander@54
    40
    ScopedRoot<String> name_;
dvander@37
    41
    ScopedRoot<Type> type_;
dvander@137
    42
    bool used_;
dvander@63
    43
dvander@63
    44
  protected:
dvander@25
    45
    SourcePosition pos_;
dvander@0
    46
dvander@0
    47
  public:
dvander@0
    48
    enum Kind {
dvander@0
    49
      VARIABLE,
dvander@1
    50
      FUNCTION,
dvander@145
    51
      CONSTANT,
dvander@145
    52
      TYPE,
dvander@145
    53
      UNBOUND
dvander@0
    54
    };
dvander@0
    55
dvander@54
    56
    BoundName(Scope *scope, Handle<String> name, const SourcePosition &pos);
dvander@0
    57
dvander@0
    58
    virtual Kind kind() const = 0;
dvander@0
    59
dvander@54
    60
    String *name() const {
dvander@0
    61
        return name_;
dvander@0
    62
    }
dvander@25
    63
    Scope *scope() const {
dvander@0
    64
        return scope_;
dvander@0
    65
    }
dvander@0
    66
    Variable *toVariable() {
dvander@0
    67
        assert(kind() == VARIABLE);
dvander@0
    68
        return reinterpret_cast<Variable *>(this);
dvander@0
    69
    }
dvander@0
    70
    NamedFunction *toNamedFunction() {
dvander@0
    71
        assert(kind() == FUNCTION);
dvander@0
    72
        return reinterpret_cast<NamedFunction *>(this);
dvander@0
    73
    }
dvander@2
    74
    NamedConstant *toNamedConstant() {
dvander@2
    75
        assert(kind() == CONSTANT);
dvander@2
    76
        return reinterpret_cast<NamedConstant *>(this);
dvander@2
    77
    }
dvander@145
    78
    NamedType *toNamedType() {
dvander@145
    79
        assert(kind() == TYPE);
dvander@145
    80
        return reinterpret_cast<NamedType *>(this);
dvander@145
    81
    }
dvander@0
    82
    Type *type() const {
dvander@0
    83
        return type_;
dvander@0
    84
    }
dvander@37
    85
    void setType(Handle<Type> type) {
dvander@0
    86
        type_ = type;
dvander@0
    87
    }
dvander@137
    88
    void setUsed() {
dvander@137
    89
        used_ = true;
dvander@137
    90
    }
dvander@137
    91
    bool used() const {
dvander@137
    92
        return used_;
dvander@137
    93
    }
dvander@25
    94
    const SourcePosition &pos() {
dvander@25
    95
        return pos_;
dvander@25
    96
    }
dvander@0
    97
};
dvander@0
    98
dvander@0
    99
class NamedFunction : public BoundName
dvander@0
   100
{
dvander@0
   101
    unsigned slot_;
dvander@63
   102
    TokenKind token_;
dvander@63
   103
    ScopedRoot<Type> forwardType_;
dvander@68
   104
    bool isVariadicNative_;
dvander@137
   105
    Vector<BoundName *, PoolAllocationPolicy> globals_;
dvander@0
   106
dvander@0
   107
  public:
dvander@63
   108
    NamedFunction(Scope *scope, Handle<String> name, const SourcePosition &pos, TokenKind token);
dvander@0
   109
dvander@0
   110
    Kind kind() const {
dvander@0
   111
        return FUNCTION;
dvander@0
   112
    }
dvander@0
   113
    void allocate(unsigned slot) {
dvander@0
   114
        slot_ = slot;
dvander@0
   115
    }
dvander@63
   116
    bool isForward() const {
dvander@63
   117
        return token_ == TOK_FORWARD;
dvander@63
   118
    }
dvander@63
   119
    bool isPublic() const {
dvander@63
   120
        return token_ == TOK_PUBLIC;
dvander@63
   121
    }
dvander@68
   122
    bool isNative() const {
dvander@68
   123
        return token_ == TOK_NATIVE;
dvander@68
   124
    }
dvander@63
   125
    void setForwardType(Handle<Type> type) {
dvander@63
   126
        forwardType_ = type;
dvander@63
   127
    }
dvander@63
   128
    Type *forwardType() {
dvander@63
   129
        return forwardType_;
dvander@63
   130
    }
dvander@63
   131
    void setImplemented(const SourcePosition &at) {
dvander@63
   132
        token_ = TOK_PUBLIC;
dvander@63
   133
        pos_ = at;
dvander@63
   134
    }
dvander@68
   135
    void markNativeVariadic() {
dvander@68
   136
        assert(token_ == TOK_NATIVE);
dvander@68
   137
        isVariadicNative_ = true;
dvander@68
   138
    }
dvander@68
   139
    bool isNativeVariadic() {
dvander@68
   140
        assert(token_ == TOK_NATIVE);
dvander@68
   141
        return isVariadicNative_;
dvander@68
   142
    }
dvander@0
   143
    unsigned slot() const {
dvander@0
   144
        return slot_;
dvander@0
   145
    }
dvander@137
   146
    bool addUsedGlobal(BoundName *name) {
dvander@137
   147
        return globals_.append(name);
dvander@137
   148
    }
dvander@137
   149
    Vector<BoundName *, PoolAllocationPolicy> *usedGlobals() {
dvander@137
   150
        return &globals_;
dvander@137
   151
    }
dvander@0
   152
};
dvander@0
   153
dvander@2
   154
class NamedConstant : public BoundName
dvander@2
   155
{
dvander@2
   156
    BoxedPrimitive value_;
dvander@2
   157
    Type *type_;
dvander@2
   158
dvander@2
   159
  public:
dvander@54
   160
    NamedConstant(Scope *scope, Handle<String> name, const SourcePosition &pos)
dvander@25
   161
      : BoundName(scope, name, pos),
dvander@2
   162
        type_(NULL)
dvander@2
   163
    {
dvander@2
   164
    }
dvander@2
   165
dvander@2
   166
    Kind kind() const {
dvander@2
   167
        return CONSTANT;
dvander@2
   168
    }
dvander@2
   169
    void set(Type *type, const BoxedPrimitive &value) {
dvander@2
   170
        value_ = value;
dvander@2
   171
        type_ = type;
dvander@2
   172
    }
dvander@2
   173
    Type *type() const {
dvander@2
   174
        return type_;
dvander@2
   175
    }
dvander@2
   176
    BoxedPrimitive value() const {
dvander@2
   177
        return value_;
dvander@1
   178
    }
dvander@1
   179
};
dvander@1
   180
dvander@145
   181
class NamedType : public BoundName
dvander@145
   182
{
dvander@145
   183
  public:
dvander@145
   184
    NamedType(Scope *scope, Handle<String> name, Handle<Type> type)
dvander@145
   185
      : BoundName(scope, name, SourcePosition())
dvander@145
   186
    {
dvander@145
   187
        setType(type);
dvander@145
   188
    }
dvander@145
   189
dvander@145
   190
    NamedType(Scope *scope, Handle<String> name, const SourcePosition &pos)
dvander@145
   191
      : BoundName(scope, name, pos)
dvander@145
   192
    {
dvander@145
   193
    }
dvander@145
   194
dvander@145
   195
    Kind kind() const {
dvander@145
   196
        return TYPE;
dvander@145
   197
    }
dvander@145
   198
};
dvander@145
   199
dvander@145
   200
class UnboundName : public BoundName
dvander@145
   201
{
dvander@145
   202
  public:
dvander@145
   203
    UnboundName(Scope *scope, Handle<String> name)
dvander@145
   204
      : BoundName(scope, name, SourcePosition())
dvander@145
   205
    {
dvander@145
   206
    }
dvander@145
   207
dvander@145
   208
    Kind kind() const {
dvander@145
   209
        return UNBOUND;
dvander@145
   210
    }
dvander@145
   211
};
dvander@145
   212
dvander@0
   213
class Variable : public BoundName
dvander@0
   214
{
dvander@0
   215
  public:
dvander@0
   216
    enum Location {
dvander@0
   217
        UNALLOCATED,
dvander@0
   218
        STACK,
dvander@85
   219
        PARAMETER,
dvander@85
   220
        ENVIRONMENT
dvander@0
   221
    };
dvander@0
   222
dvander@54
   223
    Variable(Scope *scope, Handle<String> name, const SourcePosition &pos);
dvander@0
   224
dvander@0
   225
    Kind kind() const {
dvander@0
   226
        return VARIABLE;
dvander@0
   227
    }
dvander@0
   228
    bool unallocated() const {
dvander@0
   229
        return location() == UNALLOCATED;
dvander@0
   230
    }
dvander@0
   231
    void allocate(Location location, unsigned slot) {
dvander@0
   232
        location_ = location;
dvander@0
   233
        slot_ = slot;
dvander@0
   234
    }
dvander@0
   235
    Location location() const {
dvander@0
   236
        return location_;
dvander@0
   237
    }
dvander@0
   238
    unsigned slot() const {
dvander@0
   239
        assert(!unallocated());
dvander@0
   240
        return slot_;
dvander@0
   241
    }
dvander@85
   242
    bool needsHeapAllocation();
dvander@0
   243
dvander@0
   244
  private:
dvander@0
   245
    Location location_;
dvander@0
   246
    unsigned slot_;
dvander@0
   247
};
dvander@0
   248
dvander@0
   249
}
dvander@0
   250
dvander@0
   251
#endif // _include_name_binding_h_