!Graham Toal - latest development version of SKIMPC 23/01/80 16.41
external integer array spec a(1 : 500)
external integer spec condopt
!-----------------------------------------------------------------------
external routine spec expr(integer exprp)
external routine spec dump(string (7) lab, op, reg, addr)
external routine spec filllabel(integer label)
external integer fn spec fillbranch(integer label)
external integer fn spec nextplabel
external routine spec fault(string (63) mess)
external string (7) fn spec s(integer i)
!-----------------------------------------------------------------------
external integer condflag = 0
!-----------------------------------------------------------------------
external integer fn cond(integer condp, tlabel, flabel)
routine spec processcond(integer condp)
routine spec test(integer ltestp)
routine spec condrest(integer condrestp)
routine spec store(integer testp, level, andor)
routine spec show(string (7) an, integer array name a, integer p)
const string (4) array true(1 : 6) = c
"LBEQ", "LBNE", "LBLE", "LBLT", "LBGE", "LBGT"
const string (4) array false(1 : 6) = c
"LBNE", "LBEQ", "LBGT", "LBGE", "LBLT", "LBLE"
string (4) opn
const integer array index(1 : 17) = c
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
integer array testpa, levela, andora, brancha(1 : 16), labela(1 : 17)
integer p, pp, ppp, testp, level, andor, comp
level = 0
p = 1
processcond(condp)
store(testp, -1, 1)
! pseudo-%and
store(0, -2, 2)
! pseudo-%or
p = p - 2
for pp = 1, 1, p cycle
! find branch destinations
level = levela(pp)
andor = andora(pp)
for ppp = pp + 1, 1, p + 1 cycle
if levela(ppp) < level then start
level = levela(ppp)
if andora(ppp) # andor then exit
finish
repeat
brancha(pp) = ppp + 1
repeat
if tlabel >= 0 then start
andora(p) = 2
! change last branch to branch on true
brancha(p) = p + 1
labela(p + 1) = tlabel
finish
labela(p + 2) = flabel
for pp = 1, 1, p cycle
! assign private labels where needed
if labela(brancha(pp)) < 0 then labela(brancha(pp)) = nextplabel
repeat
if condopt = 1 then start
newline
show(" ", index, p + 2)
show("TESTP ", testpa, p)
show("LEVEL ", levela, p + 1)
show("ANDOR ", andora, p + 1)
show("BRANCH", brancha, p)
show("LABEL ", labela, p + 2)
newline
finish
for pp = 1, 1, p cycle
! generate test code and fill labels
if labela(pp) >= 0 then filllabel(labela(pp))
condflag = 1
expr(testpa(pp))
comp = a(a(testpa(pp) + 2))
if andora(pp) = 1 then opn = false(comp) else opn = true(comp)
dump("", opn, "", "L" . s(labela(brancha(pp))))
repeat
if labela(p + 1) >= 0 and tlabel < 0 then filllabel(labela(p + 1))
if flabel >= 0 then result = -1 else result = labela(p + 2)
!-----------------------------------------------------------------------
routine processcond(integer condp)
test(a(condp + 1))
condrest(a(condp + 2))
end
!-----------------------------------------------------------------------
routine test(integer ltestp)
if a(ltestp) = 1 then testp = ltestp c
else level = level + 1 and processcond(a(ltestp + 1)) and level = level - 1
end
!-----------------------------------------------------------------------
routine condrest(integer condrestp)
integer andor
andor = a(condrestp)
unless andor = 3 then start
store(testp, level, andor) and test(a(condrestp + 1)) and c
condrestp = a(condrestp + 2) until a(condrestp) = 2
finish
end
!-----------------------------------------------------------------------
routine store(integer testp, level, andor)
if p > 16 then fault("CONDITION TOO LONG") and stop
testpa(p) = testp
levela(p) = level
andora(p) = andor
labela(p) = -1
p = p + 1
end
!-----------------------------------------------------------------------
routine show(string (7) an, integer array name a, integer p)
integer pp
printstring(an . " ")
for pp = 1, 1, p cycle
write(a(pp), 5)
repeat
newline
end
end
end of file