%EXTRINSICINTEGERARRAY A(1:255) %EXTRINSICINTEGERARRAY TAGLINK(0:255) %EXTRINSICINTEGERARRAY TAG(1:512) %EXTRINSICSTRING(4)%ARRAY DISPLAY(0:15) %EXTRINSICINTEGER LEVEL,CONDFLAG,EXPROPT !----------------------------------------------------------------------- %EXTERNALSTRING(255)%FNSPEC STRINT(%INTEGER N,P) %EXTERNALSTRING(8)%FNSPEC STRHEX(%INTEGER N) %EXTERNALROUTINESPEC FAULT(%STRING(63) S) %EXTERNALSTRING(255)%FNSPEC NAME(%INTEGER IDENT) %EXTERNALROUTINESPEC DUMP(%STRING(7) OPN,REG,BASE,%INTEGER DISP) %EXTERNALINTEGERFNSPEC GETWORK %EXTERNALROUTINESPEC RETURNWORK(%INTEGER WORK) %EXTERNALROUTINESPEC PROC(%INTEGER AP) %EXTERNALROUTINESPEC ARRAY(%INTEGER AP) %EXTERNALINTEGERFNSPEC GETCOTI(%INTEGER CONST) !----------------------------------------------------------------------- %EXTERNALROUTINE EXPR(%INTEGER EXPRP) %INTEGERFNSPEC TOTREE(%INTEGER EXPRP) %ROUTINESPEC EVALUATE(%INTEGER NODEP) %INTEGERARRAY TREE(1:64) %INTEGER TREEP,TREENODE,TREENODE1,TREENODE2,TESTP,EXPR1P,EXPR2P,COMPP,%C I,L %CONSTINTEGERARRAY REVERSECOMP(1:6)=1,2,5,6,3,4 TREEP=1 %IF CONDFLAG=0 %THEN TREENODE=TOTREE(EXPRP) %ELSE %START CONDFLAG=0 TESTP=EXPRP ;! FOR = EXPR1P=A(TESTP+1) COMPP=A(TESTP+2) EXPR2P=A(TESTP+3) TREENODE1=TOTREE(EXPR1P) TREENODE2=TOTREE(EXPR2P) %IF TREE(TREENODE1)=-4 %AND TREE(TREENODE1+1)=0 %THEN %START A(COMPP)=REVERSECOMP(A(COMPP)) TREENODE=TREENODE2 %FINISH %ELSE %START %IF TREE(TREENODE2)=-4 %AND TREE(TREENODE2+1)=0 %THEN %C TREENODE=TREENODE1 %ELSE %START TREE(TREEP)=10 ;! - TREE(TREEP+1)=TREENODE1 TREE(TREEP+2)=TREENODE2 TREENODE=TREEP %FINISH %FINISH %FINISH %IF EXPROPT=1 %THEN %START NEWLINE %IF 0>,&,!!,!,**,/,*,+,-,-(UNARY),\ UNARYP=A(EXPRP+1) OPERANDP=A(EXPRP+2) EXPRRESTP=A(EXPRP+3) %IF A(UNARYP)<=2 %THEN OS(1)=A(UNARYP)+10 %AND OSP=1 %ELSE OSP=0 PSP=0 %CYCLE ;! FOR EACH OPERAND %IF A(OPERANDP)=1 %THEN %START ;! NAMEP=A(OPERANDP+1) ACTUALP=A(OPERANDP+2) IDENT=A(NAMEP+1) %IF TAGLINK(IDENT)=0 %THEN %START FAULT(NAME(IDENT)." NOT DECLARED") PSEVAL(-3,0) ;! PSEVAL DUMMY TAG %FINISH %ELSE %START NAMETAG=TAG(TAGLINK(IDENT)) %IF NAMETAG>>28<=1 %THEN %START ;! SCALAR VARIABLE %IF A(ACTUALP)=1 %THEN %START FAULT("SCALAR ".NAME(IDENT)." HAS PARAMETER") PSEVAL(-3,0) %FINISH %ELSE PSEVAL(-3,NAMETAG) %FINISH %ELSE %START %IF NAMETAG>>28<=3 %THEN PSEVAL(-2,OPERANDP) %ELSE %START %IF NAMETAG>>24&X'F'=0 %THEN %START FAULT("ROUTINE NAME ".NAME(IDENT)." IN EXPRESSION") PSEVAL(-3,0) %FINISH %ELSE PSEVAL(-1,OPERANDP) %FINISH %FINISH %FINISH %FINISH %ELSE %START %IF A(OPERANDP)=2 %THEN PSEVAL(-4,A(A(OPERANDP+1)+1)) %ELSE %C PSP=PSP+1 %AND PS(PSP)=TOTREE(A(OPERANDP+1)) %FINISH %IF A(EXPRRESTP)=2 %THEN %EXIT ;! NO MORE OPERANDS OPP=A(EXPRRESTP+1) OPERANDP=A(EXPRRESTP+2) EXPRRESTP=A(EXPRRESTP+3) %WHILE OSP>0 %AND PREC(A(OPP))<=PREC(OS(OSP)) %THEN %C PSEVAL(OS(OSP),0) %AND OSP=OSP-1 ;! UNSTACK WHILE PREC(NEW OP)<= OSP=OSP+1 ;! STACK NEW OPERATOR OS(OSP)=A(OPP) %REPEAT %WHILE OSP>0 %THEN PSEVAL(OS(OSP),0) %AND OSP=OSP-1 ;! UNSTACK REST %RESULT=PS(1) !----------------------------------------------------------------------- %ROUTINE PSEVAL(%INTEGER TYPE,DATUM) %ROUTINESPEC STORE(%INTEGER T) %INTEGER NODEP NODEP=TREEP STORE(TYPE) %IF TYPE>0 %THEN %START ;! OPERATOR %IF TYPE>10 %THEN STORE(PS(PSP)) %ELSE STORE(PS(PSP-1)) %AND %C STORE(PS(PSP)) %AND PSP=PSP-1 %FINISH %ELSE STORE(DATUM) %AND PSP=PSP+1 PS(PSP)=NODEP !----------------------------------------------------------------------- %ROUTINE STORE(%INTEGER T) %IF TREEP>64 %THEN FAULT("EXPRESSION TOO LONG") %AND %STOP TREE(TREEP)=T TREEP=TREEP+1 %END %END %END !----------------------------------------------------------------------- %ROUTINE EVALUATE(%INTEGER NODEP) ! DUMP CODE TO EVALUATE EXPRESSION %ROUTINESPEC OPN(%INTEGER OP,P) %CONSTSTRING(4)%ARRAY STROP(0:12)="LOAD","SHL","SHR","AND","XOR","OR", "EXP","DIV","MLT","ADD","SUB","NEG","NOT" %CONSTINTEGERARRAY COMMUT(1:10)=0,0,1,1,1,0,0,1,1,0 %INTEGER OP,OPD1P,OPD2P,WORK %IF TREE(NODEP)<0 %THEN OPN(0,NODEP) %AND %RETURN ;! OPERAND OP=TREE(NODEP) OPD1P=TREE(NODEP+1) %IF OP>10 %THEN %START ;! UNARY OPERATOR %IF TREE(OPD1P)>=-2 %THEN EVALUATE(OPD1P) %ELSE OPN(0,OPD1P) DUMP(STROP(OP),"ACC","",0) %RETURN %FINISH OPD2P=TREE(NODEP+2) %IF TREE(OPD1P)>=-2 %THEN %START ;! OPERAND1 A NODE %IF TREE(OPD2P)>=-2 %THEN %START ;! OPERAND2 A NODE EVALUATE(OPD2P) WORK=GETWORK DUMP("STR","ACC",DISPLAY(LEVEL),WORK) EVALUATE(OPD1P) DUMP(STROP(OP),"ACC",DISPLAY(LEVEL),WORK) RETURNWORK(WORK) %FINISH %ELSE %START EVALUATE(OPD1P) OPN(OP,OPD2P) %FINISH %FINISH %ELSE %START %IF TREE(OPD2P)>=-2 %THEN %START EVALUATE(OPD2P) %IF COMMUT(OP)#0 %THEN OPN(OP,OPD1P) %AND %RETURN WORK=GETWORK DUMP("STR","ACC",DISPLAY(LEVEL),WORK) OPN(0,OPD1P) DUMP(STROP(OP),"ACC",DISPLAY(LEVEL),WORK) RETURNWORK(WORK) %FINISH %ELSE %START OPN(0,OPD1P) OPN(OP,OPD2P) %FINISH %FINISH %RETURN !----------------------------------------------------------------------- %ROUTINE OPN(%INTEGER OP,P) ! DUMP OBJECT CODE FOR SIMPLE OPERATION %STRING(7) BASE %INTEGER TYPE,DATUM,DISP TYPE=TREE(P) DATUM=TREE(P+1) %IF TYPE=-1 %THEN PROC(DATUM) %ELSE %START ;! PROCEDURE %IF TYPE=-2 %THEN %START ;! ARRAY ARRAY(DATUM) DUMP("LOAD","ACC","ACC",0) %FINISH %ELSE %START %IF TYPE=-3 %THEN %START ;! SCALAR BASE=DISPLAY(DATUM>>16&X'F') DISP=DATUM&X'FFFF' %IF DATUM>>28=1 %THEN %START ;! %NAME TYPE DUMP("LOAD","WK",BASE,DISP) DUMP(STROP(OP),"ACC","WK",0) %FINISH %ELSE DUMP(STROP(OP),"ACC",BASE,DISP) %FINISH %ELSE %START ;! CONSTANT %IF OP>0 %OR DATUM>X'FFFF' %THEN DUMP(STROP(OP),"ACC", %C "COT",GETCOTI(DATUM)) %ELSE DUMP("LDA","ACC","",DATUM) %FINISH %FINISH %FINISH %END %END %END %ENDOFFILE