%begin; ! 82S101 FPLA Simulator

%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 and(0:15,0:47),or(0:47,0:15),invert(0:7)

%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
%integer i,j,k,sym
  selectinput(1)
  invert(i)=0 %for i=0,1,7
  %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=0
        %finishelseif sym='1' %start
          sym=1
        %finishelseif sym='?' %start
          sym=2
        %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
        %else
          invert(j)=1 %if sym=0
        %finish
      %repeat
      readsymbol(sym); moan(sym,"NL") %unless sym=nl
      %exitif k&95='O'
    %repeat
  %repeat
%end

%routine simulate
%integerarray in(0:15),term(0:47),out(0:7)
%integer input,output,i,j,k

  %integerfn function(%integer input)
  %integer output
    in(i)=input>>(15-i)&1 %for i=0,1,15
    %for i=0,1,47 %cycle
      term(i)=1
      %for j=0,1,15 %cycle
        k=and(j,i)
        term(i)=0 %andexitif k=3 %or k!!in(j)=1
      %repeat
    %repeat
    output=0
    %for j=0,1,7 %cycle
      out(j)=0
      %for i=0,1,47 %cycle
        out(j)=1 %andexitif or(i,j)&term(i)=1
      %repeat
      output=output!(out(j)!!invert(j))<<(15-j)
    %repeat
    %result=output
  %end

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

  %cycle
    input=switches; output=function(input)
    display(input); display(output)
    %if attention %start
      newline; printstring("Inputs:  ")
      printsymbol(in(i)+'0') %for i=0,1,15
      newline; printstring("Terms:   ")
      printsymbol(term(i)+'0') %for i=0,1,47
      newline; printstring("Outputs: ")
      printsymbol(out(i)+'0') %for i=0,1,7
      newline
    %finish
  %repeat
%end

%onevent 9 %start
  simulate
%finish

read matrices

%endofprogram
