git @ Cat's Eye Technologies yucca / 5b8ea69
Really don't analyze computed jumps; fix IF...GOTO parsing. catseye 12 years ago
2 changed file(s) with 37 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
5353 existing line number. This includes any jumps that may occur in immediate
5454 mode commands (i.e. commands with no line number) given in the text
5555 file. If this check fails, further transformations may not be performed on
56 the program. To suppress this check, pass the -L option to `yucca`.
56 the program. To suppress this check, pass the `-L` option to `yucca`.
5757
58 The -o option may be given to dump a copy of the program to the standard
58 `yucca` cannot analyze the validity of any computed line number in a BASIC
59 program which contains computed `GOTO`s or `GOSUB`s. To reduce the chance
60 of an computed line number going unnoticed and unanalyzed, `yucca`'s
61 default behavior is to report an error if it finds any computed `GOTO`s
62 or `GOSUB`s in the input program. To acknowledge that you are aware that
63 the program contains computed jumps that `yucca` will not be able to
64 analyze, pass the `-C` option to have `yucca` suppress these errors.
65
66 The `-o` option may be given to dump a copy of the program to the standard
5967 output. This option is implied by the following two options.
6068
61 The -I option strips all immediate mode commands from the program before
69 The `-I` option strips all immediate mode commands from the program before
6270 analyzing and outputting it.
6371
64 The -R option strips all remarks (REM statements) from the program
72 The `-R` option strips all remarks (`REM` statements) from the program
6573 before analyzing and outputting it. Note that this happens before
66 analysis, so that any jumps to lines which contain only a REM will be
74 analysis, so that any jumps to lines which contain only a `REM` will be
6775 found and reported.
6876
69 The -p option causes all program transformations to act only on program
70 lines, not on immediate mode lines. Thus, in combination with -R, REMs
71 on immediate mode lines are not removed. It does not affect -I at all.
77 The `-p` option causes all program transformations to act only on program
78 lines, not on immediate mode lines. Thus, in combination with `-R`, `REM`s
79 on immediate mode lines are not removed. It does not affect `-I` at all.
7280
73 The -t option runs `yucca` through its internal test suite and exits
81 The `-t` option runs `yucca` through its internal test suite and exits
7482 immediately.
7583
7684 TODO
7785 ----
7886
79 * Show a warning message if the program contains computed jumps.
8087 * Show errors in the order they occur in the program.
8188 * Handle duplicate and deleted lines (line number then nothing.)
8289
8282 match = re.match(r'^(\s*gosub)(.*?)$', text, re.I)
8383 if match:
8484 return Gosub(match.group(1), LineNumber(match.group(2)))
85 match = re.match(r'^(\s*if(.*?)goto)(.*?)$', text, re.I)
86 if match:
87 return IfThenLine(match.group(1), LineNumber(match.group(3)))
8885 # I doubt many BASICs allow a computed goto right after a 'THEN'...
8986 match = re.match(r'^(\s*if(.*?)then)(\s*\d+\s*)$', text, re.I)
9087 if match:
9289 match = re.match(r'^(\s*if(.*?)then)(.*?)$', text, re.I)
9390 if match:
9491 return IfThen(match.group(1), BasicCommand.create(match.group(3)))
92 # We do this check *after* the above two, so as to not accidentally
93 # match something like IF A THEN PRINT "HI":GOTO 50...
94 match = re.match(r'^(\s*if(.*?)goto)(.*?)$', text, re.I)
95 if match:
96 return IfThenLine(match.group(1), LineNumber(match.group(3)))
9597 match = re.match(r'^(\s*on(.*?)go(to|sub))(.*?)$', text, re.I)
9698 if match:
9799 line_numbers = [LineNumber(x) for x in match.group(4).split(',')]
376378 ... '35 GOTO 35.0\n'
377379 ... '40 IFATHENP*40\n'
378380 ... '50 IFAGOTOP*40\n'
381 ... '60 ONAGOTO10,20,70\n'
379382 ... 'GOSUB -10*-1\n')
380383 >>> for e in b.check_computed_jumps(): print e
381384 ?COMPUTED JUMP TO "A * 4" IN: 10 GOTO A * 4
382385 ?COMPUTED JUMP TO "6+7" IN: 20 EARTH:AIR:WATER:FIRE:GOSUB 6+7
383386 ?COMPUTED JUMP TO "35.0" IN: 35 GOTO 35.0
384387 ?COMPUTED JUMP TO "P*40" IN: 50 IFAGOTOP*40
385 ?COMPUTED JUMP TO "-10*-1" IN: GOSUB -10*-1 (immediate mode, text file line 7)
388 ?COMPUTED JUMP TO "-10*-1" IN: GOSUB -10*-1 (immediate mode, text file line 8)
389
390 Computed GOTOs/GOSUBs are not analyzed for validity as jump targets.
391
392 >>> for e in b.check_line_numbers(): print e
393 ?UNDEFINED STATEMENT "70" IN: 60 ONAGOTO10,20,70
394
395 >>> b = BasicProgram('418 IF IR%>=92 THEN ON IR%-91 GOTO 361,311,321,331')
396 >>> print b.lines[0].commands[0].__class__.__name__
397 IfThen
398 >>> len([e for e in b.check_computed_jumps()])
399 0
386400
387401 """
388402 def __init__(self, text=None):
411425 text_file_line += 1
412426 for (location, referenced_line_numbers) in referenced.iteritems():
413427 for referenced_line_number in referenced_line_numbers:
428 if referenced_line_number.is_computed():
429 continue
414430 if referenced_line_number.number not in defined:
415431 errors.append(UndefinedStatement(defined[location],
416432 referenced_line_number))