1583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# An implementation of Dartmouth BASIC (1964)
2583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata#
3583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
4583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataimport sys
5583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granatasys.path.insert(0, "../..")
6583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
7583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataif sys.version_info[0] >= 3:
8583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    raw_input = input
9583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
10583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataimport basiclex
11583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataimport basparse
12583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataimport basinterp
13583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
14583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# If a filename has been specified, we try to run it.
15583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# If a runtime error occurs, we bail out and enter
16583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# interactive mode below
17583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataif len(sys.argv) == 2:
18583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    data = open(sys.argv[1]).read()
19583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    prog = basparse.parse(data)
20583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    if not prog:
21583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        raise SystemExit
22583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    b = basinterp.BasicInterpreter(prog)
23583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    try:
24583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        b.run()
25583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        raise SystemExit
26583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    except RuntimeError:
27583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        pass
28583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
29583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granataelse:
30583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    b = basinterp.BasicInterpreter({})
31583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
32583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# Interactive mode.  This incrementally adds/deletes statements
33583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# from the program stored in the BasicInterpreter object.  In
34583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# addition, special commands 'NEW','LIST',and 'RUN' are added.
35583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# Specifying a line number with no code deletes that line from
36583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata# the program.
37583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
38583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granatawhile 1:
39583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    try:
40583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        line = raw_input("[BASIC] ")
41583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    except EOFError:
42583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        raise SystemExit
43583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    if not line:
44583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        continue
45583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    line += "\n"
46583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    prog = basparse.parse(line)
47583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    if not prog:
48583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        continue
49583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata
50583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    keys = list(prog)
51583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    if keys[0] > 0:
52583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        b.add_statements(prog)
53583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata    else:
54583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        stat = prog[keys[0]]
55583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        if stat[0] == 'RUN':
56583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata            try:
57583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata                b.run()
58583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata            except RuntimeError:
59583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata                pass
60583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        elif stat[0] == 'LIST':
61583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata            b.list()
62583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        elif stat[0] == 'BLANK':
63583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata            b.del_line(stat[1])
64583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata        elif stat[0] == 'NEW':
65583d33c593896afeb8486a25fabfcf6e9dc9ca75Enrico Granata            b.new()
66