'=========================================================================== ' Subject: EXPRESSION EVALUATOR Date: 04-14-96 (10:55) ' Author: Christopher Pinder Code: PB ' Origin: comp.lang.basic.misc Packet: ALGOR.ABC '=========================================================================== ' POWER BASIC SOURCE ' A Recusive Descent Bracket Thingy to mess with parenthesized? ' Expressions. This is a bodged version in BASIC of the code given ' in Bjarne Stroustrup's The C++ Programming Language with the ' Symbol Table Stuff stripped out. ' Very little error checking etc... but it works (Famous last words) ' Probably got more bugs than three year old yogurt but hey ! ' I'm not too sure how copyright would go regarding a bit of code ' translated from a book into another language so I won't donate it ' cos I might not have the right. But I wrote this version and I don't ' care wot happens to it. %NUMBER = 1 %END = 3 %PLUS = 4 %MINUS = 5 %MUL = 6 %DIV = 7 %LP = 8 %RP = 9 shared EVAL$ shared n$,v shared currenttoken% FUNCTION GetToken% shared n$,v shared EVAL$ shared currenttoken% static state% static curpos% if state% = 0 then curpos% = 1:n$="" 'yeuch ! NUM$="0123456789." OPER$="+-*/=()~!@" WHITE$=" "+chr$(8) 'Skip whitespace x$=mid$(EVAL$,curpos%,1) l% = len(EVAL$) while (((instr(WHITE$,x$)) and (curpos%= l% then currenttoken% = %END: state% = 0: exit function end if state% = 1: dp% = 0: zz$="" 'do the numbers first if(instr(NUM$,x$)>0)then while ((instr(NUM$,x$)>0) and_ (instr(WHITE$,x$)=0) and_ (instr(OPER$,x$)=0) and_ (dp% < 2)) if x$="." then incr dp%: if dp% = 2 then exit function: zz$ =zz$+ x$ if curpos% < l% then incr curpos% x$ = mid$(EVAL$,curpos%,1) end if wend v = val(zz$) currenttoken% = %NUMBER: exit function: end if if instr(OPER$,x$) then incr curpos% select case x$: case "+":currenttoken% = %PLUS case "-":currenttoken% = %MINUS case "*":currenttoken% = %MUL case "/":currenttoken% = %DIV case "(":currenttoken% = %LP case ")":currenttoken% = %RP case else currenttoken% = %END: end select exit function end if end function: function expr shared n$,v: shared currenttoken% local myleft myleft = term while 1 select case currenttoken% case %PLUS GetToken% myleft = myleft+term:iterate case %MINUS GetToken% myleft = myleft-term:iterate case else expr = myleft: exit function: end select wend end function function term shared n$,v: local myleft myleft = prim while 1 select case currenttoken% case %MUL GetToken% myleft = myleft * prim: iterate case %DIV GetToken% d = prim : if d = 0.00 then d = 1 myleft = myleft / d: iterate case else term = myleft:exit function: end select wend end function function prim shared n$,v: select case currenttoken% case %NUMBER prim = v GetToken% case %LP GetToken% e = expr if(currenttoken% <> %RP) then prim = 0: print "Mismatched Parenthesis" exit function end if GetToken% prim = e:exit function: case %MINUS GetToken% prim = - prim: exit function case %END prim = 0: end select end function: Function Evaluate(p$) shared EVAL$ EVAL$=p$+" " 'cos we read ahead - tacky I know ! GetToken% Evaluate = expr! end function '---------------------------------------------------------------------- ' And now - to eat the pudding ! '---------------------------------------------------------------------- cls print "input or ! to end" while a$ <> "!" a$ ="" input a$ ? a$ " = " ; evaluate(a$) wend