5 "print ~baZic is a downright scary implementation of ~;"
6 "print ~Basic for the Z-machine. It features proper dynamic ~;"
7 "print ~memory allocation, mark-sweep garbage collection, ~;"
8 "print ~fully tokenised program storage, a built-in program ~;"
9 "print ~editor (cough, cough) and is almost entirely useless. ~;"
10 "print ~It is complete enough to play Hunt the Wumpus on, and ~;"
11 "print ~a copy is provided.~"
13 "print ~The language is not complete. I gave up after a certain ~;"
14 "print ~point when I realised that Basic is so crappy a language ~;"
15 "print ~that it's not fun to implement, just annoying. I am now ~;"
16 "print ~even more impressed with the authors of things like 8kB ~;"
17 "print ~Microsoft Basic and BBC Basic; impressive work.~"
19 "print ~The main lacks to baZic are string operations, proper arrays, and ~;"
20 "print ~subroutines. The bulk of the string code is in there --- the ~;"
21 "print ~scary garbage collector --- but I haven't done the string ~;"
22 "print ~operators themselves. Arrays are sort of implemented, but they're ~;"
23 "print ~done by munging the variable name with the index. (See the Wumpus ~;"
24 "print ~program for an example.) Subroutines just haven't been done.~"
26 "print ~If you're interested in the innards of the program, you can do ~;"
27 "print ~'list -1' to list the stored Basic program with byte-code, or ~;"
28 "print ~'list -2' to view the variables in memory. If you do this while ~;"
29 "print ~an array is in use, odd things will happen.~"
31 "print ~baZic is licensed under the MIT public license. For more information, contact ~;"
32 "print ~dg@@64cowlark.com.~"
36 array higherlower_script -->
39 "10print ~Higher, Lower~"
43 "40input ~What is your guess? ~; guess"
44 "50guess = val(guess)"
45 "60if guess < target then print ~Too low!~"
46 "70if guess > target then print ~Too high!~"
47 "80if guess = target then goto 110"
50 "110print ~You got it!~"
51 "120print ~In only~, tries, ~tries, too.~"
54 array wumpus_script -->
58 "20print ~Hunt the Wumpus --- loading data~"
59 "30cave1(0)=1:cave2(0)=4:cave3(0)=7"
60 "40cave1(1)=0:cave2(1)=2:cave3(1)=9"
61 "50cave1(2)=1:cave2(2)=3:cave3(2)=11"
62 "60cave1(3)=2:cave2(3)=4:cave3(3)=13"
63 "70cave1(4)=0:cave2(4)=3:cave3(4)=5"
64 "80cave1(5)=4:cave2(5)=6:cave3(5)=14"
65 "90cave1(6)=5:cave2(6)=7:cave3(6)=16"
66 "100cave1(7)=0:cave2(7)=6:cave3(7)=8"
67 "110cave1(8)=7:cave2(8)=9:cave3(8)=17"
68 "120cave1(9)=1:cave2(9)=8:cave3(9)=10"
69 "130cave1(10)=9:cave2(10)=11:cave3(10)=18"
70 "140cave1(11)=2:cave2(11)=10:cave3(11)=12"
71 "150cave1(12)=11:cave2(12)=13:cave3(12)=19"
72 "160cave1(13)=3:cave2(13)=12:cave3(13)=14"
73 "170cave1(14)=5:cave2(14)=13:cave3(14)=15"
74 "180cave1(15)=14:cave2(15)=16:cave3(15)=19"
75 "190cave1(16)=6:cave2(16)=15:cave3(16)=17"
76 "200cave1(17)=8:cave2(17)=16:cave3(17)=18"
77 "210cave1(18)=10:cave2(18)=17:cave3(18)=19"
78 "220cave1(19)=12:cave2(19)=15:cave3(19)=18"
79 "225print:input ~Do you want instructions? (y/n) ~; i$"
80 "226if i$ <> ~y~ then goto 1000"
82 "240print ~Welcome to HUNT THE WUMPUS!~"
83 "250print:print ~The wumpus lives in a cave of twenty rooms. ~;"
84 "260print ~Each room has three tunnels leading to other rooms. ~;"
85 "270print ~Two rooms have bottomless pits --- don't fall on. ~;"
86 "280print ~Two more contain Alien Space Bats. Disturb them, ~;"
87 "290print ~and they will whisk you away to some other room. ~;"
88 "300print:print:print ~Naturally, the wumpus is immune to all hazards. ~;"
89 "310print ~Usually, he's asleep: he'll wake up if he hears you ~;"
90 "320print ~shooting an arrow, or if you walk in on him. ~;"
91 "330print ~Once awake, he'll move around most turns (1 in 4 ~;"
92 "340print ~probability). If *he* walks in on *you*, he'll eat yer. ~;"
93 "350print:print:print ~Your only defence is your arrows. These arrows, ~;"
94 "360print ~which contain a Z-machine microcontroller, can be ~;"
95 "370print ~programmed to follow a certain course for up to five ~;"
96 "380print ~rooms. If they can't go where you told them, they'll ~;"
97 "390print ~move randomly. Did I mention they'll kill you, too, ~;"
98 "400print ~if you program them incorrectly? ~;"
99 "410print:print:print ~The wumpus has smelly feet; you can smell him in the ~;"
100 "420print ~next room. The bats rustle, you can hear them; the pits are ~;"
101 "430print ~drafty, and you can feel that.~"
102 "1000print:print ~Placing objects in maze...~"
103 "1010wumpus=rnd(20):player=rnd(20):pit1=rnd(20):pit2=rnd(20)"
104 "1020bat1=rnd(20):bat2=rnd(20)"
105 "1030if wumpus = player then goto 1000"
106 "1040if wumpus = pit1 then goto 1000"
107 "1050if wumpus = pit2 then goto 1000"
108 "1060if wumpus = bat1 then goto 1000"
109 "1070if wumpus = bat2 then goto 1000"
110 "1080if player = pit1 then goto 1000"
111 "1090if player = pit2 then goto 1000"
112 "1100if player = bat1 then goto 1000"
113 "1110if player = bat2 then goto 1000"
114 "1120if pit1 = pit2 then goto 1000"
115 "1130if pit1 = bat1 then goto 1000"
116 "1140if pit1 = bat2 then goto 1000"
117 "1150if pit2 = bat1 then goto 1000"
118 "1160if pit2 = bat2 then goto 1000"
119 "1170if bat1 = bat2 then goto 1000"
122 "2010print ~You are in room number ~; player; ~. Exits lead off to rooms ~;"
123 "2020print cave1(player); ~, ~; cave2(player); ~ and ~; cave3(player); ~. ~"
124 "2030if cave1(player) = wumpus then goto 2070"
125 "2040if cave2(player) = wumpus then goto 2070"
126 "2050if cave3(player) = wumpus then goto 2070"
128 "2070print ~You can smell the wumpus!~"
129 "2080if (cave1(player) = pit1) or (cave1(player) = pit2) then goto 2120"
130 "2090if (cave2(player) = pit1) or (cave2(player) = pit2) then goto 2120"
131 "2100if (cave3(player) = pit1) or (cave3(player) = pit2) then goto 2120"
133 "2120print ~You feel a draught!~"
134 "2121if (cave1(player) = bat1) or (cave1(player) = bat2) then goto 2125"
135 "2122if (cave2(player) = bat1) or (cave2(player) = bat2) then goto 2125"
136 "2123if (cave3(player) = bat1) or (cave3(player) = bat2) then goto 2125"
138 "2125print ~You hear rustling!~"
139 "2130input ~Which room do you want to go to (or -1 to fire an arrow)? ~; i$"
141 "2140if dest = -1 then goto 3000"
142 "2150if (cave1(player) = dest) or (cave2(player) = dest) or (cave3(player) = dest) then goto 2200"
143 "2160print:print ~You can't go that way.~"
146 "2210if dest=wumpus then goto 2600"
147 "2220if (dest=pit1) or (dest=pit2) then print ~*** AAAAAAaaaaaah ***~:print:print ~You have fallen down a pit.~:goto 5000"
148 "2230if (dest=bat1) or (dest=bat2) then print ~You have been abducted by alien space bats.~:dest=rnd(20)"
150 "2500if awake=0 then goto 2000"
152 "2520if i<>0 then goto 2000"
153 "2530print ~You hear the patter of tiny feet as the wumpus moves.~"
155 "2550if i=0 then wumpus = cave1(wumpus)"
156 "2560if i=1 then wumpus = cave2(wumpus)"
157 "2570if i=2 then wumpus = cave3(wumpus)"
160 "2210if awake=1 then print ~*** CRUNCH ***~:print:print ~You have been eaten by the wumpus.~:goto 5000"
162 "2630print ~The wumpus is here! Asleep, though it won't stay like that for long.~"
167 "3020input ~Please enter the next room for the arrow to go to: ~; i$"
169 "3030if (j = cave1(arrow)) or (j = cave2(arrow)) or (j = cave3(arrow)) then arrow=j:goto 3071"
171 "3050if j = 0 then arrow = cave1(arrow)"
172 "3060if j = 1 then arrow = cave2(arrow)"
173 "3070if j = 2 then arrow = cave3(arrow)"
174 "3071if j = wumpus then print:print ~You hear a distant scream... the wumpus is dead! Now you just have to deal with the RSPCA lawyers.~:goto 5010"
175 "3080if j = player then print:print ~You have just been impaled on one of your own arrows.~:goto 5000"
179 "5000print:input ~You have died. Play again? (y/n) ~; i$:goto 5020"
180 "5010print:input ~You have won. Play again? (y/n) ~; i$"
181 "5020if i$=~y~ then goto 1000"
182 "5030print:print ~Bye bye!~"
190 constant NUM_SCRIPTS 3;
192 global script_id = 0;
193 global script_lineno = 0;
195 ! List the available scripts.
198 print "Available scripts:^";
202 print " ", i, ": ", (string) scripts-->i-->0, "^";
205 return ESTATE_NORMAL;
211 if ((i < 0) || (i >= NUM_SCRIPTS))
213 error("Script ID out of range");
217 print "Invoking script ~", (string) scripts-->i-->0, "~...^";
222 store_init(heap, heap+HEAP_SIZE);
224 i = command_loop(script_reader);
225 } until ((i == ESTATE_QUIT) || (i == ESTATE_NEW));
226 } until (i == ESTATE_QUIT);
228 print "Script finished.^";
229 return ESTATE_NORMAL;
232 ! Read in a command from a script into the parse buffer.
234 [ script_reader buf in l;
235 buf = mem_alloc(255);
239 ! Get the compressed data.
241 l = scripts-->script_id-->script_lineno;
247 ! Decompress it into the temporary buffer.
250 @output_stream 3 buf;
254 ! Ensure the string is zero-terminated.
259 ! Tokenise the stream.
261 in = tokenise_stream(in, parsebuffer);