begin ; ! 82S101 FPLA Simulator (Fast version)

externalintegerfnspec  switches
externalroutinespec  display(integer  a)

predicate  attention
integer  z
  *16_e1fb; *16_4000; *0
  z=integer(0); falseif  z=0
  stopif  switches=16_76
  true 
end 

integerarray  amask1,amask0(0:47),omask(0:23)
integer  inv

routine  moan(integer  offender,string (63)would have liked)
  selectoutput(0)
  printstring("Encountered '"); printsymbol(offender)
  printstring("' when expecting "); printstring(would have liked)
  newline; stop 
end 

routine  read matrices
integerarray  and(0:15,0:47),or(0:47,0:7),invert(0:7)
integer  i,j,k,sym
integername  w
  selectinput(1)
  invert(i)=0 for  i=0,1,7; inv=0
  cycle 
    readsymbol(k); signal  9 if  k='*'
    moan(k,"& or ! or O or *") unless  k='&' or  k='!' or  k&95='O'
    readsymbol(sym); moan(sym,"NL") unless  sym=nl
    for  i=0,1,47 cycle 
      for  j=0,1,15 cycle 
        exitif  j=8 and  k#'&'
        readsymbol(sym)
        if  sym='0' start 
          sym=2
        finishelseif  sym='1' start 
          sym=1
        finishelseif  sym='?' start 
          sym=0
        finishelseif  sym&95='X' start 
          sym=3
        finishelse  moan(sym,"0 or 1 or ? or X")
        if  k='&' start 
          and(j,i)=sym
        finishelseif  k='!' start 
          or(i,j)=sym&1
        else 
          invert(j)=1 and  inv=inv!!(1<<j) if  sym=2
        finish 
      repeat 
      readsymbol(sym); moan(sym,"NL") unless  sym=nl
      exitif  k&95='O'
    repeat 
    if  k='&' start 
      for  i=0,1,47 cycle 
        amask1(i)=0; amask0(i)=0
        for  j=0,1,15 cycle 
          k=and(j,i)
          amask1(i)=amask1(i)+1<<j if  k&1#0
          amask0(i)=amask0(i)+1<<j if  k&2#0
        repeat 
      repeat 
    elseif  k='!' start 
      omask(i)=0 for  i=0,1,23
      for  i=0,1,47 cycle 
        for  j=0,1,7 cycle 
          w==omask(j+j+j+i>>4)
          w=w!!1<<(i&15) if  or(i,j)#0
        repeat 
      repeat 
    finish 
  repeat 
end 

routine  simulate
integer  input,output,i,j,k

  integerfn  function(integer  input)
  integerarray  term(0:2)
  integername  w
  integer  i,j,o
    term(i)=0 for  i=0,1,2
    for  i=0,1,47 cycle 
      if  input&amask0(i) ! (¬input)&amask1(i) # 0 start 
        w==term(i>>4); w=w!!1<<(i&15)
      finish 
    repeat 
    o=0
    for  i=0,1,7 cycle 
      j=i*3
      if  omask(j)  &term(0)#0 c 
      or  omask(j+1)&term(1)#0 c 
      or  omask(j+2)&term(2)#0 then  o=o!!1<<i
    repeat 
    result =o!!inv
  end 

  display(-1); display(-1); input=switches
  while  input=switches cycle ; repeat 

  cycle 
    input=switches; display(input); display(-1)
    output=function(input); display(-1); display(output)
    if  attention start 
      newline; printstring("Inputs: ")
      printsymbol(input>>i&1+'0') for  i=15,-1,0
      newline; printstring("Outputs: ")
      printsymbol(output>>i&1+'0') for  i=7,-1,0
      newline
    finish 
  repeat 
end 

onevent  9 start 
  simulate
finish 

read matrices

endofprogram