5 public int Scope_gid = 0;
7 public class Scope : Object
13 public Gee.ArrayList<Scope> subScopes;
14 Gee.HashMap<string,Identifier> identifiers; // map of identifiers to {Identifier} objects
15 Gee.HashMap<string,string> hints;
20 Gee.HashMap<string,bool> protectedVars ; // only used by to parent..
23 public Scope(int braceN, Scope? parent, int startTokN, Token? token) // Identifier? lastIdent
25 //if (lastIdent.length) {
26 // println("NEW SCOPE: " + lastIdent);
32 this.identifiers = new Gee.HashMap<string,Identifier>();
33 this.subScopes = new Gee.ArrayList<Scope> ();
34 this.hints = new Gee.HashMap<string,string>();
35 this.protectedVars = new Gee.HashMap<string,bool>();
36 //this.ident = lastIdent;
37 this.id = Scope_gid++;
39 //print("ADD SCOPE(" + this.gid + ") TO "+ (parent ? this.parent.gid : 'TOP') + ' : ' +
40 // (token ? token.toString() : ''));
43 this.parent.subScopes.add(this);
57 * dump the scope to StdOut...
60 void dump (string indent)
62 //indent = indent || '';
64 indent + "Scope: %d\n" +
65 indent + "Started: %d\n" +
66 indent + "- idents..: fixme\n"
69 this.token != null ? this.token.line : -1
70 // " + XObject.keys(this.identifiers).join(", ") + "
72 foreach(var s in this.subScopes) {
80 public Identifier declareIdentifier(string symbol, Token token)
83 //print("SCOPE : " + this.gid + " :SYM: " + symbol + " " + token.toString()+"");
85 if (!this.identifiers.has_key(symbol)) {
87 this.identifiers.set(symbol, new Identifier(symbol, this));
91 //if (typeof(token) != 'undefined') { // shoudl this happen?
92 token.identifier = this.identifiers.get(symbol);
95 if (this.braceN < 0) {
96 // then it's global...
97 this.identifiers[symbol].toMunge = false;
101 this.addToParentScope(symbol);
102 return this.identifiers.get(symbol);
107 public Identifier? getIdentifier(string symbol, Token token)
109 if (!this.identifiers.has_key(symbol)) {
111 //if (['String', 'Date'].indexOf(symbol)> -1) {
115 //print("SCOPE : " + this.gid +" = SYMBOL NOT FOUND?" + token.toString());
118 //print("SCOPE : " + this.gid +" = FOUND:" + token.toString());
119 return this.identifiers.get(symbol);
122 public void addHint(string varName, string varType) {
124 this.hints.set(varName, varType);
126 public void preventMunging () {
130 //usedsymcache : false,
132 public string[] getUsedSymbols () {
134 string[] result = {};
136 // if (this.usedsymcache !== false) {
137 // return this.usedsymcache;
140 var idents = this.identifiers;
141 var iter = idents.map_iterator();
142 while (iter.next()) {
143 var i = iter.get_key();
144 //println('<b>'+i+'</b>='+typeof(idents[i]) +'<br/>');
145 var identifier = this.identifiers.get(i);
146 var mungedValue = identifier.mungedValue;
148 if (mungedValue.length < 1) {
149 //println(identifier.toSource());
150 mungedValue = identifier.name;
152 result += mungedValue;
154 //println("Symbols for ("+ this.id +"): <B>" + result.join(',') + "</B><BR/>");
155 //this.usedsymcache = result;
159 string[] getAllUsedSymbols()
161 var result = this.getUsedSymbols();
162 var scope = this.parent;
163 while (scope != null) {
164 var ps = scope.getUsedSymbols();
165 for (var i =0; i< ps.length; i++) {
168 scope = scope.parent;
170 //println("Done - addused");
173 /** - we need to register short vairalbes so they never get munged into.. */
174 public void addToParentScope(string ident)
176 if (ident.length > 2) {
179 var scope = this.parent;
180 while (scope != null) {
181 //println("addused:"+scope.id);
182 if (scope.parent != null) {
183 scope.protectedVars.set(ident, true);
185 scope = scope.parent;
189 public bool isProtectedVar(string ident)
191 if (ident.length > 2) {
194 var scope = this.parent;
195 while (scope != null) {
196 //println("addused:"+scope.id);
197 if (scope.parent != null) {
198 if (scope.protectedVars.has_key(ident)) {
202 scope = scope.parent;
211 * set's all the munged values on the identifiers.
220 // Stop right here if this scope was flagged as unsafe for munging.
221 // println("MUNGE: SKIP - Scope" + this.id+"</BR>");
233 // Do not munge symbols in the global scope!
234 if (this.parent == null) {
235 // same code at bottom... ?? goto::
237 //println("Doing sub scopes");
238 for (var j = 0; j < this.subScopes.size; j++) {
239 this.subScopes.get(j).munge();
247 var iter = this.identifiers.map_iterator();
248 while (iter.next()) {
249 all += iter.get_key();
251 //print("MUNGE: " + all.join(', '));
253 //println("MUNGE: Building FreeSyms:" + this.id+"</BR>");
255 Gee.ArrayList<string> freeSymbols= new Gee.ArrayList<string>();
257 var sy = this.getAllUsedSymbols();
259 Scope.array_merge(freeSymbols,Scope.ones);
262 //println(freeSymbols.toSource());
264 //println("MUNGE: Replacing " + this.id+"</BR>");
265 iter = this.identifiers.map_iterator();
266 while (iter.next()) {
267 var i = iter.get_key();
269 // is the identifer in the global scope!?!!?
272 if (!this.identifiers.get(i).toMunge) {
273 //print("SKIP toMunge==false : " + i)
277 if (this.isProtectedVar(i)) {
278 //print("SKIP PROTECTED: " + i)
284 //if (this.identifiers[i].constructor != Identifier) {
285 // print("SKIP NOT IDENTIFIER : " + i)
288 // println("IDENT:" +i+'</BR>');
290 if (repsym.length < 1) {
291 if (freeSymbols.size < 1) {
292 Scope.array_merge(freeSymbols,Scope.twos);
294 repsym = freeSymbols.remove_at(0); // pop off beginngin???
297 var identifier = this.identifiers.get(i);
298 //println(typeof(identifier.name));
299 var mungedValue = identifier.name;
301 //println([ repsym,mungedValue ]);
303 if (this.mungeM && repsym.length < mungedValue.length) {
304 //print("REPLACE:"+ mungedValue +" with " + repsym );
305 mungedValue = repsym;
309 identifier.mungedValue = mungedValue;
311 //println("MUNGE: Done " + this.id+"</BR>");
314 //println("Doing sub scopes");
315 for (var j = 0; j < this.subScopes.size; j++) {
316 this.subScopes.get(j).munge();
322 // ---------------------- static part... --------------------
326 static void array_merge(Gee.ArrayList<string> fs, string[] toadd)
328 foreach(var i in toadd) {
333 static bool initialized = false;
334 public static Gee.ArrayList<string> builtin;
335 public static Gee.ArrayList<string> skips;
337 public static string[] ones;
338 public static string[] twos;
339 // static string[] threes : [],
342 if (Scope.initialized) {
345 Scope.initialized = true;
346 Scope.builtin = new Gee.ArrayList<string>();
347 array_merge(Scope.builtin, "NaN,top".split(","));
349 Scope.skips = new Gee.ArrayList<string>();
350 array_merge(Scope.skips, "as,is,do,if,in,for,int,new,try,use,var,NaN,top".split(","));
352 Scope.ones = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".split(",");
353 var n = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9".split(",");
356 for(var i = 0; i < Scope.ones.length; i++) {
357 for(var j = 0; j < n.length; j++) {
358 string tw = Scope.ones[i] + n[j];
359 if (Scope.skips.index_of(tw) < 0) {
364 for(var k = 0; k < n.length; k++) {
365 var thr = a[i] + n[j] + n[k];
366 //println("thr="+ thr + ":iOf="+this.skips.indexOf(thr) );
367 if (this.skips.indexOf(thr) < 0) {
369 this.threes.push(thr);
377 //println("done creating var list");
378 //println("threes="+ this.threes.toSource());