src/compiler/Scopes.cpp
author David Anderson <dvander@alliedmods.net>
Sun Jan 06 13:52:21 2013 -0800 (2013-01-06)
changeset 256 3c184218462d
parent 195 c1ba166f3fc4
child 259 99ab8b19f0b9
permissions -rw-r--r--
Initial implementation of module imports.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft 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  * Foobar 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  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "../Zone.h"
    20 #include "../Types.h"
    21 #include "../TypeManager.h"
    22 #include "../Strings.h"
    23 #include "../Environments.h"
    24 #include "../Structures.h"
    25 #include "CompileContext.h"
    26 #include "Scopes.h"
    27 #include "../Spaces-inl.h"
    28 #include "../Heap-inl.h"
    29 
    30 using namespace ke;
    31 
    32 Scope::Scope(PoolAllocator &pool, Kind kind, Scope *enclosing)
    33   : pool_(pool),
    34     kind_(kind),
    35     enclosing_(enclosing)
    36 {
    37 }
    38 
    39 bool
    40 Scope::initialize()
    41 {
    42     if (enclosing_ && !enclosing_->children_.append(this))
    43         return false;
    44     return true;
    45 }
    46 
    47 void
    48 Scope::unlink()
    49 {
    50     assert(empty());
    51 
    52     assert(enclosing_->children_[enclosing_->children_.length() - 1] == this);
    53     enclosing_->children_.pop();
    54 
    55     // OOM here is swallowed and checked after compilation.
    56     // :TODO: make the above true.
    57     for (size_t i = 0; i < children_.length(); i++)
    58         enclosing_->children_.append(children_[i]);
    59 }
    60 
    61 Scope *
    62 Scope::unlinkIfEmpty()
    63 {
    64     if (empty()) {
    65         unlink();
    66         return NULL;
    67     }
    68     return this;
    69 }
    70 
    71 Symbol *
    72 Scope::localLookup(Handle<String> name)
    73 {
    74     for (size_t i = 0; i < names_.length(); i++) {
    75         if (names_[i]->name() == name)
    76             return names_[i];
    77     }
    78     return NULL;
    79 }
    80 
    81 Symbol  *
    82 Scope::lookup(Handle<String> name)
    83 {
    84     for (Scope *scope = this; scope; scope = scope->enclosing()) {
    85         if (Symbol *bound = scope->localLookup(name))
    86             return bound;
    87     }
    88     return NULL;
    89 }
    90 
    91 #if 0
    92 void
    93 Scope::setUsesLifoHeap()
    94 {
    95     // Only one lifo slot is needed per scope.
    96 #if 0
    97     if (lifoSlot_)
    98         return;
    99 #endif
   100 
   101     // If the parent of this scope is the function scope, then this is the
   102     // function's block scope, and the lifo slot is part of the Frame instead.
   103     // Note we can get a function scope here if we're making a temporary in a
   104     // function with no local variables.
   105     if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
   106         return;
   107 
   108     Local<Type> type(ZONE(), ZONE()->types()->getPrimitive(PrimitiveType_Native));
   109     if (!type)
   110         return;
   111 
   112     Local<String> name(ZONE());
   113 #if 0
   114     lifoSlot_ = new (pool_) Variable(this, name, SourcePosition());
   115     lifoSlot_->setType(type);
   116 #endif
   117 }
   118 #endif
   119 
   120 bool
   121 Scope::addSymbol(Symbol *sym)
   122 {
   123     return names_.append(sym);
   124 }
   125 
   126 LocalScope::LocalScope(PoolAllocator &pool)
   127   : Scope(pool, Scope::BLOCK, NULL)
   128 {
   129 }
   130 
   131 LocalScope *
   132 LocalScope::New(PoolAllocator &pool)
   133 {
   134     LocalScope *scope = new (pool) LocalScope(pool);
   135     if (!scope->initialize())
   136         return NULL;
   137 
   138     return scope;
   139 }
   140 
   141 ArgumentScope::ArgumentScope(PoolAllocator &pool)
   142   : Scope(pool, Scope::FUNCTION, NULL)
   143 {
   144 }
   145 
   146 ArgumentScope *
   147 ArgumentScope::New(PoolAllocator &pool)
   148 {
   149     ArgumentScope *scope = new (pool) ArgumentScope(pool);
   150     if (!scope->initialize())
   151         return NULL;
   152 
   153     return scope;
   154 }
   155 
   156 GlobalScope::GlobalScope(PoolAllocator &pool, ImportScope *parent)
   157   : Scope(pool, Scope::GLOBAL, parent)
   158 {
   159 }
   160 
   161 GlobalScope *
   162 GlobalScope::New(PoolAllocator &pool, ImportScope *parent)
   163 {
   164     GlobalScope *scope = new (pool) GlobalScope(pool, parent);
   165     if (!scope->initialize())
   166         return NULL;
   167 
   168     return scope;
   169 }
   170 
   171 ImportScope::ImportScope(PoolAllocator &pool)
   172   : Scope(pool, Scope::IMPORT, NULL)
   173 {
   174 }
   175 
   176 ImportScope *
   177 ImportScope::New(PoolAllocator &pool)
   178 {
   179     ImportScope *scope = new (pool) ImportScope(pool);
   180     if (!scope->initialize())
   181         return NULL;
   182 
   183     return scope;
   184 }