1 3 package org.python.compiler; 4 5 import java.util.*; 6 import org.python.parser.SimpleNode; 7 8 public class ScopeInfo extends Object implements ScopeConstants { 9 10 public SimpleNode scope_node; 11 public String scope_name; 12 public int level; 13 public int func_level; 14 public int list_comprehension_count; 15 16 public void dump() { if (org.python.core.Options.verbose < org.python.core.Py.DEBUG) 18 return; 19 for(int i=0; i<level; i++) System.err.print(' '); 20 System.err.print(((kind != CLASSSCOPE)?scope_name:"class "+ 21 scope_name)+": "); 22 for (Enumeration e = tbl.keys(); e.hasMoreElements(); ) { 23 String name = (String )e.nextElement(); 24 SymInfo info = (SymInfo)tbl.get(name); 25 int flags = info.flags; 26 System.err.print(name); 27 if ((flags&BOUND) != 0) System.err.print('='); 28 if ((flags&NGLOBAL) != 0) System.err.print('G'); 31 else if ((flags&CLASS_GLOBAL) != 0) System.err.print('g'); 32 if ((flags&PARAM) != 0) System.err.print('P'); 33 else if ((flags&FROM_PARAM) != 0) System.err.print('p'); 34 if ((flags&CELL) != 0) System.err.print('!'); 35 if ((flags&FREE) != 0) System.err.print(",f"); 36 System.err.print(" "); 37 } 38 System.err.println(); 39 } 40 41 public ScopeInfo(String name, SimpleNode node, int level, int kind, 42 int func_level, ArgListCompiler ac) { 43 scope_name = name; 44 scope_node = node; 45 this.level = level; 46 this.kind = kind; 47 this.func_level = func_level; 48 this.ac = ac; 49 } 50 51 public int kind; 52 53 public boolean unqual_exec; 54 public boolean exec; 55 public boolean from_import_star; 56 public boolean generator; 57 public int yield_count; 58 59 public ArgListCompiler ac; 60 61 public Hashtable tbl = new Hashtable(); 62 public Vector names = new Vector(); 63 64 public int addGlobal(String name) { 65 int global = kind==CLASSSCOPE?CLASS_GLOBAL:NGLOBAL; 67 SymInfo info = (SymInfo)tbl.get(name); 68 if (info == null) { 69 tbl.put(name,new SymInfo(global|BOUND)); 70 return -1; 71 } 72 int prev = info.flags; 73 info.flags |= global|BOUND; 74 return prev; 75 } 76 77 public int local = 0; 78 79 public void addParam(String name) { 80 tbl.put(name, new SymInfo(PARAM|BOUND,local++)); 82 names.addElement(name); 83 } 84 85 public void markFromParam() { 86 for (Enumeration e=tbl.elements(); e.hasMoreElements(); ) { 87 SymInfo info = (SymInfo)e.nextElement(); 88 info.flags |= FROM_PARAM; 89 } 90 } 91 92 public void addBound(String name) { 93 SymInfo info = (SymInfo)tbl.get(name); 94 if (info == null) { 95 tbl.put(name, new SymInfo(BOUND)); 96 return; 97 } 98 info.flags |= BOUND; 99 } 100 101 public void addUsed(String name) { 102 if (tbl.get(name) == null) { 103 tbl.put(name, new SymInfo(0)); 104 return; 105 } 106 } 107 108 private final static Object PRESENT = new Object (); 109 110 public Hashtable inner_free = new Hashtable(); 111 112 public Vector cellvars = new Vector(); 113 114 public Vector jy_paramcells = new Vector(); 115 116 public int jy_npurecell; 117 118 public int cell; 119 120 public void cook(ScopeInfo up,CompilationContext ctxt) throws Exception { 121 if (up == null) return; 123 boolean func = kind == FUNCSCOPE; 124 Vector purecells = new Vector(); 125 cell = 0; 126 boolean some_inner_free = inner_free.size() > 0; 127 128 for (Enumeration e = inner_free.keys(); e.hasMoreElements(); ) { 129 String name = (String )e.nextElement(); 130 SymInfo info = (SymInfo)tbl.get(name); 131 if (info == null) { 132 tbl.put(name,new SymInfo(FREE)); 133 continue; 134 } 135 int flags = info.flags; 136 if (func) { 137 if ((flags&NGLOBAL) == 0 && (flags&BOUND) != 0) { 139 info.flags |= CELL; 140 if ((info.flags&PARAM) != 0) 141 jy_paramcells.addElement(name); 142 cellvars.addElement(name); 143 info.env_index = cell++; 144 if ((flags&PARAM) == 0) purecells.addElement(name); 145 continue; 146 } 147 } else { 148 info.flags |= FREE; 149 } 150 } 151 boolean some_free = false; 152 153 boolean nested = up.kind != TOPSCOPE; 154 for (Enumeration e = tbl.keys(); e.hasMoreElements(); ) { 155 String name = (String )e.nextElement(); 156 SymInfo info = (SymInfo)tbl.get(name); 157 int flags = info.flags; 158 if (nested && (flags&FREE) != 0) up.inner_free.put(name,PRESENT); 159 if ((flags&(GLOBAL|PARAM|CELL)) == 0) { 160 if ((flags&BOUND) != 0) { names.addElement(name); 163 info.locals_index = local++; 164 continue; 165 } 166 info.flags |= FREE; 167 some_free = true; 168 if (nested) up.inner_free.put(name,PRESENT); 169 } 170 } 171 if ((jy_npurecell = purecells.size()) > 0) { 172 int sz = purecells.size(); 173 for (int i = 0; i < sz; i++) { 174 names.addElement(purecells.elementAt(i)); 175 } 176 } 177 if ((unqual_exec || from_import_star)) { 178 if(some_inner_free) dynastuff_trouble(true, ctxt); 179 else if(func_level > 1 && some_free) 180 dynastuff_trouble(false, ctxt); 181 } 182 183 } 184 185 private void dynastuff_trouble(boolean inner_free, 186 CompilationContext ctxt) throws Exception { 187 String illegal; 188 if (unqual_exec && from_import_star) 189 illegal = "function '"+scope_name+ 190 "' uses import * and bare exec, which are illegal"; 191 else if (unqual_exec) 192 illegal = "unqualified exec is not allowed in function '"+ 193 scope_name+"'"; 194 else 195 illegal = "import * is not allowed in function '"+scope_name+"'"; 196 String why; 197 if (inner_free) 198 why = " because it contains a function with free variables"; 199 else 200 why = " because it contains free variables"; 201 ctxt.error(illegal + why, true, scope_node); 202 } 203 204 public Vector freevars = new Vector(); 205 206 public void setup_closure(ScopeInfo up) { 207 int free = cell; Hashtable up_tbl = up.tbl; 209 boolean nested = up.kind != TOPSCOPE; 210 for (Enumeration e = tbl.keys(); e.hasMoreElements(); ) { 211 String name = (String )e.nextElement(); 212 SymInfo info = (SymInfo)tbl.get(name); 213 int flags = info.flags; 214 if ((flags&FREE) != 0) { 215 SymInfo up_info = (SymInfo)up_tbl.get(name); 216 if (up_info != null) { 218 int up_flags = up_info.flags; 219 if ((up_flags&(CELL|FREE)) != 0) { 220 info.env_index = free++; 221 freevars.addElement(name); 222 continue; 223 } 224 if (nested && (up_flags&NGLOBAL) != 0) { 226 info.flags = NGLOBAL|BOUND; 227 continue; 228 } 229 } 230 info.flags &= ~FREE; 231 } 232 } 233 234 } 235 236 public String toString() { 237 return "ScopeInfo[" + scope_name + " " + kind + "]@" + 238 System.identityHashCode(this); 239 } 240 } 241 | Popular Tags |