Expression evaluator

Share your advanced PureBasic knowledge/code with the community.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Very nice...just what I was looking for. Good Job. Can't wait until its completly finished.

Thank You :)
User avatar
utopiomania
Addict
Addict
Posts: 1655
Joined: Tue May 10, 2005 10:00 pm
Location: Norway

Post by utopiomania »

You're welcome! Actually the program is finished as such. I had some plans at the time for more functionality,
but it works ok as is.

I'm going to put it in a Notepad clone to be able to evaluate expressions in the text.
doctornash
Enthusiast
Enthusiast
Posts: 130
Joined: Thu Oct 20, 2011 7:22 am

Re: Expression evaluator

Post by doctornash »

Hi, tried this expression evaluator in a real time sound synthesis app - it evaluated accurately but proved too expensive for each sample calculation for the audio streaming. Would there be any interest in someone having a crack at a PB interface for muparser for example?
http://beltoforion.de/article.php?a=muparser
It says:
Many applications require the parsing of mathematical expressions. The main objective of this library is to provide a fast and easy way of doing this. Written in C++, it works by transforming a mathematical expression into bytecode and precalculating constant parts of the expression. All languages that are able to use DLLs that export plain C functions should be able to use this parser. Due to the wrapper being necessary, there is some overhead associated with using the dynamic library. The following files are required: muParserDLL.h, muParser.lib, muParser.dll. Include the header file in your project and add the lib file to the project resources
jack
Addict
Addict
Posts: 1337
Joined: Fri Apr 25, 2003 11:10 pm

Re: Expression evaluator

Post by jack »

Code: Select all

ImportC "muparser32.lib"

   mupCreate (nBaseType.l) ;As "mupCreate"
   mupRelease (*a_hParser) ;As "mupRelease"
   mupSetExpr (*a_hParser, a_szExpr.s) ;As "mupSetExpr"
   mupDefinePostfixOprt (*a_hParser, a_szName.s, *a_pOprt, a_bOptimize.l) ;As "mupDefinePostfixOprt"
   mupDefineVar (*a_hParser, a_szName.s, *a_fVar) ;As "mupDefineVar"
   mupEval.d (*a_hParser) ;As "mupEval"
   mupSetVarFactory (*a_hParser, *a_pFactory, *pUserData) ;As "mupSetVarFactory"
   mupSetErrorHandler (*a_hParser, *a_pErrHandler) ;As "mupSetErrorHandler"
   mupGetErrorMsg (*a_hParser) ;As "mupGetErrorMsg" ;const muChar_t ptr
   mupGetErrorToken (*a_hParsert) ;As "mupGetErrorToken" ;const muChar_t ptr
   mupGetErrorPos (*a_hParser) ;As "mupGetErrorPos" ;muInt_t
   mupGetErrorCode (*a_hParser) ;As "mupGetErrorCode" ;muInt_t

EndImport

 #PARSER_MAXVARS	= 10
 
ProcedureC.d Factorial (x.d)
  Define.l i, n
  f.d

  f = 1
  n = x
  If n > 0
    For i = 1 To n
      f = f * i
    Next
  EndIf
  ProcedureReturn f
EndProcedure

;---------------------------------------------------------------------------
;Factory function For creating new parser variables
; This could As well be a function performing database queries.
ProcedureC AddVariable(a_szName.s, *pUserData)

   Static Dim afValBuf.d(#PARSER_MAXVARS)  ; I don't want dynamic allocation here
   Static iVal.i = 0                       ; so i used this buffer
 PrintN("Generating new variable "+a_szName+" (slots left: "+Str(#PARSER_MAXVARS-iVal)+")")
   ;;;Debug("Generating new variable "+a_szName+" (slots left: "+Str(#PARSER_MAXVARS-iVal)+")")
   ;MessageBox_(0, "Generating new variable "+a_szName+" (slots left: "+Str(#PARSER_MAXVARS-iVal)+")", "AddVariable",0)
   afValBuf(iVal) = 0
   If (iVal>=#PARSER_MAXVARS-1) 
      Debug("Variable buffer overflow.")
      ;MessageBox_(0, "Variable buffer overflow.", "AddVariable",0)
      ProcedureReturn 0
   EndIf
   iVal=iVal+1
   ProcedureReturn @afValBuf(iVal-1)
 EndProcedure
 
ProcedureC OnError (*hParser)
  PrintN("")
  PrintN("Error:")
  PrintN("------")
  PrintN("Message:  "+Chr(34)+PeekS(mupGetErrorMsg(*hParser),-1,#PB_Ascii)+Chr(34))
  PrintN("Token:    "+Chr(34)+PeekS(mupGetErrorToken(*hParser),-1,#PB_Ascii)+Chr(34))
  PrintN("Position: "+Str(mupGetErrorPos(*hParser)))
  PrintN("Errc:     "+Str(mupGetErrorCode(*hParser)))
  ProcedureReturn 0
EndProcedure
;--------------------------------------------------------------------------- 
OpenConsole()
  x.d
  y.d
  EvalResult.d
  Equation.s
  ts.s
  hParser.i
  x = 3
  
  hParser=mupCreate(0)
  PrintN("hParse = "+Str(hParse))
  mupSetVarFactory(hParser, @AddVariable(), 0)
  mupDefineVar (hParser, "x", @x)               ;map variable X to "x"
  mupDefineVar (hParser, "y", @y)               ;map variable Y To "y"
  mupSetErrorHandler(hParser, @OnError())
  ;CompilerIf 1
    mupDefinePostfixOprt(hParser,"!", @Factorial(),0)
    Equation = "z=x!"
    mupSetExpr (hParser, Equation)
    X = 7
    EvalResult = mupEval(hParser)               ;evaluate expression
    PrintN("z="+StrD(X)+"! = "+StrD(EvalResult))
    
    Equation = "z=z*8"
    mupSetExpr (hParser, Equation)
    EvalResult = mupEval(hParser)               ;evaluate expression      
    PrintN("z=z*8 = "+StrD(EvalResult))                 ;EvalResult
  ;CompilerEndIf
  
  Equation = "y=x*x"
  mupSetExpr (hParser, Equation)
  EvalResult = mupEval(hParser)                 ;evaluate expression
  
  PrintN(StrD(x)+"*"+StrD(x)+" = "+StrD(y))      ;EvalResult
  mupRelease(hParser)
  
  Print("Press return to exit ")
  Input()
CloseConsole()
Last edited by jack on Thu Mar 23, 2017 3:03 am, edited 1 time in total.
doctornash
Enthusiast
Enthusiast
Posts: 130
Joined: Thu Oct 20, 2011 7:22 am

Re: Expression evaluator

Post by doctornash »

thanks, but am getting this:
Error:
------
Message: ""
Token: ""
Position: -1
Errc: 21

Error:
------
Message: ""
Token: ""
Position: 0
Errc: 1
z=7! = 0

Error:
------
Message: ""
Token: ""
Position: 0
Errc: 1
z=z*8 = 0

Error:
------
Message: ""
Token: ""
Position: 0
Errc: 1
7*7 = 0
Press return to exit

am making reference to the lib from here:
https://github.com/beltoforion/muparser ... s/example2
jack
Addict
Addict
Posts: 1337
Joined: Fri Apr 25, 2003 11:10 pm

Re: Expression evaluator

Post by jack »

do you have visual studio installed?
you can build the libraries yourself there's a VS solution in the build directory
jack
Addict
Addict
Posts: 1337
Joined: Fri Apr 25, 2003 11:10 pm

Re: Expression evaluator

Post by jack »

try again, I updated the code.
doctornash
Enthusiast
Enthusiast
Posts: 130
Joined: Thu Oct 20, 2011 7:22 am

Re: Expression evaluator

Post by doctornash »

No I don't have VS installed, but thanks very much for the code update, as it seems to have done the trick :D
Result:
hParse = 0
Generating new variable z (slots left: 10)
z=7! = 5040
z=z*8 = 40320
7*7 = 49
Press return to exit
Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: Expression evaluator

Post by Damion12 »

Any chance someone has a compiled muparser.dll compiled for windows? I'm on a metered connection & don't want to download vss.
jack
Addict
Addict
Posts: 1337
Joined: Fri Apr 25, 2003 11:10 pm

Re: Expression evaluator

Post by jack »

Damion12
User
User
Posts: 81
Joined: Tue Oct 30, 2012 1:39 am

Re: Expression evaluator

Post by Damion12 »

Thank you - I did not see that. (Any idea why 64bit doesn't work?)
jack
Addict
Addict
Posts: 1337
Joined: Fri Apr 25, 2003 11:10 pm

Re: Expression evaluator

Post by jack »

Damion12 wrote:(Any idea why 64bit doesn't work?)
I have been trying to figure that out, it works on 64-bit if in the imports you change the string type to p-Ascii
but then it won't work on 32-bit, perhaps somebody can spot what the problem is.

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And #PB_Compiler_Processor = #PB_Processor_x64
  ImportC "muparser64.lib"
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows And #PB_Compiler_Processor = #PB_Processor_x86
  ImportC "muparser32.lib"
CompilerEndIf

   mupCreate (nBaseType.l) ;As "mupCreate"
   mupRelease (*a_hParser) ;As "mupRelease"
   mupSetExpr (*a_hParser, a_szExpr.p-Ascii) ;As "mupSetExpr"
   mupDefinePostfixOprt (*a_hParser, a_szName.p-Ascii, *a_pOprt, a_bOptimize.l) ;As "mupDefinePostfixOprt"
   mupDefineVar (*a_hParser, a_szName.p-Ascii, *a_fVar) ;As "mupDefineVar"
   mupEval.d (*a_hParser) ;As "mupEval"
   mupSetVarFactory (*a_hParser, *a_pFactory, *pUserData) ;As "mupSetVarFactory"
   mupSetErrorHandler (*a_hParser, *a_pErrHandler) ;As "mupSetErrorHandler"
   mupGetErrorMsg (*a_hParser) ;As "mupGetErrorMsg" ;const muChar_t ptr
   mupGetErrorToken (*a_hParsert) ;As "mupGetErrorToken" ;const muChar_t ptr
   mupGetErrorPos (*a_hParser) ;As "mupGetErrorPos" ;muInt_t
   mupGetErrorCode (*a_hParser) ;As "mupGetErrorCode" ;muInt_t

EndImport
Post Reply