Source Code Cross Referenced for CallFrame.java in  » Scripting » jacl » tcl » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * CallFrame.java
003:         *
004:         * Copyright (c) 1997 Cornell University.
005:         * Copyright (c) 1997-1998 Sun Microsystems, Inc.
006:         *
007:         * See the file "license.terms" for information on usage and
008:         * redistribution of this file, and for a DISCLAIMER OF ALL
009:         * WARRANTIES.
010:         * 
011:         * RCS: @(#) $Id: CallFrame.java,v 1.17 2006/03/27 00:06:42 mdejong Exp $
012:         *
013:         */
014:
015:        package tcl.lang;
016:
017:        import java.util.*;
018:
019:        /**
020:         * This class implements a frame in the call stack.
021:         *
022:         * This class can be overridden to define new variable scoping rules for
023:         * the Tcl interpreter.
024:         */
025:
026:        public class CallFrame {
027:            /**
028:             * The interpreter associated with this call frame.
029:             */
030:
031:            Interp interp;
032:
033:            /**
034:             * The Namespace this CallFrame is executing in.
035:             * Used to resolve commands and global variables.
036:             */
037:
038:            Namespace ns;
039:
040:            /**
041:             * If true, the frame was pushed to execute a Tcl procedure
042:             * and may have local vars. If false, the frame was pushed to execute
043:             * a namespace command and var references are treated as references
044:             * to namespace vars; varTable is ignored.
045:             */
046:
047:            boolean isProcCallFrame;
048:
049:            /**
050:             * Stores the arguments of the procedure associated with this CallFrame.
051:             * Is null for global level.
052:             */
053:
054:            TclObject[] objv;
055:
056:            /**
057:             * Value of interp.frame when this procedure was invoked
058:             * (i.e. next in stack of all active procedures).
059:             */
060:
061:            CallFrame caller;
062:
063:            /**
064:             * Value of interp.varFrame when this procedure was invoked
065:             * (i.e. determines variable scoping within caller; same as
066:             * caller unless an "uplevel" command or something equivalent
067:             * was active in the caller).
068:             */
069:
070:            CallFrame callerVar;
071:
072:            /**
073:             * Level of recursion. = 0 for the global level.
074:             */
075:
076:            int level;
077:
078:            /**
079:             * Stores the variables of this CallFrame.
080:             */
081:
082:            HashMap varTable;
083:
084:            /**
085:             * Array of local variables in a compiled proc frame.
086:             * These include locals set in the proc, globals
087:             * or other variable brought into the proc scope,
088:             * and compiler generated aliases to globals.
089:             * This array is always null for an interpreted proc.
090:             * A compiled proc implementation known which variable
091:             * is associated with  each slot at compile time,
092:             * so it is able to avoid a hashtable lookup each time
093:             * the variable is accessed. Both scalar variables and
094:             * array variables could appear in this array.
095:             */
096:
097:            Var[] compiledLocals;
098:            String[] compiledLocalsNames;
099:
100:            /**
101:             * Creates a CallFrame for the global variables.
102:             * @param interp current interpreter.
103:             */
104:
105:            CallFrame(Interp i) {
106:                interp = i;
107:                ns = i.globalNs;
108:                varTable = null;
109:                compiledLocals = null;
110:                compiledLocalsNames = null;
111:                caller = null;
112:                callerVar = null;
113:                objv = null;
114:                level = 0;
115:                isProcCallFrame = true;
116:            }
117:
118:            /**
119:             * Creates a CallFrame. It changes the following variables:
120:             *
121:             * <ul>
122:             *     <li> this.caller
123:             *	   <li> this.callerVar
124:             *	   <li> interp.frame
125:             *	   <li> interp.varFrame
126:             * </ul>
127:             * @param i current interpreter.
128:             * @param proc the procedure to invoke in this call frame.
129:             * @param objv the arguments to the procedure.
130:             * @exception TclException if error occurs in parameter bindings.
131:             */
132:            CallFrame(Interp i, Procedure proc, TclObject[] objv)
133:                    throws TclException {
134:                this (i);
135:
136:                try {
137:                    chain(proc, objv);
138:                } catch (TclException e) {
139:                    dispose();
140:                    throw e;
141:                }
142:            }
143:
144:            /**
145:             * Chain this frame into the call frame stack and binds the parameters
146:             * values to the formal parameters of the procedure.
147:             *
148:             * @param proc the procedure.
149:             * @param proc argv the parameter values.
150:             * @exception TclException if wrong number of arguments.
151:             */
152:            void chain(Procedure proc, TclObject[] objv) throws TclException {
153:                this .ns = proc.wcmd.ns;
154:                this .objv = objv;
155:                // FIXME : quick level hack : fix later
156:                level = (interp.varFrame == null) ? 1
157:                        : (interp.varFrame.level + 1);
158:                caller = interp.frame;
159:                callerVar = interp.varFrame;
160:                interp.frame = this ;
161:                interp.varFrame = this ;
162:
163:                // parameter bindings
164:
165:                int numArgs = proc.argList.length;
166:
167:                if ((!proc.isVarArgs) && (objv.length - 1 > numArgs)) {
168:                    wrongNumProcArgs(objv[0], proc);
169:                }
170:
171:                int i, j;
172:                for (i = 0, j = 1; i < numArgs; i++, j++) {
173:                    // Handle the special case of the last formal being
174:                    // "args".  When it occurs, assign it a list consisting of
175:                    // all the remaining actual arguments.
176:
177:                    TclObject varName = proc.argList[i][0];
178:                    TclObject value = null;
179:
180:                    if ((i == (numArgs - 1)) && proc.isVarArgs) {
181:                        value = TclList.newInstance();
182:                        value.preserve();
183:                        for (int k = j; k < objv.length; k++) {
184:                            TclList.append(interp, value, objv[k]);
185:                        }
186:                        interp.setVar(varName, value, 0);
187:                        value.release();
188:                    } else {
189:                        if (j < objv.length) {
190:                            value = objv[j];
191:                        } else if (proc.argList[i][1] != null) {
192:                            value = proc.argList[i][1];
193:                        } else {
194:                            wrongNumProcArgs(objv[0], proc);
195:                        }
196:                        interp.setVar(varName, value, 0);
197:                    }
198:                }
199:            }
200:
201:            private String wrongNumProcArgs(TclObject name, Procedure proc)
202:                    throws TclException {
203:                int i;
204:                StringBuffer sbuf = new StringBuffer(200);
205:                sbuf.append("wrong # args: should be \"");
206:                sbuf.append(name.toString());
207:                for (i = 0; i < proc.argList.length; i++) {
208:                    TclObject arg = proc.argList[i][0];
209:                    TclObject def = proc.argList[i][1];
210:
211:                    sbuf.append(" ");
212:                    if (def != null)
213:                        sbuf.append("?");
214:                    sbuf.append(arg.toString());
215:                    if (def != null)
216:                        sbuf.append("?");
217:                }
218:                sbuf.append("\"");
219:                throw new TclException(interp, sbuf.toString());
220:            }
221:
222:            /**
223:             * @param name the name of the variable.
224:             *
225:             * @return true if a variable exists and is defined inside this
226:             *     CallFrame, false otherwise
227:             */
228:
229:            static boolean exists(Interp interp, String name) {
230:                try {
231:                    Var[] result = Var.lookupVar(interp, name, null, 0,
232:                            "lookup", false, false);
233:                    if (result == null) {
234:                        return false;
235:                    }
236:                    if (result[0].isVarUndefined()) {
237:                        return false;
238:                    }
239:                    return true;
240:                } catch (TclException e) {
241:                    throw new TclRuntimeError("unexpected TclException: " + e);
242:                }
243:            }
244:
245:            /**
246:             * @return a List of the names of the (defined) variables
247:             *     in this CallFrame.
248:             */
249:
250:            // FIXME : need to port Tcl 8.1 implementation here
251:            ArrayList getVarNames() {
252:                ArrayList alist = new ArrayList();
253:
254:                if (varTable == null) {
255:                    return alist;
256:                }
257:
258:                for (Iterator iter = varTable.entrySet().iterator(); iter
259:                        .hasNext();) {
260:                    Map.Entry entry = (Map.Entry) iter.next();
261:                    Var v = (Var) entry.getValue();
262:                    if (!v.isVarUndefined()) {
263:                        alist.add(v.hashKey);
264:                    }
265:                }
266:                return alist;
267:            }
268:
269:            /**
270:             * @return a List of the names of the (defined) local variables
271:             *     in this CallFrame (excluding upvar's)
272:             */
273:
274:            ArrayList getLocalVarNames() {
275:                ArrayList alist = new ArrayList();
276:
277:                if (varTable == null) {
278:                    return alist;
279:                }
280:
281:                for (Iterator iter = varTable.entrySet().iterator(); iter
282:                        .hasNext();) {
283:                    Map.Entry entry = (Map.Entry) iter.next();
284:                    Var v = (Var) entry.getValue();
285:                    if (!v.isVarUndefined() && !v.isVarLink()) {
286:                        alist.add(v.hashKey);
287:                    }
288:                }
289:                return alist;
290:            }
291:
292:            /**
293:             * Tcl_GetFrame -> getFrame
294:             *
295:             *	Given a description of a procedure frame, such as the first
296:             *	argument to an "uplevel" or "upvar" command, locate the
297:             *	call frame for the appropriate level of procedure.
298:             *
299:             *	The return value is 1 if string was either a number or a number
300:             *  preceded by "#" and it specified a valid frame. 0 is returned
301:             *  if string isn't one of the two things above (in this case,
302:             *  the lookup acts as if string were "1"). The frameArr[0] reference
303:             *  will be filled by the reference of the desired frame (unless an
304:             *  error occurs, in which case it isn't modified).
305:             *
306:             * @param string a string that specifies the level.
307:
308:             * @exception TclException if s is a valid level specifier but
309:             *     refers to a bad level that doesn't exist.
310:             */
311:
312:            static int getFrame(Interp interp, String string,
313:                    CallFrame[] frameArr) throws TclException {
314:                int curLevel, level, result;
315:                CallFrame frame;
316:
317:                // Parse string to figure out which level number to go to.
318:
319:                result = 1;
320:                curLevel = (interp.varFrame == null) ? 0
321:                        : interp.varFrame.level;
322:
323:                if ((string.length() > 0) && (string.charAt(0) == '#')) {
324:                    level = Util.getInt(interp, string.substring(1));
325:                    if (level < 0) {
326:                        throw new TclException(interp, "bad level \"" + string
327:                                + "\"");
328:                    }
329:                } else if ((string.length() > 0)
330:                        && Character.isDigit(string.charAt(0))) {
331:                    level = Util.getInt(interp, string);
332:                    level = curLevel - level;
333:                } else {
334:                    level = curLevel - 1;
335:                    result = 0;
336:                }
337:
338:                // FIXME: is this a bad comment from some other proc?
339:                // Figure out which frame to use, and modify the interpreter so
340:                // its variables come from that frame.
341:
342:                if (level == 0) {
343:                    frame = null;
344:                } else {
345:                    for (frame = interp.varFrame; frame != null; frame = frame.callerVar) {
346:                        if (frame.level == level) {
347:                            break;
348:                        }
349:                    }
350:                    if (frame == null) {
351:                        throw new TclException(interp, "bad level \"" + string
352:                                + "\"");
353:                    }
354:                }
355:                frameArr[0] = frame;
356:                return result;
357:            }
358:
359:            /**
360:             * This method is called when this CallFrame is no longer needed.
361:             * Removes the reference of this object from the interpreter so
362:             * that this object can be garbage collected.
363:             * <p>
364:             * For this procedure to work correctly, it must not be possible
365:             * for any of the variable in the table to be accessed from Tcl
366:             * commands (e.g. from trace procedures).
367:             */
368:
369:            protected void dispose() {
370:                // Unchain this frame from the call stack.
371:
372:                interp.frame = caller;
373:                interp.varFrame = callerVar;
374:                caller = null;
375:                callerVar = null;
376:
377:                if (varTable != null) {
378:                    Var.deleteVars(interp, varTable);
379:                    varTable = null;
380:                }
381:                if (compiledLocals != null) {
382:                    Var.deleteVars(interp, compiledLocals);
383:                    compiledLocals = null;
384:                    compiledLocalsNames = null;
385:                }
386:            }
387:
388:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.