Page 2 sur 2

Re: evaluateur d'expression calcul simple

Publié : ven. 17/févr./2017 8:47
par Marc56
Avec les versions x64 de PB on a une IMA ligne 35 (Global expression.s=InputRequester...)
Avec les version x86 ça marche.
:?:

Re: evaluateur d'expression calcul simple

Publié : ven. 17/févr./2017 9:06
par Marc56
Trouvé :!:

C'est (cette saleté de) Goto :twisted: qui tente de s'éjecter d'un Select / EndSelect et qui est (à juste titre) refusé.
(Curieusement uniquement sur les compilo x64?)
En mettant un flag et en renvoyant depuis l’extérieur du Select / EndSelect, ça ne fait plus d'IMA 8)

Code : Tout sélectionner

Global expression.s=InputRequester("calculateur" ,"entrez une expression valide ", "3*5+((12*8)/2)+5") ; par defaut =68

If expression = "" : End : EndIf



; ***********************ON CALCUL !************************

retour=recherche_parenthese()

Select retour
Case -1
      MessageRequester("erreur","il y a une erreur de parentheses dans votre expression" )
      End
      
      
      
Case 1 ; calcul avec parentheses
      
      ; recherche les parentheses les plus forte level
      SortStructuredList(parenthese(), #PB_Sort_Descending, OffsetOf(parenthese\level),TypeOf(parenthese\Level.l)) ; on trie la list pour faire apparaitre en premier les parentheses les plus prioritaires
      ResetList(parenthese())
      For t= 0 To ListSize(parenthese())
            SelectElement(parenthese(), t)
            calcul()   
            If ListSize(parenthese()) >0
                  ResetList(parenthese())
                  t=-1
            EndIf
      Next t
      
      AddElement(parenthese() )    ; on rempli bidon pour faire croire qu'il reste une parenthese au debut et a la fin de l'expression
      parenthese()\pos1.l =1
      parenthese()\pos2.l=Len(expression.s)
      
      sortie.s=calcul() ; sans parenthese
      MessageRequester("Resultat","le resultat est :"+sortie.s)   
      Nouveau = 1 ; Goto debut
      
Case 0 ; sans parentheses
      AddElement(parenthese() )    ; on rempli bidon pour faire croire qu'il reste une parenthese au debut et a la fin de l'expression
      parenthese()\pos1.l =1
      parenthese()\pos2.l=Len(expression.s)
      
      sortie.s=calcul() ; sans parenthese      
      MessageRequester("Resultat","le resultat est :"+sortie.s)
      Nouveau = 1 ; Goto debut
      
      
EndSelect
; ******************************************************************************

If Nouveau = 1
     Goto debut
EndIf
; ... suite
J'ai aussi ajouté, juste après l'InputRequester un

Code : Tout sélectionner

If expression = "" : End : EndIf
Pour pouvoir quitter si l'utilisateur clique sur la case de fermeture de l'InputRequester même sans effacer le contenu.

:wink:

Re: evaluateur d'expression calcul simple

Publié : ven. 17/févr./2017 11:32
par JohnJohnsonSHERMAN
Pour moi ca marche en x64 :)
Mais c'est vrai que ce Goto me pique les yeux :mrgreen:

En tout cas c'est trés bien foutu, et pas facile a faire ce genre de trucs, merci Dobro :)

Re: evaluateur d'expression calcul simple

Publié : ven. 17/févr./2017 11:49
par Zorro
Probablement un bug du compilateur
puisqu'il n'y a pas de raisons qu'un Goto fasse planter un Select-case

c'est peut etre pas tres propre,comme programmation, mais c'est pas comme si on sautais en dehors d'une procedure....
faudrai demander a Fred ....

le goto etait là juste pour mes tests ...

j'ai modifié le code avec les suggestions de Marc , sauf que j'ai desactivé le Goto ...
ce qui compte dans ce code c'est la procedure :
lanceur_calcul( expression.s) (expression.s doit rester Global , c'est important ...
(je viens de modifier le code dans ce sens )
Merci :)

Re: evaluateur d'expression calcul simple

Publié : ven. 17/févr./2017 12:53
par Marc56
puisqu'il n'y a pas de raisons qu'un Goto fasse planter un Select-case
Je ne sais pas non plus, mais j'aurais tendance à penser que pour toutes les fonctions doubles (Select / EndSelect, Procedure / EndProcedure, etc) le compilateur pose un flag à l'instruction de début et le garde jusqu'à l'instruction de fin ou une instruction de sortie de secours (ProcedureReturn, Break).

Un Goto dans un de ces blocs doit donc laisser un flag en attente (j'imagine) et verrouille un certains nombres d'adresses mémoire (donc IMA)?
Sans oublier qu'un Goto pour sortir d'une procédure peut faire une salade entre variables locales et globales (?)

Perso, j'évite les Goto, car ça devient vite du code spaghetti. :? :mrgreen:

:wink:

Re: evaluateur d'expression calcul simple

Publié : ven. 17/févr./2017 14:31
par Zorro
un select-case , n'a rien a voir avec une procedure
(je parle de son fonctionnement interne )

ce qui fout le cirque lorsqu'on tente un goto dans une procedure ce sont les parametres de la procedure et le retour
ils sont empilé sur la pile (l'etat du prg est empillé avant l'appel de la procedure, puis remis dans son etat a la sortie de la procedure ... )


si on fais un goto alors que la pile n'est plus dans le context, forcement, le programme se retrouve dans les choux

mais pour un select case, la pile n'est en principe pas touchée ...

un select-case, est un aiguillage , tout comme une suite de If-endif

on peut sortir d'un IF avec un goto (donc avant le endif ) sans probleme !

je pense qu'il s'agit d'un bug ...
sinon de toute façon, le probleme serai aussi ressorti pour la version 32 bits de Purebasic :)