wasCSharpSQLite – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #undef DEBUG |
2 | /* |
||
3 | * TclParse.java -- |
||
4 | * |
||
5 | * A Class of the following type is filled in by Parser.parseCommand. |
||
6 | * It describes a single command parsed from an input string. |
||
7 | * |
||
8 | * Copyright (c) 1997 by Sun Microsystems, Inc. |
||
9 | * |
||
10 | * See the file "license.terms" for information on usage and redistribution |
||
11 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
||
12 | * |
||
13 | * Included in SQLite3 port to C# for use in testharness only; 2008 Noah B Hart |
||
14 | * |
||
15 | * RCS @(#) $Id: TclParse.java,v 1.2 1999/05/09 01:33:45 dejong Exp $ |
||
16 | */ |
||
17 | using System; |
||
18 | namespace tcl.lang |
||
19 | { |
||
20 | |||
21 | public class TclParse |
||
22 | { |
||
23 | |||
24 | // The original command string passed to Parser.parseCommand. |
||
25 | |||
26 | public char[] inString; |
||
27 | |||
28 | // Index into 'string' that is the character just after the last |
||
29 | // one in the command string. |
||
30 | |||
31 | public int endIndex; |
||
32 | |||
33 | // Index into 'string' that is the # that begins the first of |
||
34 | // one or more comments preceding the command. |
||
35 | |||
36 | public int commentStart; |
||
37 | |||
38 | // Number of bytes in comments (up through newline character |
||
39 | // that terminates the last comment). If there were no |
||
40 | // comments, this field is 0. |
||
41 | |||
42 | public int commentSize; |
||
43 | |||
44 | // Index into 'string' that is the first character in first |
||
45 | // word of command. |
||
46 | |||
47 | public int commandStart; |
||
48 | |||
49 | // Number of bytes in command, including first character of |
||
50 | // first word, up through the terminating newline, close |
||
51 | // bracket, or semicolon. |
||
52 | |||
53 | public int commandSize; |
||
54 | |||
55 | // Total number of words in command. May be 0. |
||
56 | |||
57 | public int numWords; |
||
58 | |||
59 | // Stores the tokens that compose the command. |
||
60 | |||
61 | public TclToken[] tokenList; |
||
62 | |||
63 | // Total number of tokens in command. |
||
64 | |||
65 | internal int numTokens; |
||
66 | |||
67 | // Total number of tokens available at token. |
||
68 | |||
69 | internal int tokensAvailable; |
||
70 | |||
71 | /* |
||
72 | *---------------------------------------------------------------------- |
||
73 | * |
||
74 | * The fields below are intended only for the private use of the |
||
75 | * parser. They should not be used by procedures that invoke |
||
76 | * Tcl_ParseCommand. |
||
77 | * |
||
78 | *---------------------------------------------------------------------- |
||
79 | */ |
||
80 | |||
81 | // Interpreter to use for error reporting, or null. |
||
82 | |||
83 | internal Interp interp; |
||
84 | |||
85 | // Name of file from which script came, or null. Used for error |
||
86 | // messages. |
||
87 | |||
88 | internal string fileName; |
||
89 | |||
90 | // Line number corresponding to first character in string. |
||
91 | |||
92 | internal int lineNum; |
||
93 | |||
94 | // Points to character in string that terminated most recent token. |
||
95 | // Filled in by Parser.parseTokens. If an error occurs, points to |
||
96 | // beginning of region where the error occurred (e.g. the open brace |
||
97 | // if the close brace is missing). |
||
98 | |||
99 | public int termIndex; |
||
100 | |||
101 | // This field is set to true by Parser.parseCommand if the command |
||
102 | // appears to be incomplete. This information is used by |
||
103 | // Parser.commandComplete. |
||
104 | |||
105 | internal bool incomplete; |
||
106 | |||
107 | // When a TclParse is the return value of a method, result is set to |
||
108 | // a standard Tcl result, indicating the return of the method. |
||
109 | public TCL.CompletionCode result; |
||
110 | |||
111 | // Default size of the tokenList array. |
||
112 | |||
113 | private const int INITIAL_NUM_TOKENS = 20; |
||
114 | private const int MAX_CACHED_TOKENS = 50; //my tests show 50 is best |
||
115 | |||
116 | internal TclParse( Interp interp, char[] inString, int endIndex, string fileName, int lineNum ) |
||
117 | { |
||
118 | this.interp = interp; |
||
119 | this.inString = inString; |
||
120 | this.endIndex = endIndex; |
||
121 | this.fileName = fileName; |
||
122 | this.lineNum = lineNum; |
||
123 | this.tokenList = new TclToken[INITIAL_NUM_TOKENS]; |
||
124 | this.tokensAvailable = INITIAL_NUM_TOKENS; |
||
125 | this.numTokens = 0; |
||
126 | this.numWords = 0; |
||
127 | this.commentStart = -1; |
||
128 | this.commentSize = 0; |
||
129 | this.commandStart = -1; |
||
130 | this.commandSize = 0; |
||
131 | this.incomplete = false; |
||
132 | } |
||
133 | internal TclToken getToken( int index ) |
||
134 | // The index into tokenList. |
||
135 | { |
||
136 | if ( index >= tokensAvailable ) |
||
137 | { |
||
138 | expandTokenArray( index ); |
||
139 | } |
||
140 | |||
141 | if ( tokenList[index] == null ) |
||
142 | { |
||
143 | tokenList[index] = grabToken(); |
||
144 | tokenList[index].script_array = tokenList[0].script_array; |
||
145 | } |
||
146 | return tokenList[index]; |
||
147 | } |
||
148 | |||
149 | |||
150 | // Release internal resources that this TclParser object might have allocated |
||
151 | |||
152 | internal void release() |
||
153 | { |
||
154 | for ( int index = 0; index < tokensAvailable; index++ ) |
||
155 | { |
||
156 | if ( tokenList[index] != null ) |
||
157 | { |
||
158 | releaseToken( tokenList[index] ); |
||
159 | tokenList[index] = null; |
||
160 | } |
||
161 | } |
||
162 | } |
||
163 | |||
164 | |||
165 | |||
166 | |||
167 | // Creating an interpreter will cause this init method to be called |
||
168 | |||
169 | internal static void init( Interp interp ) |
||
170 | { |
||
171 | TclToken[] TOKEN_CACHE = new TclToken[MAX_CACHED_TOKENS]; |
||
172 | for ( int i = 0; i < MAX_CACHED_TOKENS; i++ ) |
||
173 | { |
||
174 | TOKEN_CACHE[i] = new TclToken(); |
||
175 | } |
||
176 | |||
177 | interp.parserTokens = TOKEN_CACHE; |
||
178 | interp.parserTokensUsed = 0; |
||
179 | } |
||
180 | |||
181 | |||
182 | private TclToken grabToken() |
||
183 | { |
||
184 | if ( interp == null || interp.parserTokensUsed == MAX_CACHED_TOKENS ) |
||
185 | { |
||
186 | // either we do not have a cache because the interp is null or we have already |
||
187 | // used up all the open cache slots, we just allocate a new one in this case |
||
188 | return new TclToken(); |
||
189 | } |
||
190 | else |
||
191 | { |
||
192 | // the cache has an avaliable slot so grab it |
||
193 | return interp.parserTokens[interp.parserTokensUsed++]; |
||
194 | } |
||
195 | } |
||
196 | |||
197 | private void releaseToken( TclToken token ) |
||
198 | { |
||
199 | if ( interp != null && interp.parserTokensUsed > 0 ) |
||
200 | { |
||
201 | // if cache is not full put the object back in the cache |
||
202 | interp.parserTokensUsed -= 1; |
||
203 | interp.parserTokens[interp.parserTokensUsed] = token; |
||
204 | } |
||
205 | } |
||
206 | |||
207 | |||
208 | /* |
||
209 | //uncommenting these methods will disable caching |
||
210 | |||
211 | static void init(Interp interp) {} |
||
212 | private TclToken grabToken() {return new TclToken();} |
||
213 | private void releaseToken(TclToken token) {} |
||
214 | */ |
||
215 | |||
216 | |||
217 | |||
218 | internal void expandTokenArray( int needed ) |
||
219 | { |
||
220 | // Make sure there is at least enough room for needed tokens |
||
221 | while ( needed >= tokensAvailable ) |
||
222 | { |
||
223 | tokensAvailable *= 2; |
||
224 | } |
||
225 | |||
226 | TclToken[] newList = new TclToken[tokensAvailable]; |
||
227 | Array.Copy( (System.Array)tokenList, 0, (System.Array)newList, 0, tokenList.Length ); |
||
228 | tokenList = newList; |
||
229 | } |
||
230 | |||
231 | public override string ToString() |
||
232 | { |
||
233 | |||
234 | return ( get().ToString() ); |
||
235 | } |
||
236 | |||
237 | public TclObject get() |
||
238 | { |
||
239 | TclObject obj; |
||
240 | TclToken token; |
||
241 | string typeString; |
||
242 | int nextIndex; |
||
243 | string cmd; |
||
244 | int i; |
||
245 | |||
246 | |||
247 | System.Diagnostics.Debug.WriteLine( "Entered TclParse.get()" ); |
||
248 | System.Diagnostics.Debug.WriteLine( "numTokens is " + numTokens ); |
||
249 | |||
250 | obj = TclList.newInstance(); |
||
251 | try |
||
252 | { |
||
253 | if ( commentSize > 0 ) |
||
254 | { |
||
255 | TclList.append( interp, obj, TclString.newInstance( new string( inString, commentStart, commentSize ) ) ); |
||
256 | } |
||
257 | else |
||
258 | { |
||
259 | TclList.append( interp, obj, TclString.newInstance( "-" ) ); |
||
260 | } |
||
261 | |||
262 | if ( commandStart >= ( endIndex + 1 ) ) |
||
263 | { |
||
264 | commandStart = endIndex; |
||
265 | } |
||
266 | cmd = new string( inString, commandStart, commandSize ); |
||
267 | TclList.append( interp, obj, TclString.newInstance( cmd ) ); |
||
268 | TclList.append( interp, obj, TclInteger.newInstance( numWords ) ); |
||
269 | |||
270 | for ( i = 0; i < numTokens; i++ ) |
||
271 | { |
||
272 | System.Diagnostics.Debug.WriteLine( "processing token " + i ); |
||
273 | |||
274 | token = tokenList[i]; |
||
275 | switch ( token.type ) |
||
276 | { |
||
277 | |||
278 | case Parser.TCL_TOKEN_WORD: |
||
279 | typeString = "word"; |
||
280 | break; |
||
281 | |||
282 | case Parser.TCL_TOKEN_SIMPLE_WORD: |
||
283 | typeString = "simple"; |
||
284 | break; |
||
285 | |||
286 | case Parser.TCL_TOKEN_EXPAND_WORD: |
||
287 | typeString = "expand"; |
||
288 | break; |
||
289 | |||
290 | case Parser.TCL_TOKEN_TEXT: |
||
291 | typeString = "text"; |
||
292 | break; |
||
293 | |||
294 | case Parser.TCL_TOKEN_BS: |
||
295 | typeString = "backslash"; |
||
296 | break; |
||
297 | |||
298 | case Parser.TCL_TOKEN_COMMAND: |
||
299 | typeString = "command"; |
||
300 | break; |
||
301 | |||
302 | case Parser.TCL_TOKEN_VARIABLE: |
||
303 | typeString = "variable"; |
||
304 | break; |
||
305 | |||
306 | default: |
||
307 | typeString = "??"; |
||
308 | break; |
||
309 | |||
310 | } |
||
311 | |||
312 | System.Diagnostics.Debug.WriteLine( "typeString is " + typeString ); |
||
313 | |||
314 | TclList.append( interp, obj, TclString.newInstance( typeString ) ); |
||
315 | TclList.append( interp, obj, TclString.newInstance( token.TokenString ) ); |
||
316 | TclList.append( interp, obj, TclInteger.newInstance( token.numComponents ) ); |
||
317 | } |
||
318 | nextIndex = commandStart + commandSize; |
||
319 | TclList.append( interp, obj, TclString.newInstance( new string( inString, nextIndex, ( endIndex - nextIndex ) ) ) ); |
||
320 | } |
||
321 | catch ( TclException e ) |
||
322 | { |
||
323 | // Do Nothing. |
||
324 | } |
||
325 | |||
326 | return obj; |
||
327 | } |
||
328 | } // end TclParse |
||
329 | } |