Auto 0

# Run-time Variables

Var t: Num = 45
Var j: Num = 1
Var s: Num = 13
Var p: Num = 23759
Var z: Num = 1
Var y: Num = 1
Var n: Num = 0
Var pc: Num = 54992
Var s2: Num = 1
Var maxz: Num = 22
Var true: Num = 1
Var false: Num = 0
Var eof: Num = 5000
Var appos: Num = 39
Var plus: Num = 43
Var number: Num = 14
Var enter: Num = 13
Var string: Num = 50
Var overflow: Num = 15
Var quote: Num = 34
Var comma: Num = 44
Var space: Num = 32
Var dollar: Num = 36
Var hash: Num = 35
Var op: Num = 42
Var variable: Num = 1
Var keyword: Num = 164
Var digit0: Num = 48
Var digit9: Num = 57
Var capitala: Num = 65
Var capitalz: Num = 90
Var colon: Num = 58
Var semi: Num = 59
Var vattr: Num = 171
Var vat: Num = 172
Var vtab: Num = 173
Var vchr: Num = 194
Var vthen: Num = 203
Var vto: Num = 204
Var vstep: Num = 205
Var vink: Num = 217
Var vpaper: Num = 218
Var vflash: Num = 219
Var vbright: Num = 220
Var vinverse: Num = 221
Var vover: Num = 222
Var vborder: Num = 231
Var vdim: Num = 233
Var vrem: Num = 234
Var vfor: Num = 235
Var vgoto: Num = 236
Var vgosub: Num = 237
Var vinput: Num = 238
Var vlet: Num = 241
Var vpause: Num = 242
Var vnext: Num = 243
Var vpoke: Num = 244
Var vprint: Num = 245
Var random: Num = 249
Var vif: Num = 250
Var vcls: Num = 251
Var vclear: Num = 253
Var vreturn: Num = 254
Var vout: Num = 223
Var vstop: Num = 226
Var vint: Num = 186
Var vbin: Num = 196
Var lbracket: Num = 40
Var rbracket: Num = 41
Var smalla: Num = 97
Var smallz: Num = 122
Var source: Num = 23635
Var scroll: Num = 23692
Var index: Num = 9
Var uminus: Num = 7
Var opbrt: Num = 1
Var clbrt: Num = 2
Var gets: Num = 7986
Var fetch: Num = 6015
Var init: Num = 6010
Var dump: Num = 8035
Var deek: Num = 6205
Var doke: Num = 6300
Var findline: Num = 6745
Var toobig: Num = 6715
Var request: Num = 6900
Var skipst: Num = 7970
Var p2e: Num = 7950
Var pass1: Num = 6500
Var pass2: Num = 7000
Var patch: Num = 6795
Var tables: Num = 6700
Var addln: Num = 6725
Var next1: Num = 6555
Var z80: Num = 8000
Var itm: Num = 7330
Var p1e: Num = 6125
Var parsestr: Num = 7910
Var nextln: Num = 7030
Var nextst: Num = 7050
Var precolon: Num = 7660
Var atcolon: Num = 7670
Var store: Num = 7690
Var exppush: Num = 7752
Var exppop: Num = 7770
Var maths: Num = 7785
Var expnexts: Num = 7900
Var expnext: Num = 7800
Var expop: Num = 7822
Var expdoop: Num = 7857
Var bottom: Num = 53247
Var vars: Num = 54784
Var arrays: Num = 54992
Var prog: Num = 54992
Var top: Num = 65535
Var linetab: Num = 65535
Var tp: Num = 65535
Var last: Num = 0
Var errors: Num = 0
Var lines: Num = 1
Var num: Num = 10
Var lnum: Num = 10
Var t: NumArray(91) = 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0
Var a: NumArray(27) = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Var p: NumArray(27) = 14, 0, 8, 6, 1, 6, 9, 8, 12, 5, 5, 5, 11, 11, 11, 11, 11, -1, 11, 4, -1, 2, 3, 5, 5, 5, 11
Var o: NumArray(27) = -1, -1, 15, 16, -1, 17, 56, 18, 3, 42, 51, 44, 39, 40, 36, 38, 37, -1, 47, 41, -1, 54, 55, 43, 45, 46, 50
Var l: NumArray(22) = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Var s: NumArray(22) = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Var i: NumFOR = 27, 26, 1, 5815, 5

# End Run-time Variables

  10 FOR f=16384 TO 23295:\
     POKE f,RND *255:\
     NEXT f
4999 STOP
5000 REM Spectrum BASIC compiler
5005 REM Last revision:\
    22/03/84
5010 REM S N Goodwin & J A Smith
5015 REM
5020 REM **** INITIALISATION
5021 REM FAST
5025 CLEAR 53246
5030 PRINT "Load library.":\
     LOAD "zip.bin"CODE 53247
5035 DIM t(91):\
     REM Token types
5040 DIM a(27):\
     REM Array bases
5045 DIM p(27):\
     DIM o(27):\
     REM Function precedences & opcodes
5047 LET t=1:\
     LET i=t:\
     LET j=t:\
     LET s=t:\
     LET p=t:\
     LET pc=t:\
     LET z=t:\
     LET s2=t
5050 LET maxz=22:\
     DIM l(maxz):\
     DIM s(maxz):\
     REM Maths stacks
5060 RESTORE :\
     LET y=1:\
     LET n=0:\
     FOR i=1 TO 91:\
     READ t(i):\
     NEXT i:\
     DATA n,n,n,n,n,n,y,y,y,n,n,n,n,n,n,n,n,n,n,n,n,y,n,y,y,y,y,y,n,y,y,y,y,y,y,y,y,n,y,y,y,n,n,n,n,n,n,n,n,n,n,n,y,y,y,y,y,y,y,n,n,y,n,n,n,n,y,n,y,y,y,y,y,y,n,n,y,y,y,y,y,y,n,n,y,y,y,y,y,y,n
5070 FOR i=1 TO 27:\
     READ p(i):\
     READ o(i):\
     NEXT i:\
     DATA 14,-1,0,-1,8,15,6,16,1,-1,6,17,9,56,8,18,12,3,5,42,5,51,5,44,11,39,11,40,11,36,11,38,11,37,-1,-1,11,47,4,41,-1,-1,2,54,3,55,5,43,5,45,5,46,11,50
5190 REM
5200 REM **** MANIFEST CONSTANTS
5205 LET true=1:\
     LET false=0:\
     LET eof=5000
5210 LET appos=39:\
     LET plus=43:\
     LET number=14:\
     LET enter=13:\
     LET string=50:\
     LET overflow=15:\
     LET quote=34:\
     LET comma=44:\
     LET space=32:\
     LET dollar=36:\
     LET hash=35:\
     LET op=42:\
     LET variable=1
5220 LET keyword=164:\
     LET digit0=48:\
     LET digit9=57:\
     LET capitalA=65:\
     LET capitalZ=90:\
     LET colon=58:\
     LET semi=59
5225 LET vATTR=171:\
     LET vAT=172:\
     LET vTAB=173:\
     LET vCHR=194:\
     LET vTHEN=203:\
     LET vTO=204:\
     LET vSTEP=205:\
     LET vINK=217:\
     LET vPAPER=218:\
     LET vFLASH=219:\
     LET vBRIGHT=220:\
     LET vINVERSE=221:\
     LET vOVER=222
5230 LET vBORDER=231:\
     LET vDIM=233:\
     LET vREM=234:\
     LET vFOR=235:\
     LET vGOTO=236:\
     LET vGOSUB=237:\
     LET vINPUT=238:\
     LET vLET=241:\
     LET vPAUSE=242:\
     LET vNEXT=243:\
     LET vPOKE=244:\
     LET vPRINT=245:\
     LET random=249:\
     LET vIF=250:\
     LET vCLS=251:\
     LET vCLEAR=253:\
     LET vRETURN=254
5235 LET vOUT=223:\
     LET vSTOP=226:\
     LET vINT=186:\
     LET vBIN=196:\
     LET lbracket=40:\
     LET rbracket=41:\
     LET smalla=97:\
     LET smallz=122
5250 LET source=23635:\
     LET scroll=23692:\
     REM System variables
5255 LET index=9:\
     LET uminus=7:\
     LET opbrt=1:\
     LET clbrt=2
5390 REM
5400 REM **** BASIC LABELS
5405 LET gets=7986:\
     LET fetch=6015:\
     LET init=6010:\
     LET dump=8035
5410 LET deek=6205:\
     LET doke=6300:\
     LET findline=6745:\
     LET toobig=6715:\
     LET request=6900:\
     LET skipst=7970:\
     LET p2error=7950
5415 LET pass1=6500:\
     LET pass2=7000:\
     LET patch=6795:\
     LET tables=6700:\
     LET addln=6725:\
     LET next1=6555:\
     LET Z80=8000:\
     LET itm=7330
5420 LET p1error=6125:\
     LET parsestr=7910:\
     LET nextln=7030:\
     LET nextst=7050:\
     LET precolon=7660:\
     LET atcolon=7670:\
     LET store=7690
5440 LET exppush=7752:\
     LET exppop=7770:\
     LET maths=7785:\
     LET expnexts=7900:\
     LET expnext=7800:\
     LET expop=7822:\
     LET expdoop=7857
5790 REM
5800 REM **** MAIN PROGRAM
5805 LET bottom=53247:\
     LET vars=bottom+1537:\
     LET arrays=vars+26*8:\
     LET prog=arrays:\
     LET pc=prog
5810 LET top=65535:\
     LET linetab=top:\
     LET tp=linetab
5815 LET last=0:\
     LET errors=0:\
     LET lines=0:\
     FOR i=1 TO 26:\
     LET a(i)=0:\
     NEXT i
5820 GO SUB pass1:\
     PRINT PAPER 5; INK 0;'lines;" LINES scanned: ";errors;" ERRORS.":\
     IF errors THEN STOP
5830 GO SUB tables:\
     GO TO pass2
5840 IF errors THEN PRINT AT 0,0; PAPER 1;"ZIP FOUND ";errors;" ERRORS.":\
     STOP
5845 GO SUB patch:\
     REM Correct forward jumps
5850 PRINT AT 0,0; PAPER 1;"ZIP HAS FINISHED    (";pc-prog-36
5860 PRINT AT 19,0; INVERSE 1;"Save: SAVE ""???""CODE ";bottom;",";pc-bottom+2,,,"Run:  RANDOMIZE USR prog [";prog;"]":\
     STOP
5990 REM
6000 REM **** LEXICAL ANALYSIS
6005 REM Init & Fetch (source)
6010 LET t=source:\
     GO SUB deek:\
     LET p=t:\
     LET s=enter:\
     GO TO 6100
6015 LET last=s:\
     LET s=PEEK p:\
     LET p=p+1
6020 IF s=enter THEN GO TO 6100
6021 IF s<=space THEN GO TO 6015
6022 IF s>=smalla THEN IF s<=smallz THEN LET s=s-32:\
     REM lower case
6023 IF s=quote THEN LET num=p:\
     RETURN
6024 REM Analyse variable name
6025 IF last<capitalA OR last>capitalZ OR s<digit0 OR s>capitalZ THEN GO TO 6030
6026 IF s>digit9 THEN IF s<capitalA THEN GO TO 6030
6027 PRINT CHR$ s;:\
     LET s=PEEK p:\
     IF s>=smalla AND s<=smallz THEN LET s=s-32
6028 IF (s>=digit0 AND s<=digit9) OR s=space OR (s>=capitalA AND s<=capitalZ) THEN LET p=p+1:\
     GO TO 6027
6029 LET s=variable:\
     GO TO p1error
6030 IF s>=digit0 THEN IF s=BIN OR s<=digit9 THEN GO TO 6110
6040 IF s=INT THEN GO TO 6015
6045 IF s=hash OR s=dollar THEN GO TO p1error
6050 IF s>keyword THEN IF t(s-keyword)=0 THEN GO TO p1error
6090 RETURN
6095 REM New line found
6100 LET num=256*PEEK p+PEEK (p+1):\
     LET lnum=num:\
     LET t=p+2:\
     GO SUB deek:\
     LET p=p+4:\
     RETURN
6105 REM Number found
6110 IF PEEK p<>number THEN LET p=p+1:\
     GO TO 6110
6112 IF PEEK (p+1)<>0 THEN LET s=overflow:\
     LET p=p+6:\
     GO TO p1error
6115 LET p=p+3:\
     LET t=p:\
     GO SUB deek:\
     LET num=t:\
     IF PEEK (p-1) THEN LET num=-num
6120 LET p=p+3:\
     LET s=number:\
     RETURN
6122 REM PASS 1 Error (p1error)
6125 PAPER 6:\
     INK 0:\
     PRINT
6130 IF s=dollar THEN PRINT "Strings";
6135 IF s=variable THEN PRINT "Variable name";
6140 IF s=hash THEN PRINT "Streams";
6145 IF s>keyword THEN PRINT CHR$ s;
6150 IF s=overflow THEN PRINT "Decimal values & integers beyond+/-65535";
6155 PRINT " not allowed.":\
     LET errors=errors+1:\
     PAPER 0:\
     INK 7:\
     RETURN
6190 REM
6195 REM **** DEEK and DOKE
6200 REM Deek - t=contents of address t
6205 LET t=PEEK t+256*PEEK (t+1):\
     RETURN
6295 REM Doke - put t at address i
6300 POKE i,t-INT (t/256)*256:\
     POKE i+1,INT (t/256):\
     RETURN
6490 REM
6495 REM **** PASS1 Allocate RAM
6500 PAPER 0:\
     INK 7:\
     BORDER 0:\
     CLS :\
     PRINT PAPER 5; INK 0;"SPECTRUM BASIC COMPILER  PASS 1.":\
     GO SUB init
6505 IF s=enter THEN IF num>=eof THEN RETURN
6507 IF s=enter THEN LET lines=lines+1:\
     PRINT :\
     PRINT num;" ";:\
     POKE scroll,255:\
     GO TO next1
6510 IF s=number THEN PRINT num;:\
     GO TO next1
6512 IF s=vREM THEN GO TO 6545
6513 IF s=vDIM THEN GO SUB 6565
6515 IF s<>quote THEN PRINT CHR$ s;:\
     GO TO next1
6520 PRINT """";
6530 PRINT CHR$ PEEK p;
6535 IF PEEK p<>quote THEN LET p=p+1:\
     GO TO 6530
6540 LET p=p+1:\
     GO TO next1
6545 PRINT CHR$ s;:\
     LET s=PEEK p:\
     LET p=p+1:\
     IF s<>enter THEN GO TO 6545
6550 LET p=p-1:\
     GO TO next1
6555 GO SUB fetch:\
     GO TO 6505
6560 REM Evaluate DIM
6565 PRINT " DIM ";:\
     GO SUB fetch:\
     IF s<capitalA OR s>capitalZ THEN GO TO 6590
6570 LET v=s-64:\
     PRINT CHR$ (s);:\
     GO SUB fetch:\
     IF s<>lbracket THEN GO TO 6590
6575 PRINT "(";:\
     GO SUB fetch:\
     IF s<>number THEN GO TO 6590
6580 PRINT num;:\
     GO SUB fetch:\
     IF s<>rbracket OR num<1 THEN GO TO 6590
6585 LET a(v)=num:\
     RETURN
6590 PRINT PAPER 6; INK 0;'"Faulty DIM statement.":\
     LET errors=errors+1:\
     RETURN
6690 REM
6695 REM **** BUILD RAM TABLES
6700 FOR i=1 TO 26:\
     LET t=prog:\
     LET prog=prog+a(i)*2:\
     LET a(i)=t:\
     NEXT i:\
     LET a(27)=prog:\
     LET pc=prog
6705 LET linetab=top-4*lines-4:\
     LET tp=linetab:\
     FOR i=tp TO top-1:\
     POKE i,127:\
     NEXT i
6710 IF tp>pc THEN RETURN
6715 PRINT AT 21,0; PAPER 6; INK 0;"Insufficient memory.":\
     STOP
6718 REM
6720 REM **** CROSS REFERENCE ROUTINES
6725 REM Add an entry to line address table (addln)
6730 LET t=lnum:\
     LET i=xref:\
     GO SUB doke:\
     LET i=xref-2:\
     LET t=pc+1:\
     GO SUB doke:\
     LET xref=xref-4:\
     RETURN
6740 REM Find line n (return t pointing to its address)
6745 LET l=1:\
     LET u=(top-linetab)/4
6750 IF l>u THEN LET t=u*4+linetab-2:\
     RETURN
6755 LET t1=INT ((u+l)/2):\
     LET t=t1*4+linetab-2:\
     GO SUB deek
6760 IF n=t THEN LET t=t1*4+linetab-2:\
     RETURN
6765 IF n>t THEN LET u=t1-1:\
     GO TO 6750
6770 LET l=t1+1:\
     GO TO 6750
6790 REM
6795 REM Correct line references (patch)
6800 FOR q=linetab-2 TO tp STEP -2:\
     LET t=q:\
     GO SUB deek:\
     LET i=t:\
     GO SUB deek:\
     LET n=t:\
     GO SUB findline:\
     LET t=t-2:\
     GO SUB deek:\
     GO SUB doke:\
     NEXT q:\
     RETURN
6895 REM Put address of line t at pc-1 (request)
6910 IF lnum<t THEN GO TO 6920
6915 LET n=t:\
     GO SUB findline:\
     LET t=t-2:\
     GO SUB deek:\
     LET i=pc-1:\
     GO SUB doke:\
     RETURN
6920 IF tp-2<=pc THEN GO TO toobig
6925 LET tp=tp-2:\
     LET i=pc-1:\
     GO SUB doke:\
     LET i=tp:\
     LET t=pc-1:\
     GO SUB doke:\
     RETURN
6990 REM
6995 REM **** SYNTAX PARSER (pass2)
7000 GO SUB init:\
     LET bugs=false:\
     LET peep=0:\
     LET xref=top-2:\
     LET z=0
7010 LET pc=pc-1:\
     LET c=68:\
     GO SUB Z80:\
     REM Trap BREAK
7015 LET t=bottom+134:\
     GO SUB deek:\
     LET t1=t:\
     LET i=t1+1:\
     LET t=vars:\
     GO SUB doke:\
     LET i=t1+9:\
     LET t=prog-vars-1:\
     GO SUB doke:\
     REM Adjust library CLEAR code to initialise arrays (if any)
7020 LET c=49:\
     GO SUB Z80:\
     LET c=10:\
     GO SUB Z80:\
     REM CLEAR & CLS
7025 CLS :\
     PRINT PAPER 1;"COMPILING LINE      (0    bytes)"
7030 REM nextln
7040 IF lnum>=eof THEN LET lnum=9999:\
     GO SUB addln:\
     LET c=53:\
     GO SUB Z80:\
     POKE pc,255:\
     GO TO 5840:\
     REM End with 'OK' message
7045 PRINT AT 0,15; FLASH 1;lnum:\
     GO SUB addln
7050 REM nextst
7080 GO SUB gets
7100 IF s<>vREM THEN GO TO 7120
7105 LET s=PEEK p:\
     LET p=p+1:\
     IF s<>enter THEN GO TO 7105
7110 LET p=p-1:\
     GO TO precolon
7120 IF s<>vGOTO AND s<>vGOSUB THEN GO TO 7150
7125 LET c=4+(s=vGOSUB):\
     GO SUB gets:\
     IF s=number THEN LET t=num:\
     GO SUB Z80:\
     GO TO precolon
7130 LET bugs=number:\
     GO TO p2error
7150 IF s=vLET THEN GO SUB gets:\
     GO SUB store:\
     GO SUB gets:\
     GO SUB maths:\
     LET c=assmod:\
     LET t=assvar:\
     GO SUB Z80:\
     GO TO atcolon
7175 IF s=vRETURN THEN LET c=6:\
     GO SUB Z80:\
     GO TO precolon
7185 IF s=vIF THEN GO SUB gets:\
     GO SUB maths:\
     LET c=48:\
     LET t=lnum+1:\
     GO SUB Z80:\
     GO TO nextst
7205 IF s=vSTOP THEN LET c=53:\
     GO SUB Z80:\
     GO TO precolon
7210 IF s<>vFOR THEN GO TO 7245
7215 GO SUB gets:\
     LET assvar=s:\
     GO SUB gets:\
     GO SUB gets:\
     GO SUB maths:\
     GO SUB gets:\
     GO SUB maths:\
     IF s=vSTEP THEN GO SUB gets:\
     GO SUB maths:\
     GO TO 7230
7225 LET c=2:\
     LET t=1:\
     GO SUB Z80:\
     REM Generate implicit STEP 1
7230 LET c=7:\
     LET t=assvar-65:\
     GO SUB Z80:\
     GO TO atcolon
7245 IF s=vNEXT THEN GO SUB gets:\
     LET c=8:\
     LET t=s-65:\
     GO SUB Z80:\
     GO TO precolon
7250 IF s<>246 THEN IF s<>252 THEN GO TO 7260
7252 LET assmod=59+(s=252):\
     LET c=52:\
     GO SUB Z80:\
     REM Open #2
7254 GO SUB gets:\
     IF s>=vINK AND s<=vOVER THEN LET sep=s:\
     GO SUB gets:\
     GO SUB maths:\
     LET c=sep-189:\
     GO SUB Z80:\
     GO TO 7254
7258 GO SUB maths:\
     GO SUB gets:\
     GO SUB maths:\
     LET c=assmod:\
     GO SUB Z80:\
     GO TO atcolon
7260 IF s<>vBORDER AND s<>vPAUSE AND (s<vINK OR s>vOVER) THEN GO TO 7295
7265 LET assmod=s-197:\
     IF s=vBORDER THEN LET assmod=19
7266 IF s=vPAUSE THEN LET assmod=58
7270 GO SUB gets:\
     GO SUB maths:\
     LET c=assmod:\
     GO SUB Z80:\
     GO TO atcolon
7295 IF s=vPOKE OR s=vOUT THEN LET assmod=12+2*(s=vOUT):\
     GO SUB gets:\
     GO SUB maths:\
     GO SUB gets:\
     GO SUB maths:\
     LET c=assmod:\
     GO SUB Z80:\
     GO TO atcolon
7315 IF s=vCLEAR OR s=vCLS THEN LET c=10+39*(s=vCLEAR):\
     GO SUB Z80:\
     GO TO precolon
7320 IF s<>vPRINT THEN GO TO 7500
7323 LET sep=false:\
     LET c=52:\
     GO SUB Z80
7325 GO SUB gets
7327 REM Check print item (itm)
7330 IF s=enter OR s=colon THEN GO TO 7480
7334 LET sep=true
7335 IF s=semi THEN GO TO 7325
7340 IF s=appos THEN LET c=2:\
     LET t=13:\
     GO SUB Z80:\
     LET c=47:\
     GO SUB Z80:\
     GO TO 7325
7345 IF s=comma THEN LET c=2:\
     LET t=6:\
     GO SUB Z80:\
     LET c=47:\
     GO SUB Z80:\
     GO TO 7325
7346 LET sep=false
7355 IF s=chr THEN GO SUB maths:\
     GO TO itm
7365 IF s<>quote THEN GO TO 7385
7370 LET sptr=num
7375 GO SUB parsestr:\
     IF num THEN LET t=sptr:\
     LET c=26:\
     GO SUB Z80
7376 IF more THEN LET t=quote:\
     LET c=2:\
     GO SUB Z80:\
     LET c=47:\
     GO SUB Z80:\
     LET sptr=nptr+1:\
     GO TO 7375
7377 LET p=nptr:\
     GO SUB gets:\
     GO TO itm
7385 IF s=vAT THEN GO SUB gets:\
     GO SUB maths:\
     GO SUB gets:\
     GO SUB maths:\
     LET c=34:\
     GO SUB Z80:\
     GO TO itm
7405 IF s=vTAB THEN GO SUB gets:\
     GO SUB maths:\
     LET c=35:\
     GO SUB Z80:\
     LET c=2:\
     LET t=0:\
     GO SUB Z80:\
     LET c=47:\
     GO SUB Z80:\
     GO TO itm:\
     REM Oddly, TAB requires a 2 byte parameter!
7425 IF s>=vINK AND s<=vOVER THEN LET assmod=s:\
     GO SUB gets:\
     GO SUB maths:\
     LET c=assmod-189:\
     GO SUB Z80:\
     GO TO itm
7440 GO SUB maths:\
     LET c=27:\
     GO SUB Z80:\
     GO TO itm
7480 IF NOT sep THEN LET c=2:\
     LET t=13:\
     GO SUB Z80:\
     LET c=47:\
     GO SUB Z80
7485 GO TO atcolon
7500 IF s<>vINPUT THEN GO TO 7535
7505 GO SUB gets
7507 IF s=semi OR s=comma THEN GO TO 7505
7515 IF s=colon OR s=enter THEN GO TO atcolon
7520 IF s>=capitalA AND s<=capitalZ THEN GO SUB store:\
     LET c=9:\
     GO SUB Z80:\
     LET c=assmod:\
     LET t=assvar:\
     GO SUB Z80:\
     GO TO 7507
7525 LET bugs=vINPUT:\
     GO TO p2error
7535 IF s=random THEN GO SUB gets:\
     GO SUB maths:\
     LET c=57:\
     GO SUB Z80:\
     GO TO atcolon
7635 GO SUB skipst:\
     GO TO atcolon
7660 REM precolon
7665 GO SUB gets
7670 REM atcolon
7675 IF s=colon THEN GO TO nextst
7680 IF s=enter THEN GO TO nextln
7685 GO TO 7130:\
     REM Computed GO TO / GO SUB error??
7687 REM store  (var. name in s)
7690 LET assvar=s-65:\
     GO SUB gets:\
     LET assmod=11:\
     IF s=lbracket THEN GO SUB gets:\
     LET assmod=13:\
     GO SUB maths:\
     GO SUB gets:\
     IF a(assvar+1)=a(assvar+2) THEN LET bugs=index:\
     GO TO p2error
7695 RETURN
7698 REM
7700 REM **** EXPRESSION HANDLER
7750 REM exppush
7752 IF z=maxz THEN GO TO p2error
7755 LET z=z+1:\
     LET s(z)=tsav:\
     LET l(z)=s2:\
     LET oplast=true
7760 RETURN
7765 REM exppop
7770 LET z=z-1:\
     RETURN
7780 REM Scan expression (maths)
7785 LET commas=0:\
     LET z=0
7790 LET s2=opbrt:\
     LET tsav=0:\
     GO SUB exppush:\
     REM mark start
7795 REM expnext
7800 LET s2=s:\
     IF s2<>number THEN GO TO 7805
7802 IF l(z)=uminus THEN LET num=-num:\
     GO SUB exppop:\
     GO TO 7802:\
     REM Perform negation at once
7803 LET c=2:\
     LET oplast=false:\
     LET t=num:\
     GO SUB Z80:\
     GO TO expnexts:\
     REM Put num on Z80 stack
7805 IF s2>capitalZ OR s2<capitalA THEN GO TO expop
7810 LET oplast=false:\
     LET tsav=s2-65:\
     GO SUB gets:\
     LET s2=s:\
     IF s2=lbracket THEN LET s2=index:\
     GO SUB exppush:\
     LET s2=opbrt:\
     GO SUB exppush:\
     GO TO expnexts:\
     REM Subscript is a new expression
7815 LET c=1:\
     LET t=tsav:\
     GO SUB Z80:\
     GO TO expnext
7820 REM expop
7822 IF s2=plus AND oplast THEN GO TO expnexts:\
     REM Unary plus
7825 IF s2=appos OR (s2=comma AND commas=0) OR s2=vSTEP OR s2=vTO OR s=vTHEN OR s2=colon OR s2=semi OR s2=enter THEN LET s2=rbracket:\
     REM End expression with ')'
7828 REM Identify operators:\
    ()*+,-./<=> etc.
7830 IF s2=45 AND oplast THEN LET s2=uminus:\
     GO TO expdoop
7835 IF s2<=47 AND s2>=40 THEN LET s2=s2-39:\
     GO TO expdoop
7840 IF s2<=62 AND s2>=60 THEN LET s2=s2-50:\
     GO TO expdoop
7845 IF s2<=201 AND s2>=188 THEN LET s2=s2-175:\
     GO TO expdoop
7847 IF s2=vATTR THEN LET s2=27:\
     LET commas=commas+1:\
     GO TO expdoop
7850 GO TO p2error:\
     REM Unrecognised operator in s2
7855 REM expdoop
7857 IF z=1 AND s2=clbrt THEN RETURN :\
     REM finished
7860 LET prio=p(l(z)):\
     IF l(z)=opbrt THEN LET prio=0
7865 IF oplast OR prio<p(s2) OR prio=p(s2) AND oplast THEN GO SUB exppush:\
     GO TO expnexts:\
     REM Don't operate yet
7875 IF l(z)=opbrt AND s2=clbrt THEN GO SUB exppop:\
     GO TO expnexts:\
     REM End of sub-expression
7880 IF l(z)=opbrt THEN GO TO p2error
7885 LET c=o(l(z)):\
     LET t=s(z):\
     GO SUB exppop:\
     IF c<>-1 THEN GO SUB Z80:\
     GO TO expdoop
7887 LET commas=commas-1:\
     GO TO expdoop
7890 REM expnexts
7900 GO SUB gets:\
     GO TO expnext
7910 REM parsestr
7915 LET nptr=sptr:\
     LET num=0
7920 IF PEEK (nptr)<>quote THEN LET nptr=nptr+1:\
     LET num=num+1:\
     GO TO 7920
7925 LET nptr=nptr+1:\
     LET more=PEEK (nptr)=quote:\
     RETURN
7950 REM PASS 2 Error (p2error)
7955 LET errors=errors+1:\
     LET t=xref+4:\
     GO SUB deek:\
     PRINT AT errors+1,0;t;" ";:\
     REM Echo the most recent line reference
7956 IF bugs=index THEN PRINT "ARRAY ";CHR$ (assvar+65);"() WAS NOT DIMENSIONED":\
     GO TO 7963
7957 IF bugs=vINPUT THEN PRINT "WRONG INPUT FORMAT":\
     GO TO 7963
7958 PRINT "CALCULATION ";:\
     IF z=maxz THEN PRINT "TOO COMPLEX":\
     LET z=1:\
     GO TO 7963
7960 IF bugs=number THEN PRINT "NOT ALLOWED":\
     GO TO 7963
7961 PRINT "NOT UNDERSTOOD"
7963 LET bugs=false
7964 IF s<>enter THEN GO SUB fetch:\
     GO TO 7964
7965 IF errors<15 THEN GO TO nextln
7967 STOP
7970 REM skipst
7975 IF s<>colon AND s<>enter THEN GO SUB gets:\
     GO TO 7975
7980 RETURN
7985 REM gets
7986 IF NOT bugs THEN GO SUB fetch
7987 RETURN
7990 REM
7995 REM **** Z80 CODE GENERATION
8000 IF errors THEN RETURN
8010 IF pc>prog+36 THEN PRINT AT 0,21; PAPER 1;pc-prog-36
8020 IF c<=5 OR (c>=7 AND c<=8) OR c=11 OR c=13 OR c=26 OR c=37 OR c=48 OR c=68 THEN GO TO 8100
8025 REM Store code routine 'c'
8030 IF c>=28 AND c<=33 THEN LET c1=c:\
     LET c=35:\
     GO SUB dump:\
     POKE pc-3,c1-12:\
     RETURN :\
     REM Handle INK, PAPER etc alike
8032 REM dump (template No. c)
8035 LET j=bottom+c*2:\
     LET t=j:\
     GO SUB deek:\
     LET i=t:\
     LET t=j+2:\
     GO SUB deek:\
     LET j=t-i
8040 IF c=58 OR c=60 THEN LET j=4+(c=60)
8045 IF pc+j>=tp THEN GO TO toobig
8050 LET peep=peep AND PEEK (i)=225:\
     IF peep THEN LET pc=pc-2
8055 FOR t=1+peep TO j:\
     POKE t+pc,PEEK (i+t-1):\
     NEXT t:\
     LET pc=pc+j
8060 LET peep=PEEK pc=229:\
     RETURN
8100 LET t1=t:\
     GO SUB dump:\
     LET t=t1
8105 IF c=1 THEN LET i=pc-2:\
     LET t=vars+8*t:\
     GO SUB doke:\
     RETURN
8110 IF c=2 THEN LET i=pc-2:\
     GO SUB doke:\
     RETURN
8115 IF c=3 THEN LET i=pc-9:\
     LET t=a(t+1):\
     GO SUB doke:\
     RETURN
8120 IF c=4 OR c=5 OR c=48 THEN GO SUB request:\
     RETURN
8125 IF c<>7 THEN GO TO 8150
8130 LET t1=t*8+vars:\
     LET i=pc-15:\
     LET t=t1+2:\
     GO SUB doke:\
     LET i=pc-11:\
     LET t=t1+4:\
     GO SUB doke
8135 LET i=pc-7:\
     LET t=t1:\
     GO SUB doke:\
     LET i=pc-4:\
     LET t=pc+1:\
     GO SUB doke
8140 LET i=pc-1:\
     LET t=t1+6:\
     GO SUB doke:\
     RETURN
8150 IF c<>8 THEN GO TO 8180
8155 LET t1=vars+t*8:\
     LET i=pc-28:\
     LET t=t1:\
     GO SUB doke:\
     LET i=pc-24:\
     LET t=t1+2:\
     GO SUB doke
8160 LET i=pc-20:\
     LET t=t1:\
     GO SUB doke:\
     LET i=pc-16:\
     LET t=t1+4:\
     GO SUB doke:\
     LET i=pc-2:\
     LET t=t1+6:\
     GO SUB doke:\
     RETURN
8180 IF c=11 THEN LET i=pc-1:\
     LET t=vars+8*t:\
     GO SUB doke:\
     RETURN
8185 IF c=13 THEN LET i=pc-7:\
     LET t=a(t+1):\
     GO SUB doke:\
     RETURN
8190 IF c<>26 THEN GO TO 8205
8192 LET i=0
8194 LET i=i+1:\
     IF PEEK (t+i)<>quote THEN GO TO 8194
8196 IF i+pc>=tp THEN GO TO toobig
8198 LET i1=i:\
     LET t1=t:\
     LET i=pc-6:\
     LET t=i1:\
     GO SUB doke:\
     LET i=pc-9:\
     LET t=pc+1:\
     GO SUB doke
8200 FOR j=1 TO i1:\
     POKE pc+j,PEEK (t1+j-1):\
     NEXT j:\
     LET pc=pc+i1:\
     RETURN
8205 IF c=37 THEN LET i=pc-4:\
     LET t=pc:\
     GO SUB doke:\
     RETURN
8210 IF c=68 THEN LET t=bottom+c*2-2:\
     GO SUB deek:\
     LET i=t+1:\
     LET t=top-8:\
     GO SUB doke:\
     RETURN
8500 PRINT INK 0; PAPER 6;"CODE GENERATION ERROR";c:\
     STOP
