'=========================================================================== ' Subject: EXPRESSION EVALUATOR Date: 07-09-97 (17:41) ' Author: Ian Pitt Code: VBDOS ' Origin: IanPitt@worldnet.att.net Packet: ALGOR.ABC '=========================================================================== DECLARE SUB pusho (op() AS STRING * 1, operator$) DECLARE FUNCTION popn! (ops!()) DECLARE FUNCTION popo$ (op() AS STRING * 1) DECLARE FUNCTION peekat$ (op() AS STRING * 1) DECLARE SUB pushn (ops!(), op!) DECLARE SUB parse (expression$) DECLARE FUNCTION evaluate! (expression$) 'Programmer: Ian Pitt 'Date: 7/9/1997 'Email: IanPitt@bigfoot.com 'Program Name: The Evaluator 'Purpose: Gets a mathematical expression from the user and parse it then ' evaluates it. 'NOTE: If you need any explanation contact me at the above email address. ' Or if you find the code particularly helpful in any way please let ' me know as it encourages me to do more. DEFINT A-Z CONST true = -1, false = NOT true 'Print welcoming message and instructions CLS PRINT "WELCOME TO THE EVALUATOR" PRINT : PRINT PRINT "The following are examples of legal expressions:-" PRINT " 2 + 2 Result is 4" PRINT " 2 - 2 Result is 0" PRINT " 2 * 2 Result is 4" PRINT " 2 / 2 Result is 1" PRINT " 2 ^ 2 Result is 4 NOTE: ie 2 raised to the power 2" PRINT " 3+(4*(-3+2*34)+2)^2 Result is 68647" PRINT PRINT "You may type 'QUIT' at any time to quit the program" PRINT DO WHILE UCASE$(expression$) <> "QUIT" INPUT "Enter expression to evaluate: ", expression$ 'expression$ = "3+(4*(-3+2*34)+2)^2" PRINT " Expression = "; expression$ parse expression$ PRINT expression$; " After parsing" value! = evaluate(expression$) PRINT value! 'expression$ = "quit" LOOP END FUNCTION evaluate! (expression$) DIM operands!(20), operators(10) AS STRING * 1 lexpression = LEN(expression$) hierarchy$ = "^*/+-()" operands!(0) = 0 'clears operands stack operators(0) = CHR$(0) 'clears operators stack 'pushn operands!(), 0 'seeds stack with 0 symbolstart = 1 DO symbolend = INSTR(symbolstart, expression$, " ") IF symbolend <= 0 THEN symbolend = lexpression + 1 symbol$ = UCASE$(MID$(expression$, symbolstart, symbolend - symbolstart)) symbolpos = INSTR(hierarchy$, symbol$) IF symbolpos > 0 THEN 'this is an operator symbolonstack$ = peekat$(operators()) IF INSTR(hierarchy$, symbolonstack$) > symbolpos OR symbolonstack$ = "" OR symbol$ = "(" THEN pusho operators(), symbol$ ELSEIF symbol$ = ")" THEN DO symbolonstack$ = popo$(operators()) IF INSTR("^*/+-", symbolonstack$) > 0 THEN op2! = popn(operands!()) op1! = popn(operands!()) END IF SELECT CASE symbolonstack$ CASE "^": pushn operands!(), op1! ^ op2! CASE "*": pushn operands!(), op1! * op2! CASE "/": pushn operands!(), op1! / op2! CASE "+": pushn operands!(), op1! + op2! CASE "-": pushn operands!(), op1! - op2! END SELECT LOOP WHILE symbolonstack$ <> "(" ELSE symbolonstack$ = popo$(operators()) IF INSTR("^*/+-", symbolonstack$) > 0 THEN op2! = popn(operands!()) op1! = popn(operands!()) END IF SELECT CASE symbolonstack$ CASE "^": pushn operands!(), op1! ^ op2! CASE "*": pushn operands!(), op1! * op2! CASE "/": pushn operands!(), op1! / op2! CASE "+": pushn operands!(), op1! + op2! CASE "-": pushn operands!(), op1! - op2! CASE "(": pusho operators(), symbol$ END SELECT pusho operators(), symbol$ END IF ELSE pushn operands!(), VAL(symbol$) END IF symbolstart = symbolend + 1 LOOP WHILE symbolend < lexpression DO WHILE ASC(operators(0)) symbolonstack$ = popo$(operators()) IF INSTR("^*/+-", symbolonstack$) > 0 THEN op2! = popn(operands!()) op1! = popn(operands!()) END IF SELECT CASE symbolonstack$ CASE "^": pushn operands!(), op1! ^ op2! CASE "*": pushn operands!(), op1! * op2! CASE "/": pushn operands!(), op1! / op2! CASE "+": pushn operands!(), op1! + op2! CASE "-": pushn operands!(), op1! - op2! END SELECT LOOP evaluate! = popn(operands!()) END FUNCTION SUB parse (expression$) lexpression = LEN(expression$) WasOperator = true FOR ct = 1 TO lexpression ch$ = MID$(expression$, ct, 1) SELECT CASE ch$ CASE " " CASE "(" texpression$ = texpression$ + ch$ + " " WasOperator = true CASE ")" texpression$ = texpression$ + " " + ch$ WasOperator = false CASE "+", "-", "*", "/", "^" IF NOT WasOperator THEN texpression$ = texpression$ + " " + ch$ + " " ELSE texpression$ = texpression$ + ch$ END IF WasOperator = NOT WasOperator CASE ELSE texpression$ = texpression$ + ch$ WasOperator = false END SELECT NEXT expression$ = texpression$ END SUB FUNCTION peekat$ (op() AS STRING * 1) ct = ASC(op(0)) IF ct THEN peekat$ = op(ct) ELSE peekat$ = "" END FUNCTION FUNCTION popn! (ops!()) popn! = ops!(ops!(0)) ops!(0) = ops!(0) - 1 END FUNCTION FUNCTION popo$ (op() AS STRING * 1) ct = ASC(op(0)) popo$ = op(ct) ct = ct - 1 op(0) = CHR$(ct) END FUNCTION SUB pushn (ops!(), op!) ops!(0) = ops!(0) + 1 ops!(ops!(0)) = op! END SUB SUB pusho (op() AS STRING * 1, operator$) ct = ASC(op(0)) ct = ct + 1 op(0) = CHR$(ct) op(ct) = operator$ END SUB