86 lines
1.7 KiB
Plaintext
86 lines
1.7 KiB
Plaintext
Module CheckAst {
|
|
class EvalAst {
|
|
private:
|
|
Function Ast(&in$) {
|
|
object Ast=stack, op=stack
|
|
Do
|
|
stack Ast {stack .Ast1(&in$)}
|
|
in$=Trim$(in$)
|
|
oper$=left$(in$,1)
|
|
if Instr("+-", oper$)>0 else exit
|
|
if len(oper$)>0 then stack op {push oper$}
|
|
in$=Mid$(in$, 2)
|
|
until len(in$)=0
|
|
stack Ast {stack op} // dump op to end of stack Ast
|
|
=Ast
|
|
}
|
|
Function Ast1(&in$) {
|
|
object Ast=stack, op=stack
|
|
Do
|
|
stack Ast {stack .Ast2(&in$)}
|
|
in$=Trim$(in$)
|
|
oper$=left$(in$,1)
|
|
if Instr("*/", oper$)>0 else exit
|
|
if len(oper$)>0 then stack op {push oper$}
|
|
in$=Mid$(in$, 2)
|
|
until len(in$)=0
|
|
stack Ast {stack op}
|
|
=Ast
|
|
}
|
|
Function Ast2(&in$) {
|
|
in$=Trim$(in$)
|
|
if Asc(in$)<>40 then =.GetNumber(&in$) : exit
|
|
in$=Mid$(in$, 2)
|
|
=.Ast(&in$)
|
|
in$=Mid$(in$, 2)
|
|
}
|
|
Function GetNumber (&in$) {
|
|
Def ch$, num$
|
|
Do
|
|
ch$=left$(in$,1)
|
|
if instr("0123456789", ch$)>0 else exit
|
|
num$+=ch$
|
|
in$=Mid$(in$, 2)
|
|
until len(in$)=0
|
|
=stack:=val(num$)
|
|
}
|
|
public:
|
|
value () {
|
|
=.Ast(![])
|
|
}
|
|
}
|
|
Ast=EvalAst()
|
|
Expr$ = "1+2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10"
|
|
// Expr$="1/2+(4-3)/2+1/2"
|
|
print "Result through eval$:";eval(Expr$)
|
|
print "Expr :";Expr$
|
|
mres=Ast(&Expr$)
|
|
print "RPN :";array(stack(mres))#str$()
|
|
reg=stack
|
|
stack mres {
|
|
while not empty
|
|
if islet then
|
|
read op$
|
|
stack reg {
|
|
select case op$
|
|
case "+"
|
|
push number+number
|
|
case "-"
|
|
shift 2:push number-number
|
|
case "*"
|
|
push number*number
|
|
case "/"
|
|
shift 2:push number/number // shif 2 swap top 2 values
|
|
end select
|
|
}
|
|
else
|
|
read v
|
|
stack reg {push v}
|
|
end if
|
|
end while
|
|
}
|
|
if len(reg)<>1 then Error "Wrong Evaluation"
|
|
print "Result :";stackitem(reg)
|
|
}
|
|
CheckAst
|