001: /*
002: * @(#)Frame.java 1.4 05/06/14
003: *
004: * Copyright (c) 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.compiler;
010:
011: import java.util.HashMap;
012: import java.util.Map;
013: import java.util.ArrayList;
014: import java.util.List;
015: import java.util.Iterator;
016:
017: /**
018: * This class represents a function scope.
019: */
020: class Frame implements Cloneable {
021: Frame parent;
022: SymbolSet symbolSet;
023: SymbolSet bottom;
024: String fname;
025: String[] locals;
026: List imports = new ArrayList();
027: Map exports = new HashMap();
028: boolean leaf = true;
029: Object attr;
030: boolean finallySet;
031: BranchEnv branch_env;
032:
033: Frame() {
034: openLocal();
035: }
036:
037: Frame(String locals[], String fname, Frame parent, boolean leaf) {
038: this .parent = parent;
039: if (fname != null) {
040: this .fname = fname.intern();
041: }
042: for (int i = 0; i < locals.length; i++) {
043: locals[i] = locals[i].intern();
044: }
045: this .locals = locals;
046: this .bottom = new SymbolSet(null);
047: this .symbolSet = bottom;
048: this .leaf = leaf;
049: openLocal();
050: }
051:
052: void openLocal() {
053: this .symbolSet = new SymbolSet(symbolSet);
054: }
055:
056: void closeLocal() {
057: this .symbolSet = symbolSet.parent;
058: }
059:
060: LocalInfo lookup(String sym) {
061: if (branch_env != null) {
062: LocalInfo info = symbolSet.assoc(sym);
063: if (info == null) {
064: info = branch_env.lookup(sym);
065: }
066: return info;
067: } else {
068: return symbolSet.assoc(sym);
069: }
070: }
071:
072: LocalInfo assoc(String sym) {
073: if (branch_env != null) {
074: LocalInfo info = symbolSet.assoc(sym);
075: if (info == null) {
076: info = branch_env.assoc(sym);
077: }
078: return info;
079: } else {
080: return symbolSet.assoc(sym);
081: }
082: }
083:
084: boolean setReference(String sym) {
085: LocalInfo info = assoc(sym);
086: if (info != null) {
087: info.initialized = true;
088: return true;
089: } else {
090: return false;
091: }
092: }
093:
094: Reference findReference(String sym) {
095: return getReference(sym, true);
096: }
097:
098: Reference getReference(String sym) {
099: return getReference(sym, false);
100: }
101:
102: Reference getReference(String sym, boolean flag) {
103: LocalInfo info;
104: if (flag) {
105: info = lookup(sym);
106: if (info != null) {
107: if (branch_env != null) {
108: branch_env.declare(sym, info.map, info.index);
109: } else {
110: symbolSet.add(sym, info.map, info.index);
111: }
112: }
113: } else {
114: info = assoc(sym);
115: }
116:
117: if (info != null) {
118: return new Reference(sym, info);
119: }
120: if (locals != null) {
121: for (int i = 0; i < locals.length; i++) {
122: if (locals[i] == sym) {
123: return new Reference(sym, 1, i, true);
124: }
125: }
126: }
127: return null; // not found
128: }
129:
130: public void declare(String symbol, int key, int idx) {
131: if (branch_env != null) {
132: branch_env.declare(symbol, key, idx);
133: } else {
134: bottom.add(symbol, key, idx);
135: }
136: }
137:
138: public void declare(String symbol, int key) {
139: if (branch_env != null) {
140: branch_env.declare(symbol, key);
141: } else {
142: bottom.add(symbol, key);
143: }
144: }
145:
146: public void _declare(String symbol, int key, int idx) {
147: symbolSet.add(symbol, key, idx);
148: }
149:
150: public void _declare(String symbol, int key) {
151: symbolSet.add(symbol, key);
152: }
153:
154: public void _declare_frame(String symbol, int key) {
155: symbolSet.add(symbol, key, this );
156: }
157:
158: void openBranchEnv() {
159: branch_env = new BranchEnv(branch_env, symbolSet);
160: }
161:
162: void addBranch() {
163: branch_env.addBranch(symbolSet);
164: }
165:
166: void closeBranchEnv() {
167: branch_env.close();
168: if (branch_env.parent == null && bottom != null) {
169: for (Iterator it = branch_env.symbolToLocalInfo.values()
170: .iterator(); it.hasNext();) {
171: LocalInfo info = (LocalInfo) it.next();
172: bottom.add(info.symbol, info.map, info.index);
173: }
174: }
175: branch_env = branch_env.parent;
176: }
177:
178: public Object clone() {
179: try {
180: Frame frame = (Frame) super .clone();
181: /*
182: * frame.locals = new String[locals.length];
183: * System.arraycopy(frame.locals, 0, locals, 0, locals.length);
184: * frame.bottom = (SymbolSet)bottom.clone();
185: * frame.symbolSet =(SymbolSet)symbolSet.clone();
186: * frame.imports = (ArrayList)imports.clone();
187: * frame.exports =(HashMap)exports.clone();
188: */
189: return frame;
190: } catch (Throwable t) {
191: throw new InternalError();
192: }
193: }
194: }
|