' This program based on https://rosettacode.org/wiki/Arithmetic_evaluation#BBC_BASIC
'
' ๐ FUNCTION DECLARATIONS
declare function fNast$()
declare function fNast1$()
declare function fNast2$()
declare function fNumber$()
' ๐ MAIN PROGRAM
Expr$ = "1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
'Expr$ = "(1 + 2) * 3"
PRINT "Input = " + Expr$
print "fNast$ = " + fNast$()
'AST$ = fNast$()
'PRINT "AST = " + AST$
'PRINT "Value = " ;EVAL(AST$)
END
'
' ๐ FUNCTION DEFINITIONS
function fNast$()
dim ast$, oper$ as string
ast$ = ""
fNast_repeat:
ast$ += FNast1$()
WHILE ASC(Expr$)=32
Expr$ = MID$(Expr$,2,len(Expr$)-1)
wend
oper$ = LEFT$(Expr$,1)
IF oper$="+" OR oper$="-" THEN
ast$ += oper$
Expr$ = MID$(Expr$,2,len(Expr$)-1)
goto fNast_repeat
end if
fNast$ = "(" + ast$ + ")"
end function
function fNast1$()
dim ast$, oper$ as string
ast$ = ""
fNast1_repeat:
ast$ += fNast2$()
WHILE ASC(Expr$)=32
Expr$ = MID$(Expr$,2,len(Expr$)-1)
wend
oper$ = LEFT$(Expr$,1)
IF oper$="*" OR oper$="/" THEN
ast$ += oper$
Expr$ = MID$(Expr$,2,len(Expr$)-1)
goto fNast1_repeat
end if
fNast1$ = "(" + ast$ + ")"
end function
function fNast2$()
dim ast$ as string
WHILE ASC(Expr$)=32
Expr$ = MID$(Expr$,2,len(Expr$)-1)
wend
IF ASC(Expr$)=40 THEN
Expr$ = MID$(Expr$, 2, len(Expr$)-1)
ast$ = fNast$()
Expr$ = MID$(Expr$,2, len(Expr$)-1)
ELSE
ast$ = fNumber$()
end if
fNast2$ = ast$
end function
function fNumber$()
dim ch$, num$ as string
num$ = ""
fNumber_repeat:
ch$ = left$(Expr$, 1)
' ๐จ wwwBASIC: issues with instr breaking app when the character is a parenthesis
if ch$ <> "" and instr("0123456789.", ch$) then
num$ += ch$
Expr$ = mid$(Expr$,2,len(Expr$)-1)
goto fNumber_repeat
end if
fNumber$ = num$
end function