Code archives/Miscellaneous/Math Evaluation
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| This is my math evaluation function with an example. It outputs to easy to read asm code, which you can easily change.. It is mathmatically correct, and works out ()'s Tell me what you think :) | |||||
; zenith's Math Evaluation Function (WITH EXAMPLE!)
; please give me credit if you use this in anyway shape or form (haha)
; if you have questions, please don't spam me by email
; but find me on IRC at: irc.blitzed.org on channel #blitzbasic or #blitzcoder
; If you're jsut going to steal my code and give me no credits, just remember I worked very hard on this.. :)
; Here is where you add Mathmatical operators
Const opmax=10
Global op$[opmax]
; op you use in to eval on left, asm op name on right
; use with proper math ordering, where 0=last thing it checks, opmax= first thing it checks
op[0]="+,add"
op[1]="-,sub"
op[2]="*,mul"
op[3]="/,div"
op[4]="%,mod"
; bitwise ops
op[5]="&,and"
op[6]="|,or"
op[6]="^,eor"
op[7]=">>,shr"
op[8]="<<,shl"
;logical ops
op[9]="&&,and"
op[10]="||,or"
; Create a function called int()
f.func = New func
f\name="calldll"
; ------------- EXAMPLE ------------
Global file=WriteFile("output.txt"),time=MilliSecs()
evalme$="-34--rab*345/calldll(34)" ;what we will be evaluating
evalme$=cleanupNeg(evalme)
Printf "// problem: "+evalme
eval(evalme) ; evaluate the problem
Printf "// "+(MilliSecs()-time)+"ms taken" ; how long it took to eval
CloseFile(file) ; close the file
ExecFile "output.txt" ; open up the file
End
; ----------------------------------
; list of functions
Type func
Field name$
End Type
Function cleanupneg$(in$)
Local out$
For i=1 To Len(in)
m$=Mid(in,i,1)
n$=Mid(in,i+1,1)
If m="-" And n="-"
o$=Right(in,Len(in)-i-1)
in$=Left(in,i-1)+"-(-"+o+")"
printf in
EndIf
Next
Return in
End Function
Function eval(in$)
; In my eval function, once something is worked out, it is pushed into the stack..
; then what we just worked is renamed to 'stack'
; whenever it reads stack, it pop's it to a register and then uses it
Local vari$
For i=1 To Len(in)
m$=Mid(in,i,1)
If m="("
ble$=find_back(in,i,2)
f.func = findfunc(ble)
; we've found a function
If f<>Null
io$=find_next(in,i,0) ; Lets find the whole function name
name$=f\name+"("+io+")"
printf "// function: "+name
in=Replace(in,name,"stack") ; now lets replace that whole function with 'stack'
Select f\name
Case "calldll"
eval(io) ; io is the parameters, whereas calldll() only has one parameter
printf "pop r1" ; asm output for this function
Printf "run 'dll',r1"
Printf "push 0" ; even though this function doesnt return anything, it needs to return 0
End Select
Else
io$=find_next(in,i,0) ; well it's not a function, so it has to be some () we have to work out
eval(io)
io="("+io+")"
in=Replace(in,io,"stack") ; now that we've worked it out, lets rename it to 'stack'
Printf "// out: "+in
EndIf
EndIf
Next
; my eval function uses a first in, last out stack
; IE: push 45, push 23, pop r1 = 23, pop r2 = 45
For x=opmax To 0 Step -1 ; we're checking for every single optoken
; we do it backwards for proper math ordering
If in="stack" Exit ; if in just equals stack, then we're finished
For i=1 To Len(in)
m$=Mid(in,i,1)
tokop$=parse(op[x],",",0)
If Mid(in,i,Len(tokop))=tokop
a$=find_back(in,i)
b$=find_next(in,i+(Len(tokop)-1))
Printf "// in: "+a+tokop+b
in=Replace(in,a+tokop+b,"stack")
If a="stack" ; if a = stack
Printf "pop r1" ; then we have to pop the value out of the stack
ElseIf Int(a)=a ; if a = a value
Printf "mov r1,"+a ; then we simply just mov r1 to the value
ElseIf a="" ; a negativity
a="-"
ElseIf Left(a,1)="-"
Printf "ldr r1,"+Right(a,Len(a)-1)
Printf "sgn r1"
;printf "mov r3,r1"
;Printf "sub r1,r1,r1"
;printf "sub r1,r1,r3"
Else ; but if its a variable
Printf "ldr r1,"+a ; we have to loadregister with that variable
EndIf
; the same thing goes for the next part with variable b
If b="stack"
If a="-"
Printf "pop r1"
Else
Printf "pop r2"
EndIf
ElseIf Int(b)=b
If a="-"
Printf "mov r1,"+b
Else
Printf "mov r2,"+b
EndIf
ElseIf b="" ; a negativity
b="-"
ElseIf Left(b,1)="-"
Printf "ldr r2,"+Right(b,Len(b)-1)
Printf "sgn r2"
;printf "mov r3,r2"
;Printf "sub r2,r2,r2"
;printf "sub r2,r2,r3"
Else
If a="-"
Printf "ldr r1,"+b
Else
Printf "ldr r2,"+b
EndIf
EndIf
If a="-" ; output negativity
Printf "sgn r1"
;printf "mov r3,r2"
;Printf "sub r1,r2,r2"
;printf "sub r1,r1,r3"
ElseIf b="-"
Printf "sgn r2"
;printf "mov r3,r2"
;Printf "sub r1,r1,r1"
;printf "sub r1,r1,r3"
Else
Printf parse(op[x],",",1)+" r1,r1,r2" ; now we do the math for it
EndIf
Printf "push r1" ; last we push this value into the stack
If in="stack" Exit ; if in just equals stack, then we're finished
Printf "// out: "+in
EndIf
Next
Next
If in<>"stack" ; meanwhile, if in still doesn't equal stack
If Int(in)=in ; which means, no work was done to it yet..
Printf "push "+in ; we just have to push it to the stack ourselves :)
Else
Printf "ldr r1,"+in
Printf "push r1"
EndIf
EndIf
End Function
; just an easy output function
Function Printf(in$)
WriteLine file,in
End Function
; find a number or variable until you hit another optoken (before x position)
Function find_back$(in$,x,io=1)
Local out$
Select io
; looking for a function
Case 2
For i=x-1 To 1 Step -1
For e=opmax To 0 Step -1
m$=Mid(in,i,Len(parse(op[e],",",0)))
If m=parse(op[e],",",0) Return out
Next
m$=Mid(in,i,1)
If m="(" Return out
out=m+out
Next
; looking for optoks
Case 1
For i=x-1 To 1 Step -1
For e=opmax To 0 Step -1
m$=Mid(in,i,Len(parse(op[e],",",0)))
If m=parse(op[e],",",0) Return out
Next
m$=Mid(in,i,1)
out=m+out
Next
; finding a (
Case 0
For i=x-1 To 1 Step -1
m$=Mid(in,i,1)
If m="(" Return out
out=m+out
Next
End Select
Return out
End Function
; find a number or variable until you hit another optoken (after x position)
Function find_next$(in$,x,io=1)
Local out$
If io=1
; find op
For i=x+1 To Len(in)
For e=opmax To 0 Step -1
m$=Mid(in,i,Len(parse(op[e],",",0)))
If m=parse(op[e],",",0); And Mid(in,i+1,1)<>"-" And count=0
Return out
EndIf
Next
m$=Mid(in,i,1)
out=out+m
Next
Else
; find paras
For i=x+1 To Len(in)
m$=Mid(in,i,1)
If m="(" sub=sub+1
If m=")" If sub=0 Return out Else sub=sub-1
out=out+m
Next
EndIf
Return out
End Function
; just a quick find function.. function :)
Function findfunc.func(name$)
For f.func = Each func
If f\name=name Return f
Next
Return Null
End Function
; parse a string with a delim character at a position
; example: in$="var,ghe,oe,oxw"
; to get "ghe" you would do parse(in,",",1)
Function parse$(in$,de$,se)
For x=1 To Len(in)
v$=Mid(in,x,1)
If v=de i=i+1
If se=i And v<>de m$=m+v
Next
Return m
End Function |
Comments
| ||
| Looks amazing but I have no idea how to actually get a result from it |
Code Archives Forum