Basic Univers

; permet d'évaluer une expresion mathématique (comportant des opérations d'addition, multiplication...) et renvoie la valeur correspondante.

Procedure.s GetContent(String.s, Pos.l, First.b, Last.b) ; String = "dd(hallo)xyz", 3, '(', ')'
  Protected Content.s, *p.Byte, AnzKl.l
  *p = @String + Pos
  While *p\b
    If *p\b = First
      AnzKl.l + 1
    ElseIf *p\b = Last
      AnzKl - 1
      If AnzKl <= - 1
        Break
      EndIf
    EndIf
    Content + Chr(*p\b)
    *p + 1
  Wend
 
  ProcedureReturn Content
EndProcedure

Procedure.s CalcBiExpression(ContL.s, Op.s, ContR.s) ; A+b oder A*b ...
  Protected result.s
 
  Select Op
    Case "*"
      result = Str(Val(ContL) * Val(ContR))
    Case "/"
      result = Str(Val(ContL) / Val(ContR))
    Case "+"
      result = Str(Val(ContL) + Val(ContR))
    Case "-"
      result = Str(Val(ContL) - Val(ContR))
  EndSelect
 
 
  ProcedureReturn result.s
EndProcedure


Procedure.s ProcessExpression(Exp.s)
  Protected *p.Byte, v.s, zw.l, ContL.s, ContR.s, Op.s, Cont.s
  *p = @Exp
 
 
  ;/ Search for ()
  While *p\b
    If *p\b = '('
      Cont = GetContent(Exp, *p -@Exp + 1, '(', ')')
      v.s = ProcessExpression(Cont)
      Exp = ReplaceString(Exp, "(" + Cont +")", v)
      *p  = @Exp
    ElseIf *p\b = ')'
      Debug "Fehler: Klammer nicht geöffnet!"
    EndIf
    *p + 1
  Wend
 
 
  ;/ Search for * bzw. /
  *p = @Exp
  While *p\b
    If *p\b = '*' Or *p\b = '/'
      zw = *p ; Zwischenspeichern
      Op = Chr(*p\b)
      ; Gehe zurück bis ein Operator kommt
      *p - 1
      ContL = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b
        ContL = Chr(*p\b) + ContL
        *p - 1
      Wend
     
      *p = zw
     
      ; Gehe vorwärts bis Operator kommt
      *p + 1
      ContR = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b
        ContR = ContR + Chr(*p\b)
        *p + 1
      Wend
     
      v = CalcBiExpression(ContL, Op, ContR)
      Exp = ReplaceString(Exp, ContL + Op + ContR, v)
      *p = @Exp
    EndIf
    *p + 1
  Wend
 
  ;/ Search for + bzw. -
  *p = @Exp
  While *p\b
    If *p\b = '+' Or *p\b = '-'
      zw = *p ; Zwischenspeichern
      Op = Chr(*p\b)
      ; Gehe zurück bis ein Operator kommt
      *p - 1
      ContL = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b
        ContL = Chr(*p\b) + ContL
        *p - 1
      Wend
     
      *p = zw
     
      ; Gehe vorwärts bis Operator kommt
      *p + 1
      ContR = ""
      While *p\b <> '*' And *p\b <> '/' And *p\b <> '+' And *p\b <> '-' And *p\b
        ContR = ContR + Chr(*p\b)
        *p + 1
      Wend
     
      v = CalcBiExpression(ContL, Op, ContR)
      Exp = ReplaceString(Exp, ContL + Op + ContR, v)
      *p = @Exp
    EndIf
    *p + 1
  Wend
 
 
  ProcedureReturn Exp
EndProcedure




Expression.s = "(2*2)+2*(3+4*(4+1))*2"
Expression = RemoveString(Expression, " ") ; im Parser
res.s = ProcessExpression(Expression)
Debug "#############  RESULTAT  #############"
Debug res