Page 1 of 1

Expression as INPUT?

Posted: Mon Jun 15, 2020 10:53 pm
by AMpos
Is there an easy way to convert an user expresion input to value?

I mean:

a$=input$
result=expression(a$)
>user types "2+2"
and
RESULT=4

In my old program, I did a procedure to convert this (it only parsed +-/*, and I dont need any more), and perhaps there is some kind of trick to do it automatically...

Re: Expression as INPUT?

Posted: Mon Jun 15, 2020 11:49 pm
by STARGÅTE
One of the easiest ways is using a database query:

Code: Select all

UseSQLiteDatabase()

Procedure.s Eval(String.s)
	Static Database.i
	Protected Result.s
	If Not Database 
		Database = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)
	EndIf
	If DatabaseQuery(Database, "Select ("+String+")")
		If NextDatabaseRow(Database)
			Result = GetDatabaseString(Database, 0)
		EndIf
		FinishDatabaseQuery(Database)
	Else
		Result = DatabaseError()
	EndIf
	ProcedureReturn Result
EndProcedure

Debug Eval("2+2")
Debug Eval("3*4-1")

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 12:58 am
by Tenaja
AMpos wrote:Is there an easy way to convert an user expresion input to value?

I mean:

a$=input$
result=expression(a$)
>user types "2+2"
and
RESULT=4

In my old program, I did a procedure to convert this (it only parsed +-/*, and I dont need any more), and perhaps there is some kind of trick to do it automatically...
Stargate has a wonderful cheat to do it. To do it in your code, it all depends on how complicated of an expression you want to permit. There are several examples of other solutions on this forum, look for these keywords: calculator, parser, recursive

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 1:39 am
by Tenaja
And if you want an excellent tutorial, search Google for
Let's Build a Compiler, by Jack Crenshaw

You will only need the first few chapters 8 handle your simply expressions, but you will likely thoroughly understand it once you get through the chapters you need.

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 2:10 am
by BarryG
STARGÅTE wrote:One of the easiest ways is using a database query
That's short and sweet, but it doesn't support decimal places? Giving it 22/7 only shows 3 instead of 3.14... Can that be done?

Anyway, I've used this code forever (by Danilo) and it works great -> http://forums.purebasic.com/german/view ... =8&t=24256

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 6:37 am
by Josh
BarryG wrote:That's short and sweet, but it doesn't support decimal places?
That's not true. How it is done is exactly one of the two ways, as it is done by all compilers I testet (except Pb has no system and does everything differently). Two integer operands result in an integer value, if one of the operands is a float, then the result is also a float:

Code: Select all

21/7   = 3
21.0/7 = 3.14285714285714
21/7.0 = 3.14285714285714

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 6:53 am
by BarryG
Josh wrote:That's not true.
Yes it is. I'm referring to STARGÅTE's code. Try for yourself:

Code: Select all

UseSQLiteDatabase()

Procedure.s Eval(String.s)
   Static Database.i
   Protected Result.s
   If Not Database
      Database = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)
   EndIf
   If DatabaseQuery(Database, "Select ("+String+")")
      If NextDatabaseRow(Database)
         Result = GetDatabaseString(Database, 0)
      EndIf
      FinishDatabaseQuery(Database)
   Else
      Result = DatabaseError()
   EndIf
   ProcedureReturn Result
EndProcedure

Debug Eval("22/7") ; Shows 3 instead of 3.14
Debug Eval("100/3") ; Shows 3 instead of 3.33
Debug Eval("256/6") ; Shows 42 instead of 42.66
So how do we get it to show decimal places? It currently only returns whole integers.

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 7:01 am
by infratec
You don't read exactly, or you don't understand what you read :wink:

Code: Select all

Debug Eval("256.0/6") ; Shows 42.6666666667
How should the program (SQLite) know that you don't want integers (which are faster)?
You have to tell him by pointing out that at least one of the values is floating point.

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 7:09 am
by #NULL
BarryG wrote:So how do we get it to show decimal places? It currently only returns whole integers.
Just prepend 1.0 *

Code: Select all

exp.s = "256/6"
Debug Eval(exp) ; 42
exp.s = "1.0*" + exp
Debug Eval(exp) ; 42.66..

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 8:23 am
by BarryG
I've never used SQLite before, so I didn't know it had to be prepended by "1.0*" to force floats. Thanks for explaining!

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 8:29 am
by STARGÅTE
It's not only SQLite, it's in nearly all languages, even in PB:

Code: Select all

Debug 22/7 ; Int / Int = Int
Debug 22.0/7 ; Float / Int = Float

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 9:06 am
by mk-soft
Tip!

Add own functions to SQLite -> viewtopic.php?f=12&t=75264

Re: Expression as INPUT?

Posted: Tue Jun 16, 2020 12:36 pm
by #NULL
You can also use CAST()

Code: Select all

Debug Eval("256/6")                ; 42
Debug Eval("CAST(256/6 as FLOAT)") ; 42.0
Debug Eval("CAST(256 as FLOAT)/6") ; 42.66..