src/NameBinding.h
author David Anderson <dvander@alliedmods.net>
Sat Aug 04 17:51:43 2012 -0700 (2012-08-04)
changeset 146 dc7d3b7a918c
parent 145 e9d804821c48
child 170 5e4570966ece
permissions -rw-r--r--
Basic support for parsing and creating types from structure syntax.
     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     void setForwardType(Handle<Type> type) {
   126         forwardType_ = type;
   127     }
   128     Type *forwardType() {
   129         return forwardType_;
   130     }
   131     void setImplemented(const SourcePosition &at) {
   132         token_ = TOK_PUBLIC;
   133         pos_ = at;
   134     }
   135     void markNativeVariadic() {
   136         assert(token_ == TOK_NATIVE);
   137         isVariadicNative_ = true;
   138     }
   139     bool isNativeVariadic() {
   140         assert(token_ == TOK_NATIVE);
   141         return isVariadicNative_;
   142     }
   143     unsigned slot() const {
   144         return slot_;
   145     }
   146     bool addUsedGlobal(BoundName *name) {
   147         return globals_.append(name);
   148     }
   149     Vector<BoundName *, PoolAllocationPolicy> *usedGlobals() {
   150         return &globals_;
   151     }
   152 };
   153 
   154 class NamedConstant : public BoundName
   155 {
   156     BoxedPrimitive value_;
   157     Type *type_;
   158 
   159   public:
   160     NamedConstant(Scope *scope, Handle<String> name, const SourcePosition &pos)
   161       : BoundName(scope, name, pos),
   162         type_(NULL)
   163     {
   164     }
   165 
   166     Kind kind() const {
   167         return CONSTANT;
   168     }
   169     void set(Type *type, const BoxedPrimitive &value) {
   170         value_ = value;
   171         type_ = type;
   172     }
   173     Type *type() const {
   174         return type_;
   175     }
   176     BoxedPrimitive value() const {
   177         return value_;
   178     }
   179 };
   180 
   181 class NamedType : public BoundName
   182 {
   183   public:
   184     NamedType(Scope *scope, Handle<String> name, Handle<Type> type)
   185       : BoundName(scope, name, SourcePosition())
   186     {
   187         setType(type);
   188     }
   189 
   190     NamedType(Scope *scope, Handle<String> name, const SourcePosition &pos)
   191       : BoundName(scope, name, pos)
   192     {
   193     }
   194 
   195     Kind kind() const {
   196         return TYPE;
   197     }
   198 };
   199 
   200 class UnboundName : public BoundName
   201 {
   202   public:
   203     UnboundName(Scope *scope, Handle<String> name)
   204       : BoundName(scope, name, SourcePosition())
   205     {
   206     }
   207 
   208     Kind kind() const {
   209         return UNBOUND;
   210     }
   211 };
   212 
   213 class Variable : public BoundName
   214 {
   215   public:
   216     enum Location {
   217         UNALLOCATED,
   218         STACK,
   219         PARAMETER,
   220         ENVIRONMENT
   221     };
   222 
   223     Variable(Scope *scope, Handle<String> name, const SourcePosition &pos);
   224 
   225     Kind kind() const {
   226         return VARIABLE;
   227     }
   228     bool unallocated() const {
   229         return location() == UNALLOCATED;
   230     }
   231     void allocate(Location location, unsigned slot) {
   232         location_ = location;
   233         slot_ = slot;
   234     }
   235     Location location() const {
   236         return location_;
   237     }
   238     unsigned slot() const {
   239         assert(!unallocated());
   240         return slot_;
   241     }
   242     bool needsHeapAllocation();
   243 
   244   private:
   245     Location location_;
   246     unsigned slot_;
   247 };
   248 
   249 }
   250 
   251 #endif // _include_name_binding_h_