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