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