KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > python > compiler > ScopeInfo


1 // (C) Copyright 2001 Samuele Pedroni
2

3 package org.python.compiler;
4
5 import java.util.*;
6 import org.python.parser.SimpleNode;
7
8 public class ScopeInfo extends Object JavaDoc implements ScopeConstants {
9
10     public SimpleNode scope_node;
11     public String JavaDoc scope_name;
12     public int level;
13     public int func_level;
14     public int list_comprehension_count;
15
16     public void dump() { // for debugging
17
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 JavaDoc name = (String JavaDoc)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             // func scope global (affect nested scopes)
29
// vs. class scope global
30
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 JavaDoc 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 JavaDoc name) {
65         // global kind = func vs. class
66
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 JavaDoc name) {
80 //System.out.println("addParam " + name);
81
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 JavaDoc 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 JavaDoc name) {
102         if (tbl.get(name) == null) {
103             tbl.put(name, new SymInfo(0));
104             return;
105         }
106     }
107
108     private final static Object JavaDoc PRESENT = new Object JavaDoc();
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 JavaDoc {
121         if (up == null) return; // top level => nop
122

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 JavaDoc name = (String JavaDoc)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                 // not func global and bound ?
138
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 JavaDoc name = (String JavaDoc)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) { // ?? only func
161
// System.err.println("local: "+name);
162
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 JavaDoc {
187         String JavaDoc 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 JavaDoc 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; // env = cell...,free...
208
Hashtable up_tbl = up.tbl;
209         boolean nested = up.kind != TOPSCOPE;
210         for (Enumeration e = tbl.keys(); e.hasMoreElements(); ) {
211             String JavaDoc name = (String JavaDoc)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                 // ?? differs from CPython -- what is the intended behaviour?
217
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                     // ! func global affect nested scopes
225
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 JavaDoc toString() {
237         return "ScopeInfo[" + scope_name + " " + kind + "]@" +
238                 System.identityHashCode(this);
239     }
240 }
241
Popular Tags