1 /* Digital Mars DMDScript source code. 2 * Copyright (c) 2000-2002 by Chromium Communications 3 * D version Copyright (c) 2004-2010 by Digital Mars 4 * Distributed under the Boost Software License, Version 1.0. 5 * (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 * written by Walter Bright 7 * http://www.digitalmars.com 8 * 9 * D2 port by Dmitry Olshansky 10 * 11 * DMDScript is implemented in the D Programming Language, 12 * http://www.digitalmars.com/d/ 13 * 14 * For a C++ implementation of DMDScript, including COM support, see 15 * http://www.digitalmars.com/dscript/cppscript.html 16 */ 17 18 19 module dmdscript.scopex; 20 21 import dmdscript.script; 22 import dmdscript.program; 23 import dmdscript.symbol; 24 import dmdscript.functiondefinition; 25 import dmdscript.identifier; 26 import dmdscript.statement; 27 struct Scope 28 { 29 Scope* enclosing; // enclosing Scope 30 31 d_string src; // source text 32 Program program; // Root module 33 ScopeSymbol * scopesym; // current symbol 34 FunctionDefinition funcdef; // what function we're in 35 SymbolTable ** plabtab; // pointer to label symbol table 36 uint nestDepth; // static nesting level 37 // 38 ScopeStatement scopeContext; // nesting of scope statements 39 Statement continueTarget; 40 Statement breakTarget; 41 SwitchStatement switchTarget; 42 43 ErrInfo errinfo; // semantic() puts error messages here 44 45 void zero() 46 { 47 enclosing = null; 48 49 src = null; 50 program = null; 51 scopesym = null; 52 funcdef = null; 53 plabtab = null; 54 nestDepth = 0; 55 56 scopeContext = null; 57 continueTarget = null; 58 breakTarget = null; 59 switchTarget = null; 60 } 61 62 void ctor(Scope* enclosing) 63 { 64 zero(); 65 this.program = enclosing.program; 66 this.funcdef = enclosing.funcdef; 67 this.plabtab = enclosing.plabtab; 68 this.nestDepth = enclosing.nestDepth; 69 this.enclosing = enclosing; 70 } 71 72 void ctor(Program program, FunctionDefinition fd) 73 { // Create root scope 74 zero(); 75 this.program = program; 76 this.funcdef = fd; 77 this.plabtab = &fd.labtab; 78 } 79 80 void ctor(FunctionDefinition fd) 81 { // Create scope for anonymous function fd 82 zero(); 83 this.funcdef = fd; 84 this.plabtab = &fd.labtab; 85 } 86 87 void dtor() 88 { 89 // Help garbage collector 90 zero(); 91 } 92 93 Scope* push() 94 { 95 Scope* s; 96 97 s = new Scope; 98 s.ctor(&this); 99 return s; 100 } 101 Scope* push(FunctionDefinition fd) 102 { 103 Scope* s; 104 105 s = push(); 106 s.funcdef = fd; 107 s.plabtab = &fd.labtab; 108 return s; 109 } 110 111 void pop() 112 { 113 if(enclosing && !enclosing.errinfo.message) 114 enclosing.errinfo = errinfo; 115 zero(); // aid GC 116 } 117 118 119 Symbol search(Identifier *ident) 120 { 121 Symbol s; 122 Scope* sc; 123 124 //writef("Scope.search(%p, '%s')\n", this, ident.toString()); 125 for(sc = &this; sc; sc = sc.enclosing) 126 { 127 s = sc.scopesym.search(ident); 128 if(s) 129 return s; 130 } 131 132 assert(0); 133 //error("Symbol '%s' is not defined", ident.toString()); 134 } 135 136 Symbol insert(Symbol s) 137 { 138 if(!scopesym.symtab) 139 scopesym.symtab = new SymbolTable(); 140 return scopesym.symtab.insert(s); 141 } 142 143 LabelSymbol searchLabel(Identifier *ident) 144 { 145 SymbolTable *st; 146 LabelSymbol ls; 147 148 //writef("Scope::searchLabel('%ls')\n", ident.toDchars()); 149 assert(plabtab); 150 st = *plabtab; 151 if(!st) 152 { 153 st = new SymbolTable(); 154 *plabtab = st; 155 } 156 ls = cast(LabelSymbol )st.lookup(ident); 157 return ls; 158 } 159 160 LabelSymbol insertLabel(LabelSymbol ls) 161 { 162 SymbolTable *st; 163 164 //writef("Scope::insertLabel('%s')\n", ls.toString()); 165 assert(plabtab); 166 st = *plabtab; 167 if(!st) 168 { 169 st = new SymbolTable(); 170 *plabtab = st; 171 } 172 ls = cast(LabelSymbol )st.insert(ls); 173 return ls; 174 } 175 176 d_string getSource() 177 { 178 Scope* sc; 179 180 for(sc = &this; sc; sc = sc.enclosing) 181 { 182 if(sc.src) 183 return sc.src; 184 } 185 186 return null; 187 } 188 } 189