This is a maths parser I've been making for the development of my revolutionary "programming language"
. Anyhow, I made a similar one before (which I didn't post), but this one is just a test really so it can work with some built in functions. These are:
-Sin
-Cos
-Tan
-ASin
-ACos
-ATan
-Sqrt
All you do is call cmSolveExp(exp$), and it will return the expression
as a string, the reason for that is because this programming language doesn't have any data types.
`setup
sync on
set display mode 1024,768,32
`Main Loop
do
text 10,10,cmSolveExp("10+(5*(9/(45/sqrt(sin(90)*100)))")
sync
loop
`Maths Evaluator
function cmSolveExp(st$)
ret$=st$
for t=1 to charCount(st$,"(")
ret$=cmSolveInner(ret$)
next t
ret$=cmSolveExpS(ret$)
endfunction ret$
function cmSolveInner(st$)
if mid$(st$,1)="(" then st$=" "+st$
if isNum(mid$(st$,1)) or mid$(st$,1)="-" then st$="0"+st$
for t=1 to len(st$)
cur$=mid$(st$,t)
if cur$="(" then inc brk
if cur$=")" then dec brk
if brk>max then inc max
next t
brk=0
for t=1 to stTokenCount(st$)
curtok$=stGetToken(st$,t)
if curtok$="(" then inc brk
if curtok$=")" then dec brk
if brk=max then nesttok=t : exit
next t
brk=0
prevtok$=stGetToken(st$,nesttok-1)
for t=nesttok+1 to stTokenCount(st$)
curtok$=stGetToken(st$,t)
if curtok$=")" then exit
nest$=nest$+curtok$
next t
nestsolve$=cmSolveExpS(nest$)
tret$=nestsolve$
if prevtok$="sin" then tret$=str$(sin(val(nestsolve$))) : hasfunc=1
if prevtok$="cos" then tret$=str$(cos(val(nestsolve$))) : hasfunc=1
if prevtok$="tan" then tret$=str$(tan(val(nestsolve$))) : hasfunc=1
if prevtok$="asin" then tret$=str$(asin(val(nestsolve$))) : hasfunc=1
if prevtok$="acos" then tret$=str$(acos(val(nestsolve$))) : hasfunc=1
if prevtok$="atan" then tret$=str$(atan(val(nestsolve$))) : hasfunc=1
if prevtok$="sqrt" then tret$=str$(sqrt(val(nestsolve$))) : hasfunc=1
for t=1 to stTokenCount(st$)
if t<(nesttok-hasfunc) or t>nesttok+stTokenCount(nest$)+1
ret$=ret$+stGetToken(st$,t)
else
inc addslv
if addslv=1 then ret$=ret$+tret$
endif
next t
for t=1 to len(ret$)
cur$=mid$(ret$,t)
if cur$="(" then inc brk
if cur$=")" then dec brk
if brk<0 then exit
out$=out$+cur$
next t
endfunction out$
function cmSolveExpS(string$)
string$="0"+string$
lasttok$="+"
for t=1 to stTokenCount(string$)
if isOther(stGetToken(string$,t)) then lasttok$=stGetToken(string$,t)
if isNum(stGetToken(string$,t))
if lasttok$="+" then ret#=ret#+val(stGetToken(string$,t))
if lasttok$="-" then ret#=ret#-val(stGetToken(string$,t))
if lasttok$="*" then ret#=ret#*val(stGetToken(string$,t))
if lasttok$="/" then ret#=ret#/val(stGetToken(string$,t))
if lasttok$="^" then ret#=ret#^val(stGetToken(string$,t))
endif
next t
ret$=str$(ret#)
endfunction ret$
`String Functions
function searchStr(st$,sh$)
for t=1 to len(st$)
cur$=mid(st$,t,len(sh$))
if cur$=sh$ then pos=t
next t
endfunction pos
function remCharS(st$,ch$)
for t=1 to len(st$)
if mid$(st$,t)<>ch$
out$=out$+mid$(st$,t)
endif
next t
endfunction out$
function charCount(st$,ch$)
for t=1 to len(st$)
if mid$(st$,t)=ch$ then inc count
next t
endfunction count
function mid(st$,p,ln)
l=ln-1
for s=p to p+l
new$=new$+mid$(st$,s)
next s
endfunction new$
function stTokenCount(st$)
for c=1 to len(st$)
oldtok=tok
cur$=mid$(st$,c)
if isLetter(cur$) then tok=1
if isNum(cur$) then tok=1
if isOther(cur$) then inc tok
if cur$="." then tok=1
if oldtok<>tok
inc count
endif
next c
endfunction count
function stGetToken(st$,num)
for c=1 to len(st$)
oldtok=tok
cur$=mid$(st$,c)
if isLetter(cur$) then tok=1
if isNum(cur$) then tok=1
if isOther(cur$) then inc tok
if cur$="." then tok=1
if oldtok<>tok
inc curtok
endif
if curtok=num
ret$=ret$+cur$
endif
next c
endfunction ret$
function isLetter(text$)
if asc(text$)>=asc("a") and asc(text$)<=asc("z") then alpha=1
if asc(text$)>=asc("A") and asc(text$)<=asc("Z") then alpha=1
endfunction alpha
function isNum(text$)
if asc(text$)>=asc("0") and asc(text$)<=asc("9") then num=1
endfunction num
function isOther(text$)
if isLetter(text$)=0 and isNum(text$)=0 then exitfunction 1
endfunction 0
There are still a bug or two. I need to work on the
cmSolveExpS() function (which solves simple things without brackets). Unfortunatelly, it wont solve "-30*2" properly, it will return 60. The reason for that is because it doesn't treat the first number as -30, but instead it loops through, finds a minus, then a 30. Also, "1--1" will return 0. Not 1. I have to fix that function up, but it's a small function, so fixing it shouldn't affect the rest.
-Here's the basics of how it works for those who want to know:
If the expression is "sin(45*(20/10))", then how would you solve it?
Well, basically, it finds the inner-most nest, in this case, "(20/10)", and it solves that on it's own, then substitutes it into the function and returns it, so then you end up with: "sin(45*2)", it then repeats that process again. So then, you get the innermost nest, being "(45*2)" and solves it, you then end up with "sin(90)". Everytime it checks the innet nest, it checks the token just before it. If it's a function, in this case, sin, all it does it replace the old answer, with the sin of it, so now, you end up with "1"!
Enjoy