calculer une chaine de caractères du type :
S$ = " ((20-10)/2 * 5 * (50-5))+3 "
Bien entendu sans les parenthèse c'est faisable :
mais avec...
Code : Tout sélectionner
Structure Operands
Value.f
Prioriter.l
EndStructure
Procedure MathString(*Chaine_adresse)
Static Buffer_Pass$
Static CounterV.l
Static CounterP.l
Static Ar.f,Br.f,Fr.f
Static OldChaine$
Buffer_Pass$ = PeekS(*Chaine_adresse)
StartAlgo:
OldChaine$ = Buffer_Pass$
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Chr(47),"|")
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Chr(42),"|")
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Chr(45),"|")
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Chr(43),"|")
;Debug Buffer_Pass$
For i = 1 To Len(Buffer_Pass$)
If Mid(Buffer_Pass$,i,1)="|" : CounterV+1 : EndIf
Next i
Dim Op.Operands(CounterV+1)
For i = 0 To CounterV+1
Op(i)\Value = ValF(StringField(Buffer_Pass$,i,"|"))
Next i
Dim Pr.Operands(CounterV)
For i = 1 To Len(OldChaine$)
If Mid(OldChaine$,i,1)="/" : Pr(CounterP)\Prioriter = 10 : CounterP+1 : EndIf
If Mid(OldChaine$,i,1)="*" : Pr(CounterP)\Prioriter = 9 : CounterP+1 : EndIf
If Mid(OldChaine$,i,1)="-" : Pr(CounterP)\Prioriter = 8 : CounterP+1 : EndIf
If Mid(OldChaine$,i,1)="+" : Pr(CounterP)\Prioriter = 7 : CounterP+1 : EndIf
Next i
;;Debug
; For v = 1 To CounterV+1
; Debug Op(v)\Value
; If Pr(v-1)\Prioriter=10 : Debug "/" : EndIf
; If Pr(v-1)\Prioriter=9 : Debug "*" : EndIf
; If Pr(v-1)\Prioriter=8 : Debug "-" : EndIf
; If Pr(v-1)\Prioriter=7 : Debug "+" : EndIf
; Next
For v = 1 To CounterV
If Pr(v-1)\Prioriter=10
Ar = Op(v)\Value
Br = Op(v+1)\Value
Fr = Ar/Br
Buffer_Pass$ = OldChaine$
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Str(Ar)+"/"+(Str(Br)),Str(Fr))
Dim Pr.Operands(0) : Dim Op.Operands(0) : CounterV=0 : CounterP=0 : Goto StartAlgo
EndIf
Next
For v = 1 To CounterV
If Pr(v-1)\Prioriter=9
Ar = Op(v)\Value
Br = Op(v+1)\Value
Fr = Ar*Br
Buffer_Pass$ = OldChaine$
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Str(Ar)+"*"+(Str(Br)),Str(Fr))
Dim Pr.Operands(0) : Dim Op.Operands(0) : CounterV=0 : CounterP=0 : Goto StartAlgo
EndIf
Next
For v = 1 To CounterV
If Pr(v-1)\Prioriter=8
Ar = Op(v)\Value
Br = Op(v+1)\Value
Fr = Ar-Br
Buffer_Pass$ = OldChaine$
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Str(Ar)+"-"+(Str(Br)),Str(Fr))
Dim Pr.Operands(0) : Dim Op.Operands(0) : CounterV=0 : CounterP=0 : Goto StartAlgo
EndIf
Next
For v = 1 To CounterV
If Pr(v-1)\Prioriter=7
Ar = Op(v)\Value
Br = Op(v+1)\Value
Fr = Ar+Br
Buffer_Pass$ = OldChaine$
Buffer_Pass$ = ReplaceString(Buffer_Pass$,Str(Ar)+"+"+(Str(Br)),Str(Fr))
Dim Pr.Operands(0) : Dim Op.Operands(0) : CounterV=0 : CounterP=0 : Goto StartAlgo
EndIf
Next
ProcedureReturn Fr
EndProcedure
Debug MathString(@"50+100/2")
Pour ceux qui on la flème de lire le code, voici comment il procède :
- on récupère la chaine$ = 50 + 100 / 2
- on remplace tout les opérateurs par | = 50 | 100 | 2
- on compte le nombre d'opérandes
- on en deduit -1 pour les opérateurs
- on colle les opérandes & opérateurs dans des tableaux
- les opérateurs perdent leurs signes (+,-,/,*) au profit de 'priorités'
- on calcule suivant les priorités
- si il reste des opérateurs on recommence la fonction.
Etc :
1°Passe = 50 + 100 / 2
2°Passe = 50 + 50
3°Passe = 100
si quelqu'un à déjà bosser la dessus...
Ca m'enuyerais de ne pas trouver un truc fiable
car ca me sert pour mon petit interpreteur :
File:1->Splus.rar

un exemple est fourni avec, ainsi que le plugin screen
@++