PB_Eval()
Publié : mar. 07/mars/2017 18:17
Salut, j’essaie de créer une fonction simple mais puissante pour évaluer
une expression texte grâce au compilateur, pas si simple en faite !
Niveau évaluation ça va je gère je crois, le truc c'est
comment faire ça le mieux possible ?...
Là ou sa devient plus compliqué, c'est si ont inclue dans l'expression
des (Variables ça gère car pas besoin de les déclarer)
Listes, Tableaux, Maps voir des fonctions perso.
Il faut les déclarer avant l'expression, ça
je gère aussi plus ou moins je pense.
Bon, pour commencer, avec ce bout de code (Variables non encore implémenté mais j'y travail)
Est-ce la meilleur façon de procédé ?
Est-ce bien structurer, etc ?
Est-ce que le code est propre ?
Une fois ce bout de code propre et avec vos conseil je passerais à la suite.
Expression.s = Expression sous forme de texte, ex: "123.369 * (45 / 12 - 5) + Val(" + chr(34) + "47" + chr(34) + ")"
Variables.s = Toutes les Variables, Listes, Tableaux, Maps... Pas encore ajouté
Format.s = Format de sortie pour savoir comment évaluer l'expression, en tans que Nombre, String, Script
Type.s = C'est le type pour certain Format
Édit: Code plusieurs fois édité et corrigé.
Merci.
une expression texte grâce au compilateur, pas si simple en faite !
Niveau évaluation ça va je gère je crois, le truc c'est
comment faire ça le mieux possible ?...
Là ou sa devient plus compliqué, c'est si ont inclue dans l'expression
des (Variables ça gère car pas besoin de les déclarer)
Listes, Tableaux, Maps voir des fonctions perso.
Il faut les déclarer avant l'expression, ça
je gère aussi plus ou moins je pense.
Bon, pour commencer, avec ce bout de code (Variables non encore implémenté mais j'y travail)
Est-ce la meilleur façon de procédé ?
Est-ce bien structurer, etc ?
Est-ce que le code est propre ?
Une fois ce bout de code propre et avec vos conseil je passerais à la suite.
Expression.s = Expression sous forme de texte, ex: "123.369 * (45 / 12 - 5) + Val(" + chr(34) + "47" + chr(34) + ")"
Variables.s = Toutes les Variables, Listes, Tableaux, Maps... Pas encore ajouté
Format.s = Format de sortie pour savoir comment évaluer l'expression, en tans que Nombre, String, Script
Type.s = C'est le type pour certain Format
Édit: Code plusieurs fois édité et corrigé.
Merci.
Code : Tout sélectionner
; Evaluateur d'expression grâce au Compilateur.
; PB_Eval()
; Créer par Monsieur Dieppedalle David le 06/03/2017.
Structure PB_Eval
PB_Eval_Expression.s
PB_Eval_Variables.s
PB_Eval_Format.s
PB_Eval_Type.s
PB_Eval_Erreur.s
PB_Eval_Resultat.s
EndStructure
Global PB_Eval.PB_Eval
Procedure.b PB_Eval(PB_Eval_Expression.s = "", PB_Eval_Variables.s = "", PB_Eval_Format.s = "PB_Eval_Str", PB_Eval_Type.s = "PB_Eval_Quad")
PB_Eval.PB_Eval\PB_Eval_Expression = PB_Eval_Expression.s
PB_Eval.PB_Eval\PB_Eval_Variables = PB_Eval_Variables.s
PB_Eval.PB_Eval\PB_Eval_Format = PB_Eval_Format.s
PB_Eval.PB_Eval\PB_Eval_Type = PB_Eval_Type.s
PB_Eval.PB_Eval\PB_Eval_Erreur = ""
PB_Eval.PB_Eval\PB_Eval_Resultat = ""
Select LCase(PB_Eval_Type.s)
Case "pb_eval_quad", "pb_eval_byte", "pb_eval_ascii", "pb_eval_word", "pb_eval_unicode", "pb_eval_long"
PB_Eval_Type.s = ReplaceString(PB_Eval_Type.s, "PB_Eval", "#PB", #PB_String_NoCase)
Case "pb_eval_script_string", "pb_eval_script_nombre"
Default
PB_Eval.PB_Eval\PB_Eval_Erreur = "Paramètre PB_Eval_Type Invalide: " + PB_Eval_Type.s + "."
ProcedureReturn 0
EndSelect
If PB_Eval_Expression.s <> ""
CreateDirectory(GetCurrentDirectory() + "Compilation")
SetCurrentDirectory(GetCurrentDirectory() + "Compilation")
If CreateFile(1, GetCurrentDirectory() + "PB_Eval_CodeSource.pb")
Select LCase(PB_Eval_Format.s)
Case "pb_eval_str", ""
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, Str(" + PB_Eval_Expression.s + ")): CloseFile(1)")
Case "pb_eval_stru"
Select LCase(PB_Eval_Type.s)
Case "pb_eval_quad", "pb_eval_byte", "pb_eval_ascii", "pb_eval_word", "pb_eval_unicode", "pb_eval_long"
Default
PB_Eval.PB_Eval\PB_Eval_Erreur = "Paramètre PB_Eval_Type Invalide pour ce format: " + PB_Eval_Format.s + "."
CloseFile(1)
ProcedureReturn 0
EndSelect
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, StrU(" + PB_Eval_Expression.s + ", " + PB_Eval_Type.s + ")): CloseFile(1)")
Case "pb_eval_strf"
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, StrF(" + PB_Eval_Expression.s + ")): CloseFile(1)")
Case "pb_eval_strd"
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, StrD(" + PB_Eval_Expression.s + ")): CloseFile(1)")
Case "pb_eval_hex"
Select LCase(PB_Eval_Type.s)
Case "pb_eval_quad", "pb_eval_byte", "pb_eval_ascii", "pb_eval_word", "pb_eval_unicode", "pb_eval_long"
Default
PB_Eval.PB_Eval\PB_Eval_Erreur = "Paramètre PB_Eval_Type Invalide pour ce format: " + PB_Eval_Format.s + "."
CloseFile(1)
ProcedureReturn 0
EndSelect
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, Hex(" + PB_Eval_Expression.s + ", " + PB_Eval_Type.s + ")): CloseFile(1)")
Case "pb_eval_bin"
Select LCase(PB_Eval_Type.s)
Case "pb_eval_quad", "pb_eval_byte", "pb_eval_ascii", "pb_eval_word", "pb_eval_unicode", "pb_eval_long"
Default
PB_Eval.PB_Eval\PB_Eval_Erreur = "Paramètre PB_Eval_Type Invalide pour ce format: " + PB_Eval_Format.s + "."
CloseFile(1)
ProcedureReturn 0
EndSelect
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, Bin(" + PB_Eval_Expression.s + ", " + PB_Eval_Type.s + ")): CloseFile(1)")
Case "pb_eval_string"
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, " + Chr(34) + ReplaceString(PB_Eval_Expression.s, Chr(34), Chr(34) + "+ Chr(34) +" + Chr(34)) + Chr(34) + "): CloseFile(1)")
Case "pb_eval_script"
Select LCase(PB_Eval_Type.s)
Case "pb_eval_script_string"
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, " + PB_Eval_Expression.s + "): CloseFile(1)")
Case "pb_eval_script_nombre"
WriteString(1, CodeVariable.s + ~"CreateFile(1, GetCurrentDirectory() + \"PB_Eval_Resultat.txt\"): WriteString(1, Str(" + PB_Eval_Expression.s + ")): CloseFile(1)")
Default
PB_Eval.PB_Eval\PB_Eval_Erreur = "Paramètre PB_Eval_Type Invalide pour ce format: " + PB_Eval_Format.s + "."
CloseFile(1)
ProcedureReturn 0
EndSelect
Default
PB_Eval.PB_Eval\PB_Eval_Erreur = "Paramètre PB_Eval_Format Invalide: " + PB_Eval_Format.s + "."
CloseFile(1)
ProcedureReturn 0
EndSelect
CloseFile(1)
Else
PB_Eval.PB_Eval\PB_Eval_Erreur = "Impossible d'écrire le code source !"
ProcedureReturn 0
EndIf
Delay(25) ; Histoire de laisser souffler un peu le fichier.
PB_Eval_Compilateur = RunProgram(#PB_Compiler_Home + "/Compilers/pbcompiler", "PB_Eval_CodeSource.pb", GetCurrentDirectory(), #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide)
PB_Eval_Sortie.s = ""
PB_Eval_Erreur.s = ""
If PB_Eval_Compilateur
While ProgramRunning(PB_Eval_Compilateur)
If AvailableProgramOutput(PB_Eval_Compilateur)
PB_Eval_Sortie.s = ReadProgramString(PB_Eval_Compilateur)
If FindString(PB_Eval_Sortie.s, "Line")
PB_Eval_Erreur.s = PB_Eval_Sortie.s + Chr(13)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "is Not a valid operator", "n'est pas un opérateur valide", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Not a valid Decimal number", "Ceci n'est pas un nombre décimal valide", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Syntax error", "Erreur de syntaxe", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Bad parameter type: a string is expected", "Type de paramètre incorrect: une chaîne est attendue", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Bad parameter type, number expected instead of string", "Type de paramètre incorrect: un nombre est attendu au lieu d'une chaîne", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Literal string Not terminated (" + Chr(34) + " missing)", "Une chaîne n'est pas terminé: il manque un guillemet", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "A variable can't be named the same as a keyword", "Une variable ne peut pas être nommée comme un mot-clé", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Comparisons (=, <, >, =< And >=) are only supported With keywords like If, While, Until Or within Bool", "Les comparaisons (=, <,>, = <And> =) ne sont prises en charge qu'avec des mots clés comme: If, While, Until ou Bool", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Division by 0 forbidden", "Division par 0 interdite", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Numerical overflow: too many digits", "Débordement numérique: trop de chiffres", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "is Not a function, Array, List, Map Or Macro", "Cette Fonction est inconnue, ce n'est ni: Une Fonction, Un Tableau, Une Liste, Une Map ou une Macro", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Can't mix strings with numerical values.", "Impossible de mélanger des chaînes avec des valeurs numériques.", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Structure Not found", "Structure introuvable", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "The Array dimensions value needs To be between 1 And 255 For", "La valeur des dimensions Array doit être comprise entre 1 et 255 pour", #PB_String_NoCase)
PB_Eval_Erreur.s = ReplaceString(PB_Eval_Erreur.s, "Error: line 1", "", #PB_String_NoCase)
PB_Eval.PB_Eval\PB_Eval_Erreur = PB_Eval_Erreur.s
ProcedureReturn 0
EndIf
PB_Eval.PB_Eval\PB_Eval_Erreur = "Ok."
EndIf
Wend
PB_Eval_ExitCode = ProgramExitCode(PB_Eval_Compilateur)
CloseProgram(PB_Eval_Compilateur) ; Ferme la connection vers le programme
If Bool(Not PB_Eval_ExitCode) ; Not, inversion de valeur, 0 = 1 et 1 = 0. 0 = pas d'erreurs, 1 = erreurs
If ReadFile(1, GetCurrentDirectory() + "PB_Eval_Resultat.txt")
While Eof(1) = 0 ; Boucle tant que la fin du fichier n'est pas atteinte. (Eof = 'End Of File')
PB_Eval_Resultat.s + ReadString(1) ; Affiche du fichier
Wend
CloseFile(1)
PB_Eval.PB_Eval\PB_Eval_Resultat = PB_Eval_Resultat.s
Else
PB_Eval.PB_Eval\PB_Eval_Erreur = "Le résultat n'est pas disponnible."
ProcedureReturn 0
EndIf
Else
PB_Eval.PB_Eval\PB_Eval_Erreur = "Une erreur de compilation c'est produite."
ProcedureReturn 0
EndIf
Else
PB_Eval.PB_Eval\PB_Eval_Erreur = "Le Compilateur est Introuvable."
ProcedureReturn 0
EndIf
EndIf
ProcedureReturn 1
EndProcedure
Procedure.s PB_Eval_Get_Expression()
ProcedureReturn PB_Eval.PB_Eval\PB_Eval_Expression
EndProcedure
Procedure.s PB_Eval_Get_Variables()
ProcedureReturn PB_Eval.PB_Eval\PB_Eval_Variables
EndProcedure
Procedure.s PB_Eval_Get_Format()
ProcedureReturn PB_Eval.PB_Eval\PB_Eval_Format
EndProcedure
Procedure.s PB_Eval_Get_Type()
ProcedureReturn PB_Eval.PB_Eval\PB_Eval_Type
EndProcedure
Procedure.s PB_Eval_Get_Erreur()
ProcedureReturn PB_Eval.PB_Eval\PB_Eval_Erreur
EndProcedure
Procedure.s PB_Eval_Get_Resultat()
ProcedureReturn PB_Eval.PB_Eval\PB_Eval_Resultat
EndProcedure
Expression.s = "98/4*89/4.25"
Variables.s = ""
; pb_eval_str
; pb_eval_stru
; pb_eval_strf
; pb_eval_strd
; pb_eval_hex
; pb_eval_bin
; pb_eval_string
; pb_eval_script
Format.s = "pb_eval_str"
; pb_eval_quad
; pb_eval_byte
; pb_eval_ascii
; pb_eval_word
; pb_eval_unicode
; pb_eval_long
; pb_eval_script_string
; pb_eval_script_nombre
Type.s = "pb_eval_quad"
PB_Eval(Expression.s, Variables.s, Format.s, Type.s)
Debug "Expression Entré: " + PB_Eval_Get_Expression()
Debug "Variables Entré: " + PB_Eval_Get_Variables()
Debug "Format Entré: " + PB_Eval_Get_Format()
Debug "Type Entré: " + PB_Eval_Get_Type()
Debug "Erreur Rencontré: " + PB_Eval_Get_Erreur()
Debug "Résultat de l'expression: " + PB_Eval_Get_Resultat()