1 # An implementation of Dartmouth BASIC (1964) 2 # 3 4 import sys 5 sys.path.insert(0, "../..") 6 7 if sys.version_info[0] >= 3: 8 raw_input = input 9 10 import logging 11 logging.basicConfig( 12 level=logging.INFO, 13 filename="parselog.txt", 14 filemode="w" 15 ) 16 log = logging.getLogger() 17 18 import basiclex 19 import basparse 20 import basinterp 21 22 # If a filename has been specified, we try to run it. 23 # If a runtime error occurs, we bail out and enter 24 # interactive mode below 25 if len(sys.argv) == 2: 26 data = open(sys.argv[1]).read() 27 prog = basparse.parse(data, debug=log) 28 if not prog: 29 raise SystemExit 30 b = basinterp.BasicInterpreter(prog) 31 try: 32 b.run() 33 raise SystemExit 34 except RuntimeError: 35 pass 36 37 else: 38 b = basinterp.BasicInterpreter({}) 39 40 # Interactive mode. This incrementally adds/deletes statements 41 # from the program stored in the BasicInterpreter object. In 42 # addition, special commands 'NEW','LIST',and 'RUN' are added. 43 # Specifying a line number with no code deletes that line from 44 # the program. 45 46 while 1: 47 try: 48 line = raw_input("[BASIC] ") 49 except EOFError: 50 raise SystemExit 51 if not line: 52 continue 53 line += "\n" 54 prog = basparse.parse(line, debug=log) 55 if not prog: 56 continue 57 58 keys = list(prog) 59 if keys[0] > 0: 60 b.add_statements(prog) 61 else: 62 stat = prog[keys[0]] 63 if stat[0] == 'RUN': 64 try: 65 b.run() 66 except RuntimeError: 67 pass 68 elif stat[0] == 'LIST': 69 b.list() 70 elif stat[0] == 'BLANK': 71 b.del_line(stat[1]) 72 elif stat[0] == 'NEW': 73 b.new() 74