Doch diese Methode sollte man wirklich nur "ab und zu" verwenden.
Führt man eine solche Funktion z.B. in einer Schleife aus, geht das Programm "relativ schnell" in die Knie.
Dort kommt man um einen "eigenen" Compiler nicht drum rum.
Trotzdem möchte ich in diesem Thema noch eine kleine Erweiterung bereitstellen.
Das ganze heißt bei mir Evaluator.
Mit diesem Include ist es möglich Ausdrücke berechnen zu lassen, und als erweiterung sogar Variablen zu benutzten, als Schnittstelle zwischen PB und dem Evaluator.
Dazu kann man EvaluatorEnvironment erstellen.
Code: Alles auswählen
; Konstanten
Enumeration
#Evaluator_VariableType_Integer
#Evaluator_VariableType_Float
#Evaluator_VariableType_String
EndEnumeration
; Strukturen
Structure EvaluatorVariable
Type.i
StructureUnion
Integer.i
Float.f
EndStructureUnion
String.s
EndStructure
Structure EvaluatorEnvironment
Map Variable.EvaluatorVariable()
EndStructure
Structure Evaluator
Database.i
List Environment.EvaluatorEnvironment()
EndStructure
; Initialisierung
Procedure InitEvaluator()
Global Evaluator.Evaluator
UseSQLiteDatabase()
Evaluator\Database = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)
EndProcedure
; Interne Funktion
Procedure.i Evaluator_DatabaseQuery(String.s, *Environment.EvaluatorEnvironment=#Null)
Protected Valiabels.s, Query.s = "SELECT "+String
If *Environment And MapSize(*Environment\Variable())
Query + " FROM ( SELECT "
ForEach *Environment\Variable()
If Valiabels : Valiabels + ", " : EndIf
Select *Environment\Variable()\Type
Case #Evaluator_VariableType_String
Valiabels + "'"+ReplaceString(*Environment\Variable()\String, "'", "''")+"'"
Case #Evaluator_VariableType_Integer
Valiabels + Str(*Environment\Variable()\Integer)
Case #Evaluator_VariableType_Float
Valiabels + StrF(*Environment\Variable()\Float)
EndSelect
Valiabels + " AS "+MapKey(*Environment\Variable())
Next
Query + Valiabels + ")"
EndIf
ProcedureReturn DatabaseQuery(Evaluator\Database, Query)
EndProcedure
; EvaluatorEnvironment
Procedure.i NewEvaluatorEnvironment()
ProcedureReturn AddElement(Evaluator\Environment())
EndProcedure
Procedure FreeEvaluatorEnvironment(*Environment.EvaluatorEnvironment)
ChangeCurrentElement(Evaluator\Environment(), *Environment)
DeleteElement(Evaluator\Environment())
EndProcedure
Procedure.i SetEvaluatorEnvironmentString(*Environment.EvaluatorEnvironment, Name.s, Value.s="")
AddMapElement(*Environment\Variable(), Name)
*Environment\Variable()\Type = #Evaluator_VariableType_String
*Environment\Variable()\String = Value
EndProcedure
Procedure.i SetEvaluatorEnvironmentInteger(*Environment.EvaluatorEnvironment, Name.s, Value.i=0)
AddMapElement(*Environment\Variable(), Name)
*Environment\Variable()\Type = #Evaluator_VariableType_Integer
*Environment\Variable()\Integer = Value
EndProcedure
Procedure.i SetEvaluatorEnvironmentFloat(*Environment.EvaluatorEnvironment, Name.s, Value.f=0)
AddMapElement(*Environment\Variable(), Name)
*Environment\Variable()\Type = #Evaluator_VariableType_Float
*Environment\Variable()\Float = Value
EndProcedure
; Evaluator
Procedure.i Evaluate(String.s, *Environment.EvaluatorEnvironment=#Null)
If Trim(String) = "" : String = "0" : EndIf
If Evaluator_DatabaseQuery(String, *Environment)
If NextDatabaseRow(Evaluator\Database)
CompilerIf SizeOf(Integer) = SizeOf(Quad)
ProcedureReturn GetDatabaseQuad(Evaluator\Database, 0)
CompilerElse
ProcedureReturn GetDatabaseLong(Evaluator\Database, 0)
CompilerEndIf
EndIf
FinishDatabaseQuery(Evaluator\Database)
EndIf
EndProcedure
Procedure.s EvaluateS(String.s, *Environment.EvaluatorEnvironment=#Null)
If Trim(String) = "" : String = "''" : EndIf
If Evaluator_DatabaseQuery(String, *Environment)
If NextDatabaseRow(Evaluator\Database)
ProcedureReturn GetDatabaseString(Evaluator\Database, 0)
EndIf
FinishDatabaseQuery(Evaluator\Database)
EndIf
EndProcedure
Procedure.f EvaluateF(String.s, *Environment.EvaluatorEnvironment=#Null)
If Trim(String) = "" : String = "0.0" : EndIf
If Evaluator_DatabaseQuery(String, *Environment)
If NextDatabaseRow(Evaluator\Database)
ProcedureReturn GetDatabaseFloat(Evaluator\Database, 0)
EndIf
FinishDatabaseQuery(Evaluator\Database)
EndIf
EndProcedure
Procedure.s EvaluateError()
ProcedureReturn DatabaseError()
EndProcedure
; Beispiel
InitEvaluator()
Debug "-----------------"
Debug Evaluate("1 + 2 + 3")
Debug EvaluateF("0.25 * 2")
Debug EvaluateS("'Hallo' || ' Welt'")
Debug "-----------------"
*Environment = NewEvaluatorEnvironment()
SetEvaluatorEnvironmentInteger(*Environment, "n", 64)
SetEvaluatorEnvironmentString(*Environment, "Text", "Hallo Welt")
SetEvaluatorEnvironmentFloat(*Environment, "f", 0.25)
Debug Evaluate("n < 100 AND n > 50", *Environment)
Debug EvaluateF("n * f", *Environment)
Debug EvaluateS("(100 * f) || ' %'", *Environment)