!Graham Toal - latest development version of SKIMPB 12/02/80 16.25
external predicate spec find(integer flag, integer name ty, la)
external integer array spec a(1 : 500)
external integer array spec taglink(0 : 255)
external integer array spec tag(1 : 512)
external integer array spec link(1 : 512)
!-----------------------------------------------------------------------
external routine spec expr(integer exprp)
external integer fn spec cond(integer condp, tlabel, flabel)
external string (7) fn spec s(integer n)
external string (255) fn spec strint(integer n, p)
external integer fn spec getwork
external routine spec returnwork(integer work)
external routine spec clearwork
external integer fn spec newtag
external routine spec pushtag(integer ident, form, type, dim, level, rad)
external routine spec poptags
external integer fn spec getlabel(integer constp)
external routine spec filllabel(integer label)
external integer fn spec fillbranch(integer label)
external routine spec poplabels
external integer fn spec nextplabel
external routine spec dump(string (7) lab, op, reg, addr)
external routine spec fault(string (63) mess)
external string (255) fn spec name(integer ident)
external routine spec pushstart(integer flag, plab)
external routine spec popstart(integer name flag, plab)
external routine spec findcontinue(integer name type, flag)
external routine spec findexit(integer name type, flag)
external routine spec popcycle(integer name type, lab)
external routine spec clearstart
external integer fn spec enter
external routine spec dumpreturn
external routine spec proc(integer procp)
external routine spec array(integer arrayp)
external routine spec endofprog
!-----------------------------------------------------------------------
external integer array nextrad(0 : 15)
external string (5) array display(0 : 15) = "Bug", "-2,X", "-4,X", c
"-6,X", "-8,X", "-10,X", "-12,X", "-14,X", "-16,X", "-18,X", "-20,X", c
"-22,X", "-24,X", "-26,X", "-28,X", "-30,X"
external integer level, nextcad = 1, pstr = 0
!-----------------------------------------------------------------------
own integer array proctype(0 : 15)
own integer array staticalloc(0 : 15)
own string (3) array regs(1 : 2) = "A", "A,B"
external integer array rt(0 : 15)
external integer array parms(0 : 15)
external integer spec traceopt, checkopt
external integer aopt = 0
!-----------------------------------------------------------------------
external routine statement(integer statementp)
own integer access = 1
routine spec doloop(integer loopsp)
routine spec instr(integer instrp)
string (4) base, b1, b2
switch sttype(1:13)
integer condp, instrp, elsep, constp, arrayp, namep, namesp, expr1p, c
expr2p, instr2p, tlabel, flabel, label, fplabel, tplabel, work1, work2, c
flag, plabel, procp, formalp, formp, params, procid, ident, form, paramt, c
paraml, dim, basep, type, cyclab, cntlab, extlab
-> sttype(a(statementp))
!-----------------------------------------------------------------------
sttype(1):
! <instr><CYCLAUSE>
if access = 0 then fault("ACCESS?") and access = 1
dump("", "SWI", "3", "") if traceopt = 1
unless a(a(a(statementp + 2) + 1)) = 2 then doloop(a(statementp + 2))
instr(a(statementp + 1))
if a(a(a(statementp + 2) + 1)) = 2 then return
if access = 0 then fault("DUBIOUS STATEMENT") and access = 1
condp = a(a(a(statementp + 2) + 1) + 1)
a(1) = 1
a(2) = 3
if a(a(statementp + 2)) <= 2 then a(3) = 2 else a(3) = 1
statementp = 1
-> untilst
!-----------------------------------------------------------------------
sttype(2):
! "IF"<cond>"THEN"<instr><else>
condp = a(statementp + 1)
instrp = a(statementp + 2)
elsep = a(statementp + 3)
if access = 0 then fault("ACCESS?") and access = 1
dump("", "SWI", "3", "") if traceopt = 1
if 7 <= a(instrp) <= 8 or a(instrp) = 2 then start
! branch
if a(instrp) = 7 then findcontinue(type, tlabel) c
else if a(instrp) = 8 then findexit(type, tlabel) else start
constp = a(instrp + 1)
tlabel = getlabel(constp)
finish
if a(elsep) = 2 then filllabel(cond(condp, tlabel, -1)) else start
instrp = a(elsep + 1)
if 7 <= a(instrp) <= 8 or a(instrp) = 2 then start
! branch
if a(instrp) = 7 then findcontinue(type, flabel) c
else if a(instrp) = 8 then findexit(type, flabel) else start
constp = a(instrp + 1)
flabel = getlabel(constp)
finish
access = 0
filllabel(cond(condp, tlabel, flabel))
dump("", "LBRA", "", "L" . s(flabel))
return
finish else start
filllabel(cond(condp, tlabel, -1))
if a(instrp) = 3 then pushstart(1, -1) else instr(instrp)
finish
finish
finish else start
if a(elsep) = 2 then start
fplabel = cond(condp, -1, -1)
if a(instrp) = 3 then pushstart(0, fplabel) else instr(instrp) and filllabel(fplabel)
finish else start
instr2p = a(elsep + 1)
if 7 <= a(instr2p) <= 8 or a(instr2p) = 2 then start
! branch
if a(instr2p) = 7 then findcontinue(type, flabel) c
else if a(instr2p) = 8 then findexit(type, flabel) else start
constp = a(instr2p + 1)
flabel = getlabel(constp)
finish
fplabel = cond(condp, -1, flabel)
! result always -1
instr(instrp)
finish else start
fplabel = cond(condp, -1, -1)
instr(instrp)
tplabel = nextplabel
dump("", "LBRA", "", "L" . s(tplabel))
filllabel(fplabel)
if a(instr2p) = 3 then pushstart(1, tplabel) c
else instr(instr2p) and filllabel(tplabel)
finish
finish
finish
access = 1
return
!-----------------------------------------------------------------------
sttype(3):
! <const>':'<statement>
access = 1
constp = a(statementp + 1)
statementp = a(statementp + 2)
label = getlabel(constp)
filllabel(label)
statement(statementp)
return
!-----------------------------------------------------------------------
sttype(4):
! "FINISH"<else>
access = 1
elsep = a(statementp + 1)
popstart(flag, plabel)
if flag = 0 then start
! first %start/%finish
if a(elsep) = 1 then start
instrp = a(elsep + 1)
tplabel = nextplabel
dump("", "LBRA", "", "L" . s(tplabel))
filllabel(plabel)
if a(instrp) = 3 then pushstart(1, tplabel) c
else instr(instrp) and filllabel(tplabel)
finish else filllabel(plabel)
finish else start
! second %start/%finish
if a(elsep) = 1 then fault("SPURIOUS %ELSE") else filllabel(plabel)
finish
return
!-----------------------------------------------------------------------
sttype(5):
! "INTEGER"<array>
arrayp = a(statementp + 1)
namep = a(arrayp + 1)
namesp = a(arrayp + 2)
if a(arrayp) = 1 then start
! array declaration
dump("", "SWI", "3", "") if traceopt = 1
if access = 0 then fault("ACCESS?") and access = 1
if find(2, cyclab, type) then fault("ORDER?")
if level = 1 then base = ",X" else base = ",Y"
cycle
expr1p = a(arrayp + 3)
expr2p = a(arrayp + 4)
expr(expr1p)
dump("", "SEX", "", "")
dump("", "PSH", "U", "A,B")
work1 = getwork
!***dump("STR","ACC",display(level),work1)
expr(expr2p)
dump("", "SEX", "", "")
dump("", "ADD", "D", "#1")
dump("", "PSH", "U", "A,B")
dump("", "TFR", "", "S,D")
!***dump("LDA","ACC","ACC",1)
work2 = getwork
!***dump("STR","ACC",display(level),work2)
cycle
staticalloc(level) = staticalloc(level) + 2
nextrad(level) = nextrad(level) + 2
pushtag(a(namep + 1), 2, 1, 2, level, nextrad(level))
dump("", "SUB", "D", "0,U")
dump("", "ST", "D", "-" . s(nextrad(level)) . base)
dump("", "ADD", "D", "2,U")
! DUMP("","SUB","D","#1")
!***dump("SUB","STP",display(level),work1)
!***dump("STR","STP",display(level),nextrad(level))
!***dump("ADD","STP",display(level),work2)
if a(namesp) = 2 then exit
namep = a(namesp + 1)
namesp = a(namesp + 2)
repeat
dump("", "TFR", "", "D,S")
dump("", "LEA", "U", "4,U")
returnwork(work1)
returnwork(work2)
if a(a(arrayp + 5)) = 1 then start
arrayp = a(arrayp + 5)
namep = a(arrayp + 1)
namesp = a(arrayp + 2)
continue
finish else return
repeat
finish else start
cycle
staticalloc(level) = staticalloc(level) + 1
nextrad(level) = nextrad(level) + 1
pushtag(a(namep + 1), 0, 1, 1, level, nextrad(level))
if a(namesp) = 2 then exit
namep = a(namesp + 1)
namesp = a(namesp + 2)
repeat
finish
return
!-----------------------------------------------------------------------
sttype(6):
! <proc><name><formal>
if level = 0 then fault("PROCEDURE BEFORE %BEGIN")
if level = 15 then fault("PROCEDURE NESTING TOO DEEP")
access = 1
procp = a(statementp + 1)
namep = a(statementp + 2)
formalp = a(statementp + 3)
procid = a(namep + 1)
! skipproc(level)=nextcad
pushtag(procid, 4, a(procp) - 1, 0, level, nextcad)
level = level + 1
rt(level) = tag(taglink(procid)) & 16_FFFF
dump("", "LBRA", "", "S" . s(rt(level)))
dump("E" . s(rt(level)), "EQU", "", "*")
proctype(level) = a(procp)
staticalloc(level) = enter
! nextrad(level)=2
parms(level) = 0
if a(formalp) = 2 then -> retn
! no parameters
params = 0
paraml = taglink(procid)
cycle
formp = a(formalp + 1)
namep = a(formalp + 2)
namesp = a(formalp + 3)
formalp = a(formalp + 4)
if a(formp) = 1 then form = 3 and dim = 2 else start
if a(formp) = 2 then form = 1 and dim = 2 c
else form = 0 and dim = 1
finish
cycle
ident = a(namep + 1)
! declare parameters as locals
nextrad(level) = nextrad(level) + dim
staticalloc(level) = staticalloc(level) + dim
pushtag(ident, form, 1, dim, level, nextrad(level))
! DUMP("","PUL","U",REGS(DIM))
! DUMP("","PSH","S",REGS(DIM))
! append parameter tag cells to procedure tag cell
paramt = newtag
tag(paramt) = tag(taglink(ident))
link(paramt) = link(paraml)
link(paraml) = paramt
paraml = paramt
parms(level) = parms(level) + dim
params = params + 1
if params > 15 then fault(name(procid) . " HAS TOO MANY PARAMETERS") and stop
if a(namesp) = 2 then exit
namep = a(namesp + 1)
namesp = a(namesp + 2)
repeat
repeat until a(formalp) = 2
! insert number of parameters into tag cell
tag(taglink(procid)) = tag(taglink(procid)) ! params << 20
retn:
dump("", "LEA", "S", "-A" . s(rt(level)) . ",S")
return
!-----------------------------------------------------------------------
sttype(7):
! "END"<ofprog>
if level > 1 start
! DUMP("P".S(RT(LEVEL)),"EQU","",S(PARMS(LEVEL)))
if proctype(level) # 1 and checkopt = 1 then dump("", "SWI", "", "")
! %RESULT NOT ENCOUNTERED
! DUMP("R".S(RT(LEVEL)),"EQU","","*")
finish
poptags
poplabels
clearstart
clearwork
dump("A" . s(rt(level)), "EQU", "", s(staticalloc(level)))
if proctype(level) >= 1 and access = 1 then dumpreturn
access = 1
level = level - 1
if a(a(statementp + 1)) = 2 then start
! %end
if level <= 0 then fault("SPURIOUS %END") and endofprog
dump("S" . s(rt(level + 1)), "EQU", "", "*")
finish else start
! %endofprogram
if level # 0 then fault("TOO FEW %ENDS")
endofprog
finish
return
!-----------------------------------------------------------------------
sttype(8):
! "BEGIN"
if level # 0 then fault("SPURIOUS %BEGIN") else start
rt(1) = 0
level = 1
proctype(1) = 0
staticalloc(1) = enter
nextrad(1) = staticalloc(1)
finish
return
sttype(9):
! <LOOPS>%CYCLE
if access = 0 then fault("WARNING - ACCESS???") and access = 1
dump("", "SWI", "3", "") if traceopt = 1
doloop(a(statementp + 1))
return
sttype(10):
! %REPEAT<UNTIL>
condp = a(a(statementp + 1) + 1)
dump("", "SWI", "3", "") if traceopt = 1
untilst:
access = 1
popcycle(type, cyclab)
cntlab = cyclab + 1
extlab = cntlab + 1
if a(a(statementp + 1)) # 2 then start
dump("L" . s(cntlab), "EQU", "", "*")
tplabel = cond(condp, -1, cyclab)
if type = 2 then dump("L" . s(extlab), "LEA", "U", "4,U") c
else dump("L" . s(extlab), "EQU", "", "*")
finish else start
dump("L" . s(cntlab), "LBRA", "", "L" . s(cyclab))
if type = 2 then dump("L" . s(extlab), "LEA", "U", "4,U") c
else dump("L" . s(extlab), "EQU", "", "*")
finish
return
sttype(13):
! "PRINTTEXT" <STRING>
pstr = 1
fault("ACCESS?") and access = 1 if access = 0
dump("", "SWI", "3", "") if traceopt = 1
dump("", "LBSR", "", "PSTR")
printstring(" FCB ")
work1 = 4
cycle
work2 = a(work1)
if work2 # 16_80 then write(work2, 0) else printstring("$80") and exit
printsymbol(',')
work1 = work1 + 1
repeat
newline
return
sttype(11):
! "CONSTANT" <NAME) '=' <VALUE>
dump(name(a(a(statementp + 1) + 1)), "EQU", "", s(a(a(statementp + 2) + 1)))
return
sttype(12):
! "LABEL" <NAME>
dump(name(a(a(statementp + 1) + 1)), "EQU", "", "*")
return
!-----------------------------------------------------------------------
routine instr(integer instrp)
switch instype(1:14)
string (4) base
integer namep, assignp, constp, ident, actualp, exprp, nametag, c
disp, work, rinstrp, type, lab
-> instype(a(instrp))
!-----------------------------------------------------------------------
instype(1):
! <name><actual><assign>
namep = a(instrp + 1)
actualp = a(instrp + 2)
assignp = a(instrp + 3)
rinstrp = a(instrp + 4)
ident = a(namep + 1)
!? %if taglink(ident)=0 %then fault(name(ident)." NOT DECLARED") !? %and %return
if taglink(ident) = 0 start
if a(assignp) # 1 then dump("", "FDB", "", name(ident)) c
else expr(a(assignp + 1)) and dump("", "ST", "B", name(ident))
finish else start
nametag = tag(taglink(ident))
! %ROUTINE GET NAME ADDRESS ????
if a(assignp) = 1 then start
if nametag >> 28 = 4 then fault(name(ident) . " NOT A DESTINATION") and return
exprp = a(assignp + 1)
if nametag >> 28 >= 2 then start
! array variable
expr(exprp)
work = getwork
dump("", "PSH", "U", "B")
array(instrp)
dump("", "PUL", "U", "B")
dump("", "ST", "B", "[0,X]")
returnwork(work)
finish else start
expr(exprp)
basep = nametag >> 16 & 16_F
disp = nametag & 16_FFFF
base = display(basep)
base = ",Y" if basep = level
base = ",X" if basep = 1
if basep = level or basep = 1 start
if nametag >> 28 = 1 then b1 = "[" and b2 = "]" else b1 = "" and b2 = ""
dump("", "ST", "B", b1 . "-" . s(disp) . base . b2)
finish else start
dump("", "PSH", "U", "A,B")
dump("", "LD", "D", base)
dump("", "SUB", "D", "#" . s(disp))
dump("", "ST", "D", "0,X")
if nametag >> 28 = 1 then start
dump("", "LD", "D", "[0,X]")
dump("", "ST", "D", "0,X")
finish
dump("", "PUL", "U", "A,B")
dump("", "ST", "B", "[0,X]")
finish
if a(actualp) = 1 then fault(name(ident) . " DECLARED AS SCALAR")
finish
! %END OF ROUTINE GET NAME ADDRESS???
finish else start
if nametag >> 28 = 4 and nametag >> 24 & 16_F = 0 c
then proc(instrp) else fault(name(ident) . " NOT A ROUTINE NAME")
finish
finish
if a(rinstrp) = 1 then instrp = a(rinstrp + 1) and -> instype(a(instrp))
return
!-----------------------------------------------------------------------
instype(2):
! '->'<const>
access = 0
constp = a(instrp + 1)
label = getlabel(constp)
dump("", "LBRA", "", "L" . s(label))
return
!-----------------------------------------------------------------------
instype(3):
! "START"
fault("ILLEGAL %START")
return
!-----------------------------------------------------------------------
instype(4):
! "RETURN"
if proctype(level) # 1 then fault("%RETURN OUT OF CONTEXT")
access = 0
dumpreturn
! DUMP("","LBRA","","R".S(RT(LEVEL)))
return
!-----------------------------------------------------------------------
instype(5):
! "RESULT"'='<expr>
if proctype(level) # 2 then fault("%RESULT OUT OF CONTEXT")
access = 0
expr(a(instrp + 1))
dumpreturn
! DUMP("","LBRA","","R".S(RT(LEVEL)))
return
!-----------------------------------------------------------------------
instype(6):
! "STOP"
access = 0
dump("", "SWI", "2", "")
! CALL MONITOR AND HALT?
return
instype(7):
access = 0
findcontinue(type, lab)
dump("", "LBRA", "", "L" . s(lab))
return
instype(8):
access = 0
findexit(type, lab)
dump("", "LBRA", "", "L" . s(lab))
return
instype(9):
! <OPCODE> # <CONST>
dump("", name(a(a(instrp + 1) + 1)), "", "#" . s(a(a(instrp + 2) + 1)))
return
instype(10):
! <OPCODE> <CONST>
dump("", name(a(a(instrp + 1) + 1)), "", s(a(a(instrp + 2) + 1)))
return
instype(11):
! <OPCODE> # <NAME>
namep = a(instrp + 2)
ident = a(namep + 1)
dump("", name(a(a(instrp + 1) + 1)), "", "#" . name(ident))
return
instype(12):
! <OPCODE> <NAME>
namep = a(instrp + 2)
ident = a(namep + 1)
nametag = tag(taglink(ident)) if taglink(ident) # 0
if taglink(ident) = 0 or nametag >> 28 = 4 start
dump("", name(a(a(instrp + 1) + 1)), "", name(ident))
finish else start
basep = nametag >> 16 & 15
disp = nametag & 16_FFFF
base = display(basep)
base = ",Y" if basep = level
base = ",X" if basep = 1
b1 = ""
b2 = ""
b1 = "[" and b2 = "]" if nametag >> 28 = 1
dump("", name(a(a(instrp + 1) + 1)), "", b1 . "-" . s(disp) . base . b2)
finish
return
instype(13):
! <OPCODE> <STRING>
begin
string (255) addr = ""
integer i, sym
i = 10
cycle
sym = a(i)
i = i + 1
exit if sym = 128
addr = addr . tostring(sym)
repeat
dump("", name(a(a(instrp + 1) + 1)), "", addr)
end
return
instype(14):
! <OPCODE>
dump("", name(a(a(instrp + 1) + 1)), "", "")
return
end
routine doloop(integer loopsp)
integer type, cyclab, cntlab, extlab, namep, actualp, forp, c
initp, incrp, finalp, tplabel, condp, whilep, disp, nametag
string (7) base, reg
switch cycle(1:3)
if a(loopsp) = 1 then type = 2 else type = 3
cyclab = nextplabel
cntlab = nextplabel
extlab = nextplabel
pushstart(type, cyclab)
-> cycle(a(loopsp))
cycle(1):
!FOR
forp = a(loopsp + 1)
namep = a(forp + 1)
actualp = a(forp + 2)
initp = a(forp + 3)
incrp = a(forp + 4)
finalp = a(forp + 5)
ident = a(namep + 1)
reg = "D"
!? %if taglink(ident)=0 %then fault(name(ident)." NOT DECLARED") %andreturn
if taglink(ident) = 0 then start
dump("", "LD", "D", "#" . name(ident))
finish else start
nametag = tag(taglink(ident))
if nametag >> 28 = 4 then start
fault("NOT A DESTINATION")
return
finish
if nametag >> 28 = 2 start
aopt = 1
array(forp)
finish else start
basep = nametag >> 16 & 16_F
base = display(basep)
disp = nametag & 16_FFFF
base = "Y" if basep = level
base = "X" if basep = 1
if nametag >> 28 = 1 then start
if 1 < basep < level then start
dump("", "LD", "D", base)
dump("", "SUB", "D", "#" . s(disp))
dump("", "ST", "D", "0,X")
dump("", "LD", "D", "[0,X]")
finish else start
dump("", "LD", "D", "-" . s(disp) . "," . base)
finish
finish else start
if 1 < basep < level then start
dump("", "LD", "D", base)
dump("", "SUB", "D", "#" . s(disp))
finish else start
if basep = 1 = level then start
dump("", "LEA", "Y", "-" . s(disp) . ",X")
reg = "Y"
finish else start
dump("", "TFR", "", base . ",D")
dump("", "SUB", "D", "#" . s(disp))
finish
finish
if a(actualp) = 1 then fault(name(ident) . " DECLARED AS SCALAR")
finish
finish
finish
dump("", "PSH", "U", reg)
expr(finalp)
dump("", "PSH", "U", "B")
expr(incrp)
dump("", "PSH", "U", "B")
expr(initp)
dump("", "SUB", "B", ",U")
dump("", "ST", "B", "[2,U]")
dump("L" . s(cyclab), "EQU", "", "*")
dump("", "LD", "B", "[2,U]")
dump("", "CMP", "B", "1,U")
dump("", "LBEQ", "", "L" . s(extlab))
dump("", "ADD", "B", ",U")
dump("", "ST", "B", "[2,U]")
return
cycle(*):
dump("L" . s(cyclab), "EQU", "", "*")
return if a(loopsp) # 2
whilep = a(loopsp + 1)
condp = a(whilep + 1)
tplabel = cond(condp, -1, extlab)
end
end
end of file