Code archives/Algorithms/MathToString$(...)
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| New in 1.5: More Operators have fun :) | |||||
Print MathToString("3")
Print MathToString("2/(3+2)")
Print MathToString("5>1 And 5<100")
Function MathToString$(TheMath$, unit = 0, divnow = 0)
Local MyParam$ = "*/^+-=<>&|%@", MyNumbs$ = "0123456789.", MyDivParam$ = "*/^"
Local Ziffer$, ScanPos, MathAnswer#, MathArt$, MathPower#, OldMathPower#
Local Scan, ScanNumber$, OldScanNumber$, MathScan$, MyScanText$
Local bscan, bscannow, bscanhave, ScanPosA, ScanPosB
Local deScan, deMathScan$, deMath
Local debsScan
TheMath$ = Lower(TheMath$)
TheMath$ = Replace(TheMath$, "and", "&")
TheMath$ = Replace(TheMath$, "xor", "@")
TheMath$ = Replace(TheMath$, "or", "|")
TheMath$ = Replace(TheMath$, "mod", "%")
MathScan$ = Replace(TheMath$, " ", "") : debsScan = 1
While bscan < Len(MathScan$)
bscan = bscan + 1
If Mid$(MathScan$, bscan, 1) = "(" Then
ScanPosA = bscan : bscannow = 1
While bscannow
If Mid$(MathScan$, bscan, 1) = "(" Then bscanhave = bscanhave + 1
If Mid$(MathScan$, bscan, 1) = ")" Then bscanhave = bscanhave - 1
If bscanhave = 0 Then bscannow = 0
bscan = bscan + 1
If KeyDown(1) Then End
Wend
ScanPosB = bscan
MyScanText$ = Mid$(MathScan$, ScanPosA+1, ScanPosB - ScanPosA - 2)
MyScanText$ = MathToString$(MyScanText$, unit + 1)
MathScan$ = Replace(MathScan$, Mid$(MathScan$, ScanPosA, ScanPosB - ScanPosA), MyScanText$)
bscan = 0
End If
If KeyDown(1) Then End
Wend
.NewMathScan
deMathScan$ = MathScan$
Scan = InMid$(MathScan$, MyParam$)
If Scan Then
ScanNumber$ = Mid$(MathScan$, 1, Scan-1)
MathScan$ = Mid$(MathScan$, Scan)
MathAnswer = val2(ScanNumber$)
Else
Return MathScan$
End If
deScan = 1
While Not MathScan$ = ""
uu$ = MathScan$
MathArt$ = Mid$(MathScan$, 1, 1)
MathScan$ = Mid$(MathScan$, 2)
If Mid$(MathScan$,1,1) = "-" Then
MathPower# = -1
MathScan$ = Mid$(MathScan$, 2)
Else
MathPower# = 1
End If
Scan = InMid$(MathScan$, MyParam$)
OldScanNumber$ = ScanNumber$
OldMathPower# = MathPower#
ScanNumber$ = Mid$(MathScan$, 1, Scan-1)
MathScan$ = Mid$(MathScan$, Len(ScanNumber$)+1)
If MathArt$ = "+" Then
MathAnswer# = MathAnswer# + (val2(ScanNumber$)*MathPower#)
ElseIf MathArt$ = "-" Then
MathAnswer# = MathAnswer# - (val2(ScanNumber$)*MathPower#)
ElseIf MathArt$ = "*" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) * (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "*-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "*" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "/" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) / (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "/-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "/" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "^" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) ^ (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "^-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "^" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "=" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) = (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "=-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "=" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "<" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) < (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "<-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "<" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = ">" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) > (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + ">-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + ">" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "&" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) And (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "&-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "&" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "|" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) Or (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "|-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "|" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "%" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) Mod (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "%-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "%" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
ElseIf MathArt$ = "@" Then
MathAnswer# = (val2(OldScanNumber$)*OldMathPower#) Xor (val2(ScanNumber$)*MathPower#)
If MathPower# = -1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "@-" + ScanNumber$, "-" + Str$(MathAnswer))
ElseIf MathPower# = 1 Then
MathScan$ = Replace(deMathScan$, OldScanNumber$ + "@" + ScanNumber$, Str$(MathAnswer))
End If
Goto NewMathScan
Else
Return "SYNTAX ERROR"
End If
Wend
Return Str(MathAnswer)
End Function
Function InMid$(A$, B$) ; in benutzung
Local C, Q, W
C = 0
For Q = 1 To Len(A$)
For W = 1 To Len(B$)
If (Mid$(A$, Q, 1) = Mid$(B$, W, 1)) And C = 0 Then C = Q : Exit
Next
If C>0 Then Exit
Next
Return C
End Function
Function val2#(sstring$)
Local temp#=0
Local decimal=0
Local sign=1
Local a
Local b
Local c
Local base=10
a=Instr(sstring$,"-",1)
If a Then negative=-1
b=Instr(sstring$,"&",a+1)
If b Then
Select Mid$(sstring$,a+1,1)
Case "B", "b"
base=2
a=b+1
Case "O", "o"
base=8
a=b+1
Case "H", "h"
base=16
a=b+1
Default
base=10
End Select
End If
decimal=0
For b=a+1 To Len(sstring$)
c=Asc(Mid(sstring$,b,1))
Select c
Case 44 ;","
Goto skip
Case 45 ;"-"
sign=-sign
Case 46 ;"."
decimal=1
Case 48,49,50,51,52,53,54,55,56,57 ;"0" To "9"
temp#=temp*base+c-48
If decimal Then decimal=decimal*base
Case 65,66,67,68,69,60 ;"A" to "F"
If base=16 Then
temp#=temp#*base+c-55
If decimal Then decimal=decimal*base
Else
Goto fini
EndIf
Case 97,98,99,100,101,102 ;"a" to "f"
If base=16 Then
temp#=temp#*base+c-87
If decimal Then decimal=decimal*base
Else
Goto fini
EndIf
Default
Goto fini
End Select
.skip
Next
.fini
If decimal Then temp#=temp#/decimal
If negative = -1 Then
Return -(temp#*sign)
Else
Return temp#*sign
End If
End Function |
Comments
| ||
| i had think about writing a code lexer but here is the end. Helpfull for anyone? |
| ||
| I tested this code. So, in other words, it parses math "text", computes it, and returns the result as updated "text". QUite interesting. I can imagine you took days on this. |
| ||
| weeks ;) |
| ||
| I just had a wild idea for a future project... (A:) You can extend this concept of text computations to include various mathematical unicode characters,..., and therefore compute that text. For example, you can parse (and compute) text that has subscripts, superscripts, fractions, etc. ![]() ![]() SC Unipad (excellent unicode editor) :: http://www.unipad.org/main/ ....Here's some Unicode code that I did (several years ago). I forgot what it does; you're welcome to use it. UNICODE to UTF8 conversion Functions ;;=== And, here is "FastText_Unicode.BB" , include file ::=== |
Code Archives Forum

