1*09948d41SKrzysztof KosińskiInspired by a September 14, 2006 Salon article "Why Johnny Can't Code" by 2*09948d41SKrzysztof KosińskiDavid Brin (http://www.salon.com/tech/feature/2006/09/14/basic/index.html), 3*09948d41SKrzysztof KosińskiI thought that a fully working BASIC interpreter might be an interesting, 4*09948d41SKrzysztof Kosińskiif not questionable, PLY example. Uh, okay, so maybe it's just a bad idea, 5*09948d41SKrzysztof Kosińskibut in any case, here it is. 6*09948d41SKrzysztof Kosiński 7*09948d41SKrzysztof KosińskiIn this example, you'll find a rough implementation of 1964 Dartmouth BASIC 8*09948d41SKrzysztof Kosińskias described in the manual at: 9*09948d41SKrzysztof Kosiński 10*09948d41SKrzysztof Kosiński http://www.bitsavers.org/pdf/dartmouth/BASIC_Oct64.pdf 11*09948d41SKrzysztof Kosiński 12*09948d41SKrzysztof KosińskiSee also: 13*09948d41SKrzysztof Kosiński 14*09948d41SKrzysztof Kosiński http://en.wikipedia.org/wiki/Dartmouth_BASIC 15*09948d41SKrzysztof Kosiński 16*09948d41SKrzysztof KosińskiThis dialect is downright primitive---there are no string variables 17*09948d41SKrzysztof Kosińskiand no facilities for interactive input. Moreover, subroutines and functions 18*09948d41SKrzysztof Kosińskiare brain-dead even more than they usually are for BASIC. Of course, 19*09948d41SKrzysztof Kosińskithe GOTO statement is provided. 20*09948d41SKrzysztof Kosiński 21*09948d41SKrzysztof KosińskiNevertheless, there are a few interesting aspects of this example: 22*09948d41SKrzysztof Kosiński 23*09948d41SKrzysztof Kosiński - It illustrates a fully working interpreter including lexing, parsing, 24*09948d41SKrzysztof Kosiński and interpretation of instructions. 25*09948d41SKrzysztof Kosiński 26*09948d41SKrzysztof Kosiński - The parser shows how to catch and report various kinds of parsing 27*09948d41SKrzysztof Kosiński errors in a more graceful way. 28*09948d41SKrzysztof Kosiński 29*09948d41SKrzysztof Kosiński - The example both parses files (supplied on command line) and 30*09948d41SKrzysztof Kosiński interactive input entered line by line. 31*09948d41SKrzysztof Kosiński 32*09948d41SKrzysztof Kosiński - It shows how you might represent parsed information. In this case, 33*09948d41SKrzysztof Kosiński each BASIC statement is encoded into a Python tuple containing the 34*09948d41SKrzysztof Kosiński statement type and parameters. These tuples are then stored in 35*09948d41SKrzysztof Kosiński a dictionary indexed by program line numbers. 36*09948d41SKrzysztof Kosiński 37*09948d41SKrzysztof Kosiński - Even though it's just BASIC, the parser contains more than 80 38*09948d41SKrzysztof Kosiński rules and 150 parsing states. Thus, it's a little more meaty than 39*09948d41SKrzysztof Kosiński the calculator example. 40*09948d41SKrzysztof Kosiński 41*09948d41SKrzysztof KosińskiTo use the example, run it as follows: 42*09948d41SKrzysztof Kosiński 43*09948d41SKrzysztof Kosiński % python basic.py hello.bas 44*09948d41SKrzysztof Kosiński HELLO WORLD 45*09948d41SKrzysztof Kosiński % 46*09948d41SKrzysztof Kosiński 47*09948d41SKrzysztof Kosińskior use it interactively: 48*09948d41SKrzysztof Kosiński 49*09948d41SKrzysztof Kosiński % python basic.py 50*09948d41SKrzysztof Kosiński [BASIC] 10 PRINT "HELLO WORLD" 51*09948d41SKrzysztof Kosiński [BASIC] 20 END 52*09948d41SKrzysztof Kosiński [BASIC] RUN 53*09948d41SKrzysztof Kosiński HELLO WORLD 54*09948d41SKrzysztof Kosiński [BASIC] 55*09948d41SKrzysztof Kosiński 56*09948d41SKrzysztof KosińskiThe following files are defined: 57*09948d41SKrzysztof Kosiński 58*09948d41SKrzysztof Kosiński basic.py - High level script that controls everything 59*09948d41SKrzysztof Kosiński basiclex.py - BASIC tokenizer 60*09948d41SKrzysztof Kosiński basparse.py - BASIC parser 61*09948d41SKrzysztof Kosiński basinterp.py - BASIC interpreter that runs parsed programs. 62*09948d41SKrzysztof Kosiński 63*09948d41SKrzysztof KosińskiIn addition, a number of sample BASIC programs (.bas suffix) are 64*09948d41SKrzysztof Kosińskiprovided. These were taken out of the Dartmouth manual. 65*09948d41SKrzysztof Kosiński 66*09948d41SKrzysztof KosińskiDisclaimer: I haven't spent a ton of time testing this and it's likely that 67*09948d41SKrzysztof KosińskiI've skimped here and there on a few finer details (e.g., strictly enforcing 68*09948d41SKrzysztof Kosińskivariable naming rules). However, the interpreter seems to be able to run 69*09948d41SKrzysztof Kosińskithe examples in the BASIC manual. 70*09948d41SKrzysztof Kosiński 71*09948d41SKrzysztof KosińskiHave fun! 72*09948d41SKrzysztof Kosiński 73*09948d41SKrzysztof Kosiński-Dave 74*09948d41SKrzysztof Kosiński 75*09948d41SKrzysztof Kosiński 76*09948d41SKrzysztof Kosiński 77*09948d41SKrzysztof Kosiński 78*09948d41SKrzysztof Kosiński 79*09948d41SKrzysztof Kosiński 80