comparison src/parse.s-saved @ 138:4983ba49f936

Make backup of parse.s in preparation for a complete refactor
author William Astle <lost@l-w.ca>
date Sat, 13 Jul 2024 17:33:01 -0600
parents src/parse.s@917b4893bb3d
children
comparison
equal deleted inserted replaced
137:18940aa42dcf 138:4983ba49f936
1 *pragmapush list
2 *pragma list
3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ; This is the overall parsing package. This is responsible for converting program text into the internal byte code and
5 ; reporting any syntax errors and anything else reasonably detectable at parse time without having overly complicated
6 ; code analysis. In almost all cases, the returned error will be a syntax error. The internal byte code shares the same
7 ; token number allocations as the parser. Some allocated tokens cannot be identified by the lexer (parse_nexttok) but
8 ; are used at runtime and when "decompiling" to text.
9 ;
10 ; In the event of a parse error, everything up to the next end of statement is retained as is using a special token
11 ; that preserves the unparsable text and parsing resumes. Only the first error is referenced by the return error
12 ; pointer.
13 ;
14 ; This is a recursive descent parser.
15 ;
16 ; Entry:
17 ; X Points to the text to encode
18 ; B Nonzero to prevent generating any output (error check/length calculation only)
19 ;
20 ; Exit:
21 ; X Points to the encoded line
22 ; D Length of the encoded line
23 ; CC.C clear
24
25 ; Error Exit:
26 ; X Points to the encoded line
27 ; D Length of the encoded line
28 ; Y Pointer to the first error location in the input
29 ; U Error code
30 ; CC.C set
31 ;
32 ; This is the error handler. It is responsible for resetting the stack to bail out to the top level
33 ; parsing loop. It must also store the input pointer if this is the first error. Finally, it has to
34 ; output all the text up to either the end of the line *or* the next valid statement separator.
35 parse_errorsn ldb #err_sn
36 parse_error lds parse_stackptr ; restore the original stack pointer so we can call from down stack
37 puls u ; get back original free pointer
38 stu freestart ; deallocate any allocated result
39 ldu parse_tokenst ; get start location of the token where the error was raised
40 coma ; make sure C is set for error
41 rts
42 parse stb parse_noout ; save no-output flag
43 leay ,x ; save input pointer in a less useful register
44 ldu freestart ; point to start of free memory where we will build the output
45 pshs u ; save original free memory location
46 sts parse_stackptr ; save the stack pointer for bailing out on errors
47 parse_nextstmt jsr parse_nexttok ; fetch the next token, return type in D
48 bcs parse_error ; brif we failed at parsing a token
49 parse0 ldx #parsetab_cmd ; point to jump table for token type handler
50 cmpb #token_stmtsep ; is it a statement separator?
51 beq parse_nextstmt ; brif so - we can just skip it
52 parse1 cmpb ,x ; did we match a valid command token?
53 beq parse3 ; brif so
54 leax 3,x ; move to next entry
55 cmpx #parsetab_cmde ; end of table?
56 blo parse1 ; brif not
57 bra parse_errorsn ; fell off the end
58 parse3 jsr [1,x] ; call the handler
59 bcs parse_error ; brif the handler indicated error
60 bsr parse_curtoken ; fetch the token we left off on
61 cmpb #token_eot ; end of input?
62 bne parse4 ; brif not
63 ldb #bc_eol ; stash an end of line op
64 bsr parse_write
65 bcs parse_error ; brif we errored out writing to the result (OM?)
66 tfr u,d ; calculate the length of the result
67 subd ,s
68 puls u,pc ; get pointer to start of encoded result and return (C is already clear)
69 parse4 cmpb #token_stmtsep ; statement separator?
70 beq parse_nextstmt ; brif so - do another statement
71 cmpb #token_remabbr ; ' token?
72 beq parse0 ; brif so - parse it as a new statement
73 bra parse_errorsn ; raise a syntax error
74 parse_write lda parse_noout ; are we doing output?
75 beq parse_write0 ; brif so
76 leau 1,u ; just count up the output and don't do anything
77 rts
78 parse_write0 leax -stackheadroom,s ; calculate bottom of stack with headroom
79 cmpx freestart ; did the stack run into the end of the output?
80 bhs parse_write1 ; brif not - we're good
81 ldb #err_om ; raise out of memory error, C already set from comparison
82 rts
83 parse_write1 stb ,u+ ; save output byte
84 stu freestart ; save new to of used memory
85 list_noop
86 parse_noop rts ; return all clear - C clear from comparison above
87 parse_curtoken ldb parse_curtok ; fetch token code of current token
88 rts
89 parse_tokerr comb ; flag error - unexpected token
90 ldb #err_sn ; raise syntax error
91 rts
92 parse_nextchar lda ,y ; at end of input already?
93 beq parse_curchar ; brif so
94 leay 1,y ; move to next input character
95 parse_curchar lda ,y ; fetch input character
96 rts
97 parse_nexttokc bsr parse_nexttok ; fetch next token
98 parse_iseos cmpb #token_eot ; end of text?
99 beq parse_iseos0 ; brif so
100 cmpb #token_stmtsep ; is it a statement separator
101 parse_iseos0 rts
102 parse_nexttok bsr parse_curchar ; fetch current input
103 beq parse_nexttok1 ; brif end of input
104 parse_nexttok0 cmpa #0x20 ; space?
105 bne parse_nexttok2 ; brif not
106 bsr parse_nextchar ; eat the space
107 bne parse_nexttok0 ; brif not end of input
108 parse_nexttok1 ldb #token_eot ; flag end of input
109 bra parse_nexttok6 ; go return it
110 parse_nexttok2 sty parse_tokenst ; save start of current token after skipping spaces
111 bsr parse_toupper ; make sure we have upper case letters for matching
112 ldx #parse_wt ; point to keyword parsing table
113 jsr parse_wordtab ; go see if we have a match in the keyword table
114 bcc parse_nexttok6 ; brif we do - return it
115 ldy parse_tokenst ; return to the start of the token - pointer probably clobbered
116 bsr parse_curchar ; get back input character (may have been clobbered)
117 cmpa #'. ; leading decimal?
118 beq parse_nexttok3 ; brif so - parse number
119 cmpa #'0 ; is it a digit
120 blo parse_nexttok10 ; brif not
121 cmpa #'9 ; is it still a digit?
122 bhi parse_nexttok10 ; brif not
123 parse_nexttok3 jmp parse_number ; go parse a number
124 parse_nexttok6 stb parse_curtok ; save token type
125 leay 1,y ; eat the input character
126 clra ; clear C to indicate no error (and clear Z also)
127 rts
128 parse_nexttok10 cmpa #'A ; is it alpha?
129 blo parse_nexttok11 ; brif not
130 cmpa #'Z ; is it still alpha?
131 bls parse_nexttok12 ; brif so
132 parse_nexttok11 comb ; flag error - unrecognized token
133 ldb #token_error
134 rts
135 parse_nexttok12 bsr parse_nextcharu ; fetch next input character
136 cmpa #'0 ; is it alphanumeric?
137 blo parse_nexttok13 ; brif not
138 cmpa #'9 ; is it numeric?
139 bls parse_nexttok12 ; brif so - keep skipping it
140 cmpa #'A ; is it alpha?
141 blo parse_nexttok13 ; brif not
142 cmpa #'Z ; is it still alpha?
143 bls parse_nexttok12 ; brif so - keep skipping it
144 parse_nexttok13 tfr y,d ; calculate length of identifier
145 subd parse_tokenst
146 std val0+val.strlen ; save it for reference
147 ldb #token_ident ; indicate an identifier (variable name, etc.)
148 rts ; return result (C will be clear from SUBD above)
149 parse_nextcharu bsr parse_nextchar ; fetch next input character
150 beq parse_toupper0 ; brif end of input
151 parse_toupper cmpa #'a ; is it lower case alpha?
152 blo parse_toupper0 ; brif not
153 cmpa #'z ; is it still lower case alpha?
154 bhi parse_toupper0 ; brif not
155 suba #0x20 ; adjust to upper case alpha
156 parse_toupper0 rts ; Z only set here if input was zero entering from parse_nextcharu
157 parse_number jmp parse_tokerr
158 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
159 ; Parse a statement that consists of just the command token
160 parse_cmdsingle equ parse_write ; just write the token out and bail
161 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
162 ; Parse a REM or ' statement. We just copy the comment out after the REM or ' token.
163 parse_rem jsr parse_write ; write the token/character out
164 ldb ,y+ ; get next input character
165 bne parse_rem ; brif not at the end of the input
166 ldb #token_eot ; flag end of input for mainline parser
167 stb parse_curtok
168 rts ; return, pass back the C result from parse_write
169 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
170 ; This routine parses tokens using the table at parse_wordtab. The table is structured as follows:
171 ;
172 ; * two bytes which contain the length of the table less the two bytes for this length value
173 ; * a sequence of entries consisting of a single byte matching character and a token code followed
174 ; by an optional sub table, structured exactly the same way.
175 ;
176 ; The optional subtable will be present if the token code is token_eot
177 ;
178 ; If the character match is negative, it means a lookahead failed. The negative value is the number
179 ; of characters to unget and the token code is the token value to return. No other entries after this
180 ; in a table will be considered since thie negative match is a global match.
181 ;
182 ; When a token_eot match is found, if there are no further characters in the input, the match is
183 ; determined to be invalid and processing continues with the next entry.
184 parse_wordtab0 leas 3,s ; clean up stack for sub table handling
185 parse_wordtab pshs a,x ; save input character and start of table
186 ldd ,x++ ; get length of this table
187 addd 1,s ; calculate the address of the end of the table
188 std 1,s ; save end address for comparison later
189 lda ,s ; get back input character
190 parse_wordtab1 ldb 1,x ; fetch token code for this entry
191 cmpa ,x++ ; does this entry match?
192 bne parse_wordtab4 ; brif not
193 cmpb #token_eot ; is it indicating a sub table?
194 bne parse_wordtab6 ; brif not
195 jsr parse_nextcharu ; fetch next input character (for sub table match)
196 bne parse_wordtab0 ; brif we are going to check the sub table
197 parse_wordtab2 ldd ,x ; fetch length of sub table
198 leax d,x ; move past sub table
199 parse_wordtab3 lda ,s ; get back input character
200 cmpx 1,s ; are we at the end of the table?
201 blo parse_wordtab1 ; brif not - check another entry
202 comb ; indicate no match
203 puls a,x,pc ; clean up stack and return
204 parse_wordtab4 lda -2,x ; get the match character
205 bmi parse_wordtab5 ; brif negative - lookahead fail
206 cmpb #token_eot ; is there a sub table to skip?
207 beq parse_wordtab2 ; brif so - skip sub table
208 bra parse_wordtab3 ; otherwise just move to the next entry
209 parse_wordtab5 leay a,y ; move back the specified number of characters
210 parse_wordtab6 clra ; clear C to indicate a match
211 puls a,x,pc ; clean up stack and return
212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213 ; Convert a token number back to its keyword. This will use the same table used by parse_wordtab. Enter with a character
214 ; output routine pointer in U which takes the character in A. The routine can assume that Y is preserved. Will return
215 ; with C set if the token does not exist in the word table and clear otherwise.
216 parse_wtdc pshs u ; save routine pointer
217 ldu #strbuff+20 ; point to temporary string buffer
218 clr ,-u ; put a NUL at the end of the string
219 ldx #parse_wt ; point to keyword parse table
220 bsr parse_wtdc2 ; call the tree walker function
221 bcc parse_wtdc1 ; brif we do have a match
222 puls u,pc ; clean stack and return
223 parse_wtdc0 jsr [,s] ; output the character
224 parse_wtdc1 lda ,u+ ; get output byte
225 bne parse_wtdc0 ; brif we're not at the end yet
226 clra ; make sure C is clear
227 puls u,pc ; clean stack and return
228 parse_wtdc2 pshs a,x ; save the token match value and the table pointer
229 ldd ,x++ ; get table length
230 addd 1,s ; calculate end address
231 std 1,s ; save it
232 parse_wtdc3 ldd ,x++ ; get this table entry
233 bmi parse_wtdc6 ; brif it's a backtracking entry - skip it
234 cmpa ,s ; does the token match here?
235 bne parse_wtdc5 ; brif not
236 parse_wtdc4 sta ,-y ; add the character to the output buffer
237 puls a,x,pc ; return up the call stack - C is clear from CMPA above
238 parse_wtdc5 cmpb #token_eot ; does this entry have a sub table?
239 bne parse_wtdc6 ; brif not
240 pshs a ; save the matched character
241 lda 1,s ; get back the token we need
242 bsr parse_wtdc2 ; go handle the sub table
243 puls a ; get back the matched character
244 bcc parse_wtdc4 ; brif it did match - record it and return
245 parse_wtdc6 cmpx 1,s ; are we at the end of this table?
246 bne parse_wtdc3 ; brif not - handle another table entry
247 coma ; make sure C is set for no match
248 puls a,x,pc ; clean up stack and return
249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
250 ; Validate a line number. Must enter with the token type in B. Will return the line number in X. It will return a
251 ; syntax error if the line number is invalid or out of range. It will also consume a valid line number token.
252 parse_linenum cmpb #token_int32 ; is it an integer?
253 beq parse_linenum1 ; brif so
254 parse_linenum0 ldb #err_sn ; flag syntax error
255 coma ; flag error
256 rts
257 parse_linenum1 ldx val0+val.int ; get high word of integer
258 bne parse_linenum0 ; brif not a valid line number
259 ldx val0+val.int+2 ; get actual line number
260 pshs x ; save it
261 jsr parse_nexttok ; consume line number
262 puls x,pc ; get back line number and return it
263 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
264 ; Parse a line number range which is one of the following forms:
265 ; <linenum1>
266 ; <linenum1>-
267 ; <linenum1>-<linenum2>
268 ; -<linenum2>
269 ; The result will store two line numbers. If no - token appears, then both line numbers will be the same. Otherwise,
270 ; if <linenum1> is omitted, it will be assumed to be 0. If <linenum2> is omitted, it will be assumed to be 65535. Those
271 ; are the minimum and maximum line numbers.
272 ;
273 ; Parsing works by first looking for an integer token that is in range. If it finds one, it looks for an optional -
274 ; followed by an optional integer token that is in range. If the first token is not an integer, it must be a - which may
275 ; be optionally followed by another integer in range.
276 ;
277 ; It is technically valid to have a single - with no line numbers.
278 ;
279 ; Enter with the current token in B.
280 ;
281 ; The resulting line numbers will be returned in parse_buff
282 parse_linerange ldx zero ; default start line number
283 leau -1,x ; default end line number
284 pshs x,u ; save the return range
285 cmpb #token_minus ; range with no start?
286 beq parse_linerang1 ; brif so
287 bsr parse_linenum ; verify line number, return in X
288 bcs parse_linerang4 ; bail out on error
289 stx ,s ; save new start line number
290 jsr parse_nexttokc ; fetch next token, set Z if end of statement
291 bne parse_linerang0 ; brif not end of line
292 ldx ,s ; get end line to use as start line
293 bra parse_linerang2 ; go set range end and return
294 parse_linerang0 cmpb #token_minus ; do we have a range character?
295 bne parse_linerang3 ; brif not - we have an error
296 parse_linerang1 jsr parse_nexttokc ; parse what comes after the range mark
297 beq parse_linerang2 ; brif end of statement - use the default range end
298 bsr parse_linenum ; make sure it's a valid line number
299 bcs parse_linerang4 ; bail out on error
300 parse_linerang2 stx 2,s ; set range end
301 clra ; make sure C is clear
302 puls x,u,pc ; fetch return values and return
303 parse_linerang3 ldb #err_sn ; flag a syntax error
304 coma ; make sure C is set
305 parse_linerang4 puls x,u,pc ; clean up stack and return error condition
306 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
307 ; This table defines the various handler routines for the various bytecode tokens. Each token is defined as follows:
308 ; parse_tokdefT <sym>,<parse>,<list>,<exec>
309 ; where:
310 ; T: c for command, f for function, p for particle
311 ; <sym>: the symbol name without the "token_" prefix
312 ; <parse>: parse handler for the type, ignored for particles
313 ; <list>: list handler for the type, ingored for particles
314 ; <exec>: execution handler for the type, ignored for particles
315 *pragmapush list
316 *pragma nolist
317 __toknump set 0
318 __toknumc set 0x40
319 __toknumf set 0xc0
320 setstr __cmdparset=""
321 setstr __cmdlistt=""
322 setstr __cmdexect=""
323 setstr __fnparset=""
324 setstr __fnlistt=""
325 setstr __fnexect=""
326 parse_tokendefp macro noexpand
327 token_\1 equ __toknump
328 __toknump set __toknump+1
329 endm
330 parse_tokendefc macro noexpand
331 token_\1 equ __toknumc
332 __toknumc set __toknumc+1
333 ifstr ne,"{2}",""
334 setstr __cmdparset="%(__cmdparset)\tfcb\ttoken_\1\n\tfdb {2}\n"
335 endc
336 ifstr ne,"{3}",""
337 setstr __cmdlistt="%(__cmdlistt)\tfcb\ttoken_\1\n\tfdb {3}\n"
338 endc
339 ifstr ne,"{4}",""
340 setstr __cmdexect="%(__cmdexect)\tfdb {3}\n"
341 else
342 setstr __cmdexect="%(__cmdexect)\tfdb SNERROR\n"
343 endc
344 endm
345 parse_tokendeff macro noexpand
346 token_\1 equ __toknumf
347 __toknumf set __toknumf+1
348 ifstr ne,"{2}",""
349 setstr __fnparset="%(__fnparset)\tfcb\ttoken_\1\n\tfdb {2}\n"
350 endc
351 ifstr ne,"{3}",""
352 setstr __fnlistt="%(__fnlistt)\tfcb\ttoken_\1\n\tfdb {3}\n"
353 endc
354 ifstr ne,"{4}",""
355 setstr __fnexect="%(__fnexect)\tfdb {3}\n"
356 else
357 setstr __fnexect="%(__fnexect)\tfdb SNERROR\n"
358 endc
359 endm
360 token_cmdparse macro
361 *pragmapush nolist
362 *pragma nolist
363 includestr "%(__cmdparset)"
364 *pragmapop nolist
365 endm
366 token_cmdlist macro
367 *pragmapush nolist
368 *pragma nolist
369 includestr "%(__cmdlistt)"
370 *pragmapop nolist
371 endm
372 token_cmdexec macro
373 *pragmapush nolist
374 *pragma nolist
375 includestr "%(__cmdexect)"
376 token__maxcmd equ __toknumc-1
377 *pragmapop nolist
378 endm
379 token_fnparse macro
380 *pragmapush nolist
381 *pragma nolist
382 includestr "%(__fnparset)"
383 *pragmapop nolist
384 endm
385 token_fnlist macro
386 *pragmapush nolist
387 *pragma nolist
388 includestr "%(__fnlistt)"
389 *pragmapop nolist
390 endm
391 token_fnexec macro
392 *pragmapush nolist
393 *pragma nolist
394 includestr "%(__fnexect)"
395 token__maxfn equ __toknumf-1
396 *pragmapop nolist
397 endm
398 *pragmapop list
399 ; the tokens defined in this section all have special parsing or meaning
400 parse_tokendefp error ; Used to mark errors; should always be first so it's token #0
401 parse_tokendefp eot ; End of input marker or special handling in word tables
402 parse_tokendefp int32 ; 32 bit integer (has special parsing)
403 parse_tokendefp float ; floating point value (has special parsing)
404 parse_tokendefp ident ; identifier (has special parsing)
405 parse_tokendefp linenum ; a 16 bit unsigned integer treated as a line number
406 parse_tokendefp linerange ; a pair of 16 bit unsigned integers treated as line numbers
407 ; everything below here references keywords or particle characters
408 parse_tokendefp stmtsep ; statement separator
409 parse_tokendefp times ; times (multiplication) operator (*)
410 parse_tokendefp plus ; addition operator
411 parse_tokendefp divide ; division operator (/)
412 parse_tokendefp minus ; subtraction operator
413 parse_tokendefp exp ; exponentiation operator (^)
414 parse_tokendefp lt ; less than operator
415 parse_tokendefp le ; less than or equal operateor
416 parse_tokendefp gt ; greater than operator
417 parse_tokendefp ge ; greater than or equal operator
418 parse_tokendefp eq ; equality operator
419 parse_tokendefp ne ; inequality operator
420 parse_tokendefp not ; boolean NOT operator
421 parse_tokendefp and ; boolean AND operator
422 parse_tokendefp or ; boolean OR operator
423 parse_tokendefp bang ; exclamation mark
424 parse_tokendefp hash ; number sign
425 parse_tokendefp dollar ; dollar sign (string sigil)
426 parse_tokendefp percent ; percent sign (integer sigil)
427 parse_tokendefp amp ; ampersand
428 parse_tokendefp oparen ; opening paren
429 parse_tokendefp cparen ; closing paren
430 parse_tokendefp sep ; comma (separator)
431 parse_tokendefp semi ; semicolon
432 parse_tokendefp at ; @ symbol
433 parse_tokendefp else ; ELSE
434 parse_tokendefp then ; THEN
435 parse_tokendefp to ; TO
436 parse_tokendefp sub ; SUB
437 parse_tokendefp as ; AS
438
439 parse_tokendefc remabbr,parse_rem,list_noop,exec_noop ; abbreviated REM (')
440 parse_tokendefc rem,parse_rem,list_noop,exec_noop ; REM
441 parse_tokendefc return,parse_cmdsingle,parse_noop,parse_noop ; RETURN
442 parse_tokendefc run,parse_noop,parse_noop,parse_noop ; RUN
443 parse_tokendefc data,parse_noop,parse_noop,parse_noop ; DATA
444 parse_tokendefc end,parse_cmdsingle,parse_noop,parse_noop ; END
445 parse_tokendefc stop,parse_cmdsingle,parse_noop,parse_noop ; STOP
446 parse_tokendefc let,parse_noop,parse_noop,parse_noop ; LET
447 parse_tokendefc list,parse_noop,parse_noop,parse_noop ; LIST
448 parse_tokendefc new,parse_cmdsingle,parse_noop,parse_noop ; NEW
449 parse_tokendefc print,parse_noop,parse_noop,parse_noop ; PRINT
450 parse_tokendefc pop,parse_cmdsingle,parse_noop,parse_noop ; POP
451 parse_tokendefc goto,parse_noop,parse_noop,parse_noop ; GOTO
452 parse_tokendefc gosub,parse_noop,parse_noop,parse_noop ; GOSUB
453 parse_tokendefc go,parse_noop,parse_noop,parse_noop ; GO
454
455 parse_tokendeff asc,parse_noop,parse_noop,parse_noop ; ASC()
456 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
457 ; Parse handling tables
458 parsetab_cmd token_cmdparse
459 parsetab_cmde
460 parsetab_fn token_fnparse
461 parsetab_fne
462 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
463 ; List handling tables
464 listtab_cmd token_cmdlist
465 listtab_cmde
466 listtab_fn token_fnlist
467 listtab_fne
468 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
469 ; Execution handling tables
470 exectab_cmd token_cmdexec
471 exectab_fn token_fnexec
472 *pragmapop list