RosettaCodeData/Task/Arithmetic-evaluation/BBC-BASIC/arithmetic-evaluation.basic

59 lines
1.4 KiB
Plaintext

Expr$ = "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
PRINT "Input = " Expr$
AST$ = FNast(Expr$)
PRINT "AST = " AST$
PRINT "Value = " ;EVAL(AST$)
END
DEF FNast(RETURN in$)
LOCAL ast$, oper$
REPEAT
ast$ += FNast1(in$)
WHILE ASC(in$)=32 in$ = MID$(in$,2) : ENDWHILE
oper$ = LEFT$(in$,1)
IF oper$="+" OR oper$="-" THEN
ast$ += oper$
in$ = MID$(in$,2)
ELSE
EXIT REPEAT
ENDIF
UNTIL FALSE
= "(" + ast$ + ")"
DEF FNast1(RETURN in$)
LOCAL ast$, oper$
REPEAT
ast$ += FNast2(in$)
WHILE ASC(in$)=32 in$ = MID$(in$,2) : ENDWHILE
oper$ = LEFT$(in$,1)
IF oper$="*" OR oper$="/" THEN
ast$ += oper$
in$ = MID$(in$,2)
ELSE
EXIT REPEAT
ENDIF
UNTIL FALSE
= "(" + ast$ + ")"
DEF FNast2(RETURN in$)
LOCAL ast$
WHILE ASC(in$)=32 in$ = MID$(in$,2) : ENDWHILE
IF ASC(in$)<>40 THEN = FNnumber(in$)
in$ = MID$(in$,2)
ast$ = FNast(in$)
in$ = MID$(in$,2)
= ast$
DEF FNnumber(RETURN in$)
LOCAL ch$, num$
REPEAT
ch$ = LEFT$(in$,1)
IF INSTR("0123456789.", ch$) THEN
num$ += ch$
in$ = MID$(in$,2)
ELSE
EXIT REPEAT
ENDIF
UNTIL FALSE
= num$