;*********************************************************************** ; ; LANGUAGE FOR TUTORIAL COURSES ; UTILITIES. PART 2 ; CALCULATE THE ARITHMETIC EXPRESSIONS ; ; INPUT ; R1 = PTR TO EXPRESSION ( LEADING BLANKS ARE POSSIBLE ) ; ; OUTPUT ; R0 = TYPE OF RESULT ; R1 = PTR TO ANY SYMBOL AFTER THE EXPRESSION ; R2 = VALUE OF RESULT ; TYPE & RESULT ARE SAME AS RETURNED BY U.LEX ROUTINE ; ; GRAMMAR ; ::= [-] { (+!-) } ; ::= { (*!/!%) } ; ::= ! ! ! ! () ; ; ALL STRINGS ITEMS ARE CONVERTED TO INTEGER VALUE ; ; ALGORITHM ; TOP-TO-DOWN RECURSIVE ANALYSIS OF GRAMMAR ; REGISTERS' USAGE IN ANALYSIS ROUTINES ; R0 = TYPE OF ITEM ; R2 = VALUE OF ITEM ; R3 = OP CODE ; R4 = WORK ; .ENABL GBL ; OPERATION CODES OP.PL = 0. ; "+" - ADDITION OP.MN = 2. ; "-" - SUBSTRACTION OP.MU = 4. ; "*" - MULTIPLICATION OP.DV = 6. ; "/" - INTEGER DIVISION OP.MD = 8. ; "%" - OBTAINING THE REMAINDER FROM DIVSN .PAGE ;---------------------------------------------------------------------- ; ; ANALYSIS OF UA.EXPR:: MOV R3,-(SP) MOV R4,-(SP) 10$: MOVB (R1)+,R4 CMPB R4,#' BEQ 10$ ; SCAN THE LEADING BLANKS MOV PC,R3 ; R3 /= 0 - FLAG OF UNARY MINUS CMPB R4,#'- BEQ 20$ ; LEADING MINUS IS FOUND CLR R3 ; ELSE RESET THE FLAG - UNARY MINUS DEC R1 ; R1 POINTS TO THE 1. NOTBLANK 20$: CALL UA.TERM ; ANALYSIS OF THE 1. TERM TST R3 BEQ ELOOP ; NO LEADING MINUS CALL UA.NUM ; ELSE CONVERT THE TERM TO INTEGER NEG R2 ; TYPE & NEGATE THE ITS VALUE ELOOP: ; THE MAIN LOOP - SEARCH FOR "+" OR "-" MOVB (R1)+,R4 CMPB R4,#' BEQ ELOOP ; SCAN THE LEADING BLANKS MOV #OP.PL,R3 ; SET CODE FOR PLUS OP CMPB R4,#'+ BEQ ENXT MOV #OP.MN,R3 ; SET CODE FOR MINUS OP CMPB R4,#'- BNE EEX ; NO NEXT TERM - EXIT ENXT: ; NEXT TERM IS FOUND CALL UA.NUM ; CONVERT THE 1. OPERAND TO NUMERICAL MOV R2,-(SP) ; FORM & PUSH IT IN STACK CALL UA.TERM ; ANALYSIS OF NEXT TERM CALL UA.NUM ; CONVERT IT TO NUMERICAL FORM CALL UA.OP ; DO THE OPERATION AT OPERANDS BR ELOOP ; AND CONTINUE EEX: ; END OF EXPRESSION REACHED DEC R1 ; R1 POINTS TO ENDING SYMBOL MOV (SP)+,R4 MOV (SP)+,R3 RETURN .PAGE ;---------------------------------------------------------------------- ; ; ANALYSIS OF UA.TERM: MOV R3,-(SP) MOV R4,-(SP) CALL UA.FACT ; GET THE 1. OPERAND TLOOP: ; THE MAIN LOOP - SEARCH FOR "*", "/", "%" MOVB (R1)+,R4 CMPB R4,#' BEQ TLOOP ; SCAN THE LEADING BLANKS MOV #OP.MU,R3 ; SET CODE FOR MULTIP OP CMPB R4,#'* BEQ TNXT MOV #OP.DV,R3 ; SET CODE FOR DIV OP CMPB R4,#'/ BEQ TNXT MOV #OP.MD,R3 ; SET CODE FOR MOD OP CMPB R4,#'% BNE TEX ; NO NEXT FACTOR - EXIT TNXT: ; NEXT FACTOR IS FOUND CALL UA.NUM ; CONVERT THE 1. OPERAND TO NUMERICAL MOV R2,-(SP) ; FORM & PUSH IT IN STACK CALL UA.FACT ; ANALYSIS OF NEXT FACTOR CALL UA.NUM ; CONVERT IT TO NUMERICAL FORM CALL UA.OP ; DO THE OPERATION AT OPERANDS BR TLOOP ; AND CONTINUE TEX: ; END OF TERM REACHED DEC R1 ; R1 POINTS TO ENDING SYMBOL MOV (SP)+,R4 MOV (SP)+,R3 RETURN .PAGE ;---------------------------------------------------------------------- ; ; ANALYSIS OF UA.FACT: CALL U.LEX ; GET THE LEXEM CMP R0,#TY.UN BNE FEX ; ANY TYPE ALLOWED - EXIT CMPB (R1)+,#'( BNE ERR ; SYNTAX ERROR CALL UA.EXP ; ANALYSIS OF EXPR IN BRACES CMPB (R1)+,#') BEQ FEX ; CLOSE BRACE IS PRESENT - OK ERR: CALL ERROR .WORD 11. ; SYNTAX ERROR FEX: RETURN ;---------------------------------------------------------------------- ; ; CONVERT THE VALUE OF ITEM TO NUMERICAL FORM ; ; INPUT ; R0 = TYPE OF ITEM ; R2 = VALUE OF ITEM ; OUTPUT ; R0 = TY.IC ; R2 = INTEGER NUMBER - NUMERICAL VALUE OF ITEM UA.NUM:: CMP R0,#TY.IC BEQ NEX ; R2 HAS THE INTEGER CONSTANT YET CMP R0,#TY.IV BNE 10$ MOV @R2,R2 ; GET A VALUE OF INTEGER VARIABLE BR NEX 10$: MOV R1,-(SP) MOV R2,R1 ; CONVERT THE STRING VAR OR CONSTANT CALL UU.DEC ; TO NUMERICAL FORM MOV R0,R2 ; SET THE ANSWER MOV (SP)+,R1 NEX: MOV #TY.IC,R0 ; SET THE TYPE - INTEGER CONSTANT RETURN .PAGE ;-------------------------------------------------------------------------- ; ; CALL FOR THE OPERATION EXECUTORS ; R3 = INDEX OF OPERATION NEEDED, ; @SP = RETURN ADDR UA.OP: MOV 2(SP),R4 ; SWAB TWO WORDS (RETURN ADDR AND MOV @SP,2(SP) ; PTR TO 1. OPERAND) AT THE STACK MOV R4,@SP ; TOP ADD PC,R3 ADD #,R3 ; R3 = PTR TO CORRESP ENTRY IN TABLE ADD @R3,R3 ; R3 = ABSOLUTE PTR TO EXECUTORS JMP @R3 ; BRANCH TO EXECUTOR T.OP: .WORD OPPL-. ; PLUS .WORD OPMN-. ; MINUS .WORD OPMU-. ; MULTIPLY .WORD OPDV-. ; DIVIDE .WORD OPMD-. ; MOD ;========================================================================== ; ; OPERATION EXECUTORS ; ; INPUT ; @SP = 1. OPERAND ; R2 = 2. OPERAND - ALL IN NUMERICAL FORM ; R0 = TY.IC ; OUTPUT ; R2 = VALUE OF OPERATION ; R0 = TY.IC - TYPE OF RESULT ; R3,R4 = MAY BE NOT RESTORED ; STACK LEVEL IS RESTORED OPPL: ; ADDITION ADD (SP)+,R2 RETURN OPMN: ; SUBSTRACTION SUB (SP)+,R2 NEG R2 RETURN OPMU: ; MULTIPLICATION MOV (SP)+,R3 ; 1. MULTIPLICAND BEQ OPZERO ; ZERO RESULT BPL 10$ ; DO IT POSITIVE, NEG R3 ; CHANGE SIGNS IF NEEDED NEG R2 10$: CLR R4 ; CLEAR THE ACCUMULATOR 20$: ADD R2,R4 SOB R3,20$ ; ACCUMULATE THE PRODUCT MOV R4,R2 ; SET THE RESULT RETURN OPZERO: ; ZERO RESULT CLR R2 RETURN .PAGE OPDV: ; DIVISION MOV (SP)+,R3 ; DIVISAND BEQ OPZERO ; ZERO RESULT BPL 10$ ; DO IT POSITIVE, NEG R3 ; CHANGE SIGNS IF NEEDED NEG R2 10$: CLR -(SP) ; NULL - FLAG OF POSITIVE RESULT MOV R2,R4 ; LOAD THE DIVISOR BEQ ERR ; DIVIDING BY 0 BPL 20$ NEG R4 ; NEGATE THE DIVISOR INC @SP ; AND SET FLAG OF NEGATIVE RESULT 20$: CLR R2 ; CLEAR THE QUOTIENT ACCUMULATOR 30$: SUB R4,R3 ; DIVIDE BY SEQUENTIAL SUBTRACTIONS BLT 40$ INC R2 BR 30$ 40$: TST (SP)+ ; SET THE TRUE SIGN OF QUOTIENT BEQ 50$ ; NULL - FLAG OF POSITIVE NUMBER NEG R2 50$: RETURN OPMD: ; OBTAIN THE REMAINDER MOV R2,R3 ; LOAD THE DIVISOR BEQ ERR ; DIVIDING BY 0 BPL 10$ ; DO IT POSITIVE, NEG R3 ; CHANGE SIGNS IF NEEDED NEG @SP 10$: CLR R4 ; NULL - FLAG OF POSITIVE RESULT MOV (SP)+,R2 ; LOAD THE DIVISAND BEQ OPZERO ; ZERO RESULT BPL 20$ NEG R2 ; NEGATE THE DIVISAND INC R4 ; AND SET FLAG OF NEGATIVE RESULT 20$: SUB R3,R2 ; DIVIDE BY SEQUENTIAL SUBTRACTIONS BEQ 30$ ; EXIT IF ZERO REMAINDER BGT 20$ ADD R3,R2 TST R4 ; NOTE THAT REMAINDER IS ALWAYS >=0 BEQ 30$ ; NULL - FLAG OF POSITIVE NUMBER SUB R3,R2 NEG R2 30$: RETURN .END