1 package gnu.expr; 2 import gnu.bytecode.*; 3 4 8 9 public abstract class ScopeExp extends Expression 10 { 11 Declaration decls; 12 Declaration last; 13 14 private Scope scope; 15 16 public Declaration firstDecl () { return decls; } 17 18 public Scope getVarScope () 19 { 20 Scope sc = scope; 21 if (sc == null) 22 scope = sc = new Scope(); 23 return sc; 24 } 25 26 30 public void popScope (CodeAttr code) 31 { 32 for (Declaration decl = firstDecl(); decl != null; decl = decl.nextDecl()) 33 decl.var = null; 34 code.popScope(); 35 scope = null; 36 } 37 38 public void add (Declaration decl) 39 { 40 if (last == null) 41 decls = decl; 42 else 43 last.next = decl; 44 last = decl; 45 decl.context = this; 46 } 47 48 50 public void add (Declaration prev, Declaration decl) 51 { 52 if (prev == null) 53 { decl.next = decls; 55 decls = decl; 56 } 57 else 58 { 59 decl.next = prev.next; 60 prev.next = decl; 61 } 62 if (last == prev) 63 last = decl; 64 decl.context = this; 65 } 66 67 69 public void replaceFollowing (Declaration prev, Declaration newDecl) 70 { 71 Declaration oldDecl; 72 if (prev == null) 73 { 74 oldDecl = decls; 75 decls = newDecl; 76 } 77 else 78 { 79 oldDecl = prev.next; 80 prev.next = newDecl; 81 } 82 newDecl.next = oldDecl.next; 83 if (last == oldDecl) 84 last = newDecl; 85 oldDecl.next = null; 86 newDecl.context = this; 87 } 88 89 public void remove (Declaration decl) 90 { 91 Declaration prev = null; 92 for (Declaration cur = firstDecl(); cur != null; cur = cur.nextDecl()) 93 { 94 if (cur == decl) 95 { 96 remove(prev, decl); 97 return; 98 } 99 prev = cur; 100 } 101 } 102 103 public void remove (Declaration prev, Declaration decl) 104 { 105 if (prev == null) 106 decls = decl.next; 107 else 108 prev.next = decl.next; 109 if (last == decl) 110 last = prev; 111 } 112 113 public ScopeExp () { } 114 115 116 public ScopeExp outer; 117 118 public LambdaExp currentLambda () 119 { 120 ScopeExp exp = this; 121 for (;; exp = exp.outer) 122 { 123 if (exp == null) 124 return null; 125 if (exp instanceof LambdaExp) 126 return (LambdaExp) exp; 127 } 128 } 129 130 public ModuleExp currentModule () 131 { 132 ScopeExp exp = this; 133 for (;; exp = exp.outer) 134 { 135 if (exp == null) 136 return null; 137 if (exp instanceof ModuleExp) 138 return (ModuleExp) exp; 139 } 140 } 141 142 147 public Declaration lookup (Object sym) 148 { 149 if (sym != null) 150 { 151 for (Declaration decl = firstDecl(); 152 decl != null; decl = decl.nextDecl()) 153 { 154 if (sym.equals(decl.symbol)) 155 return decl; 156 } 157 } 158 return null; 159 } 160 161 public Declaration lookup (Object sym, Language language, int namespace) 162 { 163 for (Declaration decl = firstDecl(); 164 decl != null; decl = decl.nextDecl()) 165 { 166 if (sym.equals(decl.symbol) 167 && language.hasNamespace(decl, namespace)) 168 return decl; 169 } 170 return null; 171 } 172 173 174 public Declaration getNoDefine (Object name) 175 { 176 Declaration decl = lookup(name); 177 if (decl == null) 178 { 179 decl = addDeclaration(name); 180 decl.flags |= Declaration.NOT_DEFINING | Declaration.IS_UNKNOWN; 181 } 182 return decl; 183 } 184 185 186 public Declaration getDefine (Object name, char severity, Compilation parser) 187 { 188 Declaration decl = lookup(name); 189 if (decl == null) 190 decl = addDeclaration(name); 191 else if ((decl.flags & (Declaration.NOT_DEFINING | Declaration.IS_UNKNOWN)) 192 != 0) 193 decl.flags &= ~ (Declaration.NOT_DEFINING|Declaration.IS_UNKNOWN); 194 else 195 { 196 Declaration newDecl = addDeclaration(name); 197 duplicateDeclarationError(decl, newDecl, parser); 198 decl = newDecl; 199 } 200 return decl; 201 } 202 203 public static void duplicateDeclarationError (Declaration oldDecl, 204 Declaration newDecl, 205 Compilation comp) 206 { 207 comp.error('e', newDecl, "duplicate declaration of '", "'"); 208 comp.error('e', oldDecl, "(this is the previous declaration of '", "')"); 209 } 210 211 215 public final Declaration addDeclaration (Object name) 216 { 217 Declaration decl = new Declaration (name); 218 add(decl); 219 return decl; 220 } 221 222 227 public final Declaration addDeclaration (Object name, Type type) 228 { 229 Declaration decl = new Declaration (name, type); 230 add(decl); 231 return decl; 232 } 233 234 237 public final void addDeclaration (Declaration decl) 238 { 239 add(decl); } 241 242 public int countDecls () 243 { 244 int n = 0; 245 for (Declaration decl = firstDecl(); decl != null; decl = decl.nextDecl()) 246 n++; 247 return n; 248 } 249 250 public static int nesting (ScopeExp sc) 251 { 252 int n = 0; 253 while (sc != null) 254 { 255 sc = sc.outer; 256 n++; 257 } 258 return n; 259 } 260 261 262 protected int frameSize; 263 264 265 protected void setIndexes () 266 { 267 int i = 0; 268 for (Declaration decl = firstDecl(); decl != null; decl = decl.nextDecl()) 269 { 270 decl.evalIndex = i++; 271 } 272 frameSize = i; 273 } 274 275 protected Expression walk (ExpWalker walker) 276 { 277 return walker.walkScopeExp(this); 278 } 279 280 public String toString() { return getClass().getName()+"#"+id; } 281 282 static int counter; 283 284 public int id = ++counter; 285 } 286 | Popular Tags |