home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ahoy 1988 October
/
Ahoy_Magazine_88-10_1988_Double_L.d64
/
Mini-comp
(
.txt
)
< prev
next >
Wrap
Commodore BASIC
|
2022-10-26
|
8KB
|
249 lines
1 rem==================================
2 rem mini-comp
3 rem rupert report #58
4 rem a minimal compiler for the c-64
5 rem==================================
6 rem run 2000 to compile
7 rem==================================
8 rem
9 rem lines 1 through 999 are examples of all statements allowed by mini-comp
10 a=50
20 b=-10
30 c=a
40 d=a+b
50 if a=b then 60
60 goto 70
70 print
80 print a
90 print b;
100 print chr$(c)
110 print chr$(d);
999 end
1000 rem --- common routines ---
1100 c=peek(m): m=m+1: print c,: if c=32 then 1100: rem ignore spaces
1110 if c=0 then print
1120 return
1300 vf=true: if c<65 or c>90 then vf=false: return
1310 ad=(c-65)*2 + vm
1320 nx=ad: gosub 1400: a0=nl: a1=nh : rem var lsb
1330 nx=ad+1: gosub 1400: a2=nl: a3=nh : rem var msb
1340 return
1400 nh=int(nx/256)
1410 nl=nx-256*nh
1420 return
1500 for kk=1 to n
1510 if cm>em then print"out of memory - compiled prgm too large": end
1520 poke cm,c(kk)
1530 print cm;":";c(kk)
1540 cm=cm+1: next
1550 return
2000 rem ====== initialization =========
2010 dim ll(50,2) :rem ll(n,1)=line # of nth line
2015 :rem ll(n,2)=compiled mem location of this line
2020 dim c(50) :rem stores object code bytes
2030 false=0: true=not false
2040 def fnptr(m)=peek(m)+256*peek(m+1)
2050 vm=49152 :rem $c000 start of variable mem
2060 pm=49408 :rem $c100 start of object memory
2070 em=53247 :rem $cfff end of object memory
2080 bt=2049 :rem $0800 start of basic text
2085 gosub 11000 :rem put print rtn in mem
2090 m=bt :rem next source memory to peek
2100 sn=1 :rem current source statement number
2110 cm=pm :rem next object memory to poke
2120 for n=vm to vm+51: poke n,0: next : rem clr var's
2125 rem ============= main ============
2130 ptr=fnptr(m): m=m+2 :rem next line ptr
2140 ln=fnptr(m): m=m+2 :rem current line #
2150 if ln>999 then print "=== end of pass 1 ===": goto 2400
2160 print " current line # ="; ln
2170 ll(sn,1)=ln :rem current line #
2180 ll(sn,2)=cm :rem start obj mem loc
2190 sn=sn+1 :rem # source statements
2200 rem --- get byte ---
2210 gosub 1100 :rem fetch next byte
2220 gosub 1300: if vf then gosub 3000 : goto 2290: rem 'variable
2230 if c=139 then gosub 4000: goto 2290: rem 'if
2240 if c=137 then gosub 5000: goto 2290: rem 'goto
2250 if c=153 then gosub 6000: goto 2290: rem 'print
2260 if c=128 then gosub 7000: goto 2290: rem 'end
2270 if c=143 then gosub 8000: goto 2290: rem 'rem
2280 print "unknown command code";c;"in line";ll(sn,1):stop
2290 if c>0 then ec=0: gosub 10000: stop :rem 'eol
2300 get k$:if k$="" then 2130 :rem back for more
2310 get k$:if k$="" then 2310
2320 goto 2130
2400 rem - pass 2 - fix jump addresses
2410 if ji=0 then 2570 :rem no jumps
2420 for n=1 to ji :rem check items in jump table
2430 :mm=jt(n,1) :rem referenced line #
2440 :for j=1 to sn :rem check actual line #s
2445 :rem - get obj mem target address and jmp address:
2450 :if mm=ll(j,1) then taddr=jt(n,2): jaddr=ll(j,2): goto 2490
2460 :next j
2470 :rem no match found
2480 :ec=1: ln=jt(n,0): gosub 10000:stop
2490 :nx=jaddr :rem addr of line # mm
2530 :gosub 1400 :rem convert line #
2540 :poke taddr,nl :rem use addr in jump table
2550 :poke taddr+1,nh
2560 next n :rem next jump table item
2570 print"=== end of pass 2 ==="
2580 print"to execute the compiled program, enter"
2590 print" sys"; pm
2595 print"object code resides from";pm;"to";cm-1
2600 end
3000 rem <<< a=(-)nn, a=b, a=b+c >>>
3010 d0=a0: d1=a1 :rem addr of a's lsb
3020 d2=a2: d3=a3 :rem a's msb
3030 gosub 1100: if c<>178 then ec=178: ec$=" = ": gosub 10000: stop :rem '=
3040 gosub 1100 :rem '-, nn, or b
3050 gosub 1300: if vf then 3400 :rem 'b
3055 rem <<< a=(-)nn >>>
3060 if c=171 then c$="-" :rem '-
3065 if c<>171 then c$=" "+chr$(c) :rem '0-9
3070 gosub 1100 :rem get digits of nn
3080 if c=0 then 3120
3085 if chr$(c)<"0" or chr$(c)>"9" then ec=48: gosub 10000: stop
3090 c$=c$+chr$(c)
3100 goto 3070
3120 nn=val(c$)
3130 nn%=nn :rem error check
3140 if nn<0 then nn=nn+65536 :rem convert (-32768,32767) to (0,65535)
3150 nx=nn: gosub 1400
3170 msb=nh: lsb=nl
3175 :rem lda #nn(lsb), sta a(lsb), lda #nn(msb), sta a(msb)
3180 n=10: c(1)=169: c(2)=lsb: c(3)=141: c(4)=d0: c(5)=d1
3190 c(6)=169: c(7)=msb: c(8)=141: c(9)=d2: c(10)=d3
3200 gosub 1500 :rem poke values into object memory
3210 return
3400 rem <<< a=b or a=b+c >>>
3410 s0=a0: s1=a1 :rem b's lsb addr
3420 s2=a2: s3=a3 :rem b's msb
3430 gosub 1100
3440 if c=0 then 3600 :rem a=b
3450 rem <<< a=b+c >>>
3460 if c<>170 then ec=170: ec$=" + ": gosub 10000: stop :rem test '+
3470 gosub 1100: gosub 1300: if not vf then ec=65: gosub 10000: stop: rem 'c
3480 gosub 1100: if c>0 then ec=0: gosub 10000: stop :rem 'eol
3490 s4=a0: s5=a1 :rem addr c's lsb
3500 s6=a2: s7=a3 :rem c's msb
3530 rem clc, lda b(lsb), adc c(lsb),sta a(lsb)
3535 rem lda b(msb), adc c(msb), sta a(msb)
3540 n=19: c(1)=24: c(2)=173: c(3)=s0: c(4)=s1
3550 c(5)=109: c(6)=s4: c(7)=s5: c(8)=141: c(9)=d0: c(10)=d1
3560 c(11)=173: c(12)=s2: c(13)=s3: c(14)=109: c(15)=s6: c(16)=s7
3570 c(17)=141: c(18)=d2: c(19)=d3
3580 gosub 1500
3590 return
3600 rem <<< a=b >>>
3610 rem lda b(lsb), sta a(lsb), lda b(msb), sta a(msb)
3620 n=12: c(1)=173: c(2)=s0: c(3)=s1: c(4)=141: c(5)=d0: c(6)=d1
3630 c(7)=173: c(8)=s2: c(9)=s3: c(10)=141: c(11)=d2: c(12)=d3
3640 gosub 1500
3650 return
4000 rem <<< if a=b then mm >>>
4010 gosub 1100 :rem 'a
4020 gosub 1300: if not vf then ec=65: gosub 10000: stop
4030 s0=a0: s1=a1: s2=a2: s3=a3
4040 gosub 1100: if c<>178 then ec=178: gosub 10000: stop :rem '=
4050 gosub 1100 :rem 'b
4060 gosub 1300: if not vf then ec=65: gosub 10000: stop
4070 gosub 1100 :rem 'then
4080 if c<>167 then ec=167: gosub 10000: stop
4090 c$=""
4100 gosub 1100: if c=0 then 4120 :rem get mm
4110 c$=c$+chr$(c): goto 4100
4120 mm=val(c$)
4130 if mm<0 or mm>999 then ec=1: gosub 10000: stop
4140 ji=ji+1 :rem jump table index
4150 jt(ji,0)=ln :rem current line #
4160 jt(ji,1)=mm :rem target line #
4170 jt(ji,2)=cm+17 :rem mem loc after 'jmp
4180 rem lda a(msb), cmp b(msb), bne exit,
4185 rem lda a(lsb), cmp b(lsb), bne exit, jmp mm
4190 n=19: c(1)=173: c(2)=s2: c(3)=s3
4200 c(4)=205: c(5)=a2: c(6)=a3
4210 c(7)=208: c(8)=11: c(9)=173: c(10)=s0: c(11)=s1
4220 c(12)=205: c(13)=a0: c(14)=a1
4230 c(15)=208: c(16)=3: c(17)=76: c(18)=0: c(19)=0
4240 gosub 1500
4250 return
5000 rem <<< goto mm >>>
5010 c$=""
5020 gosub 1100: rem get digits of mm
5030 if c=0 then 5060
5040 c$=c$+chr$(c)
5050 goto 5020
5060 mm=val(c$)
5070 if mm<0 or mm>999 then ec=1: gosub 10000: stop
5080 ji=ji+1 :rem jump table index
5085 jt(ji,0)=ln :rem source line#
5090 jt(ji,1)=mm :rem target line#
5100 jt(ji,2)=cm+1 :rem obj mem location after 'jmp'
5110 rem jmp mm
5120 n=3: c(1)=76: c(2)=0: c(3)=0
5130 gosub 1500
5140 return
6000 rem <<< print, print a[;], or print chr$(a)[;] >>>
6010 gosub 1100: if c=199 then 6300 :rem 'chr$
6020 if c=0 then pc=13: gosub 6200: return: rem 'print
6030 gosub 1300: if not vf then ec=65: gosub 10000: stop
6040 rem <<< print a >>>
6050 rem ldx $a(msb), ldy $a(lsb), jsr $c0e0
6060 print: n=9: c(1)=174: c(2)=a0: c(3)=a1
6070 c(4)=172: c(5)=a2: c(6)=a3
6080 c(7)=32: c(8)=224: c(9)=192
6090 gosub 1500
6095 pc=32: gosub 6200 :rem add space after digits
6100 gosub 1100: if c=0 then pc=13: gosub 6200: return :rem print cr
6110 if c<>59 then ec=59: gosub 10000: stop :rem ' ;
6120 gosub 1100: if c>0 then ec=0: gosub 10000: stop
6130 return
6200 rem --- print character pc ---
6210 rem lda #pc, jsr $ffd2
6220 print:n=5: c(1)=169: c(2)=pc: c(3)=32
6230 c(4)=210: c(5)=255: gosub 1500
6240 return
6300 rem <<< print chr$(a) [;] >>>
6310 gosub 1100: if c<>40 then ec=40: gosub 10000: stop :rem '(
6320 gosub 1100: gosub 1300: if not vf then ec=65: gosub 10000: stop
6330 rem lda a(lsb), jsr $ffd2
6340 print: n=6: c(1)=173: c(2)=a0: c(3)=a1
6350 c(4)=32: c(5)=210: c(6)=255
6360 gosub 1500
6370 gosub 1100: if c<>41 then ec=41: gosub 10000: stop : rem ')
6380 gosub 1100: if c>0 then 6400
6390 print: pc=13: gosub 6200: return
6400 if c<>59 then ec=59: gosub 10000: stop :rem ';
6410 gosub 1100: if c<>0 then ec=0:gosub 10000: stop
6420 return
7000 rem <<< end >>>
7005 rem rts
7010 n=1: c(1)=96: gosub 1500
7020 gosub 1100: if c<>0 then ec=0:gosub 10000: stop
7030 return
8000 rem <<< rem >>>
8010 gosub 1100: if c>0 then 8010
8020 return
10000 print:print"syntax error in line[146]";ln
10010 if ec=0 then print"expected end-of-line not found":return
10020 if ec=1 then print"invalid line number":return
10030 if ec=48 then print"numeric value 0-9 expected": return
10040 if ec=65 then print"variable a-z expected": return
10050 if ec>127 then print"expected basic keyword ";ec$: return
10060 print"expected character ";chr$(ec);" with ascii value"ec :return
11000 rem -- put m.l. print routine into memory --
11010 m=49376 :rem $c0e0
11020 cs=3319 :rem checksum
11030 read b: if b<0 then 11060
11040 poke m,b: m=m+1: ck=ck+b
11050 goto 11030
11060 if ck<>cs then print"error in data statements starting at 11120":stop
11070 return
11080 data 169, 32, 200, 136, 16, 2
11090 data 169, 45, 32, 210, 255, 152, 16, 12
11100 data 138, 73, 255, 24, 105, 1, 170, 152
11110 data 73, 255, 105, 0, 32, 205, 189, 96
11120 data -1