Skip to content

Commit 250cb4f

Browse files
committed
Update VBAexpressions.cls
1 parent 3771ec6 commit 250cb4f

File tree

1 file changed

+111
-68
lines changed

1 file changed

+111
-68
lines changed

src/VBAexpressions.cls

Lines changed: 111 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ Private Const op_like As String = "$"
144144
Private Const op_neg As String = "~"
145145
Private Const op_AllItems As String = "*+-/^%\=<>&|$"
146146
Private Const op_AllNotUnaryItems As String = "*/^%\=<>&|$"
147+
Private Const d_FullGrammar As String = "*+-~/^%\=<>&|!$()[]{}'; "
147148
Private Const d_lCurly As String = "{"
148149
Private Const d_rCurly As String = "}"
149150
Private Const d_lParenthesis As String = "("
@@ -152,7 +153,10 @@ Private Const d_lSquareB As String = "["
152153
Private Const d_rSquareB As String = "]"
153154
Private Const d_Apostrophe As String = "'"
154155
Private Const d_Space As String = " "
156+
Private Const d_Semicolon As String = ";"
155157
Private Const e_ValueError As String = "#VALUE!"
158+
Private Const e_NAError As String = "#NA"
159+
Private Const e_InvalidAssignment As String = "#e-100" 'Expressions cannot be assigned a value.
156160
Private Const Tiny As Double = 1E-20
157161
'#
158162
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -305,7 +309,7 @@ Private Sub Class_Initialize()
305309
PI = 4 * Atn(1)
306310
PID2 = PI / 2
307311
e = Exp(1)
308-
P_SEPARATORCHAR = ";"
312+
P_SEPARATORCHAR = d_Semicolon
309313
P_DEC_SYMBOL = dsDot
310314
AscDecSymbol = 46
311315
P_GALLOPING_MODE = True
@@ -598,67 +602,99 @@ End Function
598602

599603
''' <summary>
600604
''' Method to obtain abstract expressions that do not contemplate the intermediate
601-
''' assignments defined by the equals sign.
605+
''' assignments.
602606
''' </summary>
603-
Public Sub AbstractAssignments()
604-
Dim i As Long
605-
Dim j As Long
606-
Dim tUB As Long
607-
Dim tkUB As Long
607+
Public Function AbstractAssignments(ByRef aExpression As Variant) As String()
608+
Dim strToEvaluate As String
609+
Dim EqualSymbolPos As Long
610+
Dim TokenDet As TokenInfo
608611
Dim tmpToken As token
609-
Dim BaseIndex As Long
612+
Dim tmpResult() As String
613+
Dim tmpStrAssignments As String
610614
Dim n As Long
611-
Dim tmpIdxRep As String
615+
Dim testChar As String
616+
Dim testChar2 As String
612617

613-
tUB = UBound(EvalTree)
614-
tkUB = UBound(EvalTree(tUB).Storage)
615-
i = LBound(EvalTree(tUB).Storage)
616-
BaseIndex = UBound(SubTreeData) + 1
618+
strToEvaluate = FormatEntry(CStr(aExpression))
619+
strToEvaluate = ReconstructLiteralStrings(P_EXPRESSION, _
620+
SBracketsNotationToNominal(ReplaceImpliedMult(strToEvaluate)))
621+
ReDim tmpResult(0 To 1) 'Indexes: [0] variables; [1] expression to evaluate
617622
Do
618-
If EvalTree(tUB).Storage(i).OperationToken = otEqual Then
619-
If (i + j + 1) <= tkUB Then 'Do not move anything beyond array limits
620-
tmpToken = EvalTree(tUB).Storage(i)
621-
EvalTree(tUB).Storage(i) = EvalTree(tUB).Storage(i + j + 1)
622-
EvalTree(tUB).Storage(i + j + 1) = tmpToken
623+
Do 'Discard false positives
624+
EqualSymbolPos = GetOPeratorSymbolPos(strToEvaluate, op_equal, EqualSymbolPos + 1)
625+
If EqualSymbolPos > 2 Then
626+
testChar = MidB$(strToEvaluate, EqualSymbolPos - 2, 2)
627+
testChar2 = MidB$(strToEvaluate, EqualSymbolPos + 2, 2) 'Check ahead for "=="
628+
Else
629+
testChar = vbNullString
630+
testChar2 = vbNullString
623631
End If
624-
j = j + 1 'equality counter
625-
Else
626-
If EvalTree(tUB).Storage(i).Arg1.LinkedIndex <> -1 Then
627-
If EvalTree(tUB).Storage(i).Arg1.LinkedIndex >= BaseIndex Then
628-
LIndexConstruc(1) = EvalTree(tUB).Storage(i).Arg1.LinkedIndex
629-
tmpIdxRep = Join$(LIndexConstruc, vbNullString)
630-
EvalTree(tUB).Storage(i).Arg1.LinkedIndex = EvalTree(tUB).Storage(i).Arg1.LinkedIndex - j
631-
LIndexConstruc(1) = EvalTree(tUB).Storage(i).Arg1.LinkedIndex
632-
EvalTree(tUB).Storage(i).DefString = Replace( _
633-
EvalTree(tUB).Storage(i).DefString, _
634-
tmpIdxRep, _
635-
Join$(LIndexConstruc, vbNullString))
632+
Loop While EqualSymbolPos > 0 And (testChar Like "[<>=]" Or testChar2 = op_equal)
633+
If EqualSymbolPos Then
634+
TokenDet.LogicalToken = True
635+
TokenDet.Position = EqualSymbolPos
636+
TokenDet.OperationToken = otEqual
637+
TokenDet.OperatorLen = LenB(op_equal)
638+
ExtractEvalToken strToEvaluate, tmpToken, TokenDet
639+
'Collect variables
640+
If tmpStrAssignments = vbNullString Then
641+
If AbstractValidate(tmpToken.Arg1.DefString) Then
642+
tmpStrAssignments = tmpToken.Arg1.DefString
643+
Else
644+
n = n + 1
636645
End If
637-
End If
638-
If EvalTree(tUB).Storage(i).Arg2.LinkedIndex <> -1 Then
639-
If EvalTree(tUB).Storage(i).Arg2.LinkedIndex >= BaseIndex Then
640-
LIndexConstruc(1) = EvalTree(tUB).Storage(i).Arg2.LinkedIndex
641-
tmpIdxRep = Join$(LIndexConstruc, vbNullString)
642-
EvalTree(tUB).Storage(i).Arg2.LinkedIndex = EvalTree(tUB).Storage(i).Arg2.LinkedIndex - j
643-
LIndexConstruc(1) = EvalTree(tUB).Storage(i).Arg2.LinkedIndex
644-
EvalTree(tUB).Storage(i).DefString = Replace( _
645-
EvalTree(tUB).Storage(i).DefString, _
646-
tmpIdxRep, _
647-
Join$(LIndexConstruc, vbNullString))
646+
If AbstractValidate(tmpToken.Arg2.DefString) Then
647+
If tmpStrAssignments = vbNullString Then
648+
tmpStrAssignments = tmpToken.Arg2.DefString
649+
Else
650+
tmpStrAssignments = tmpStrAssignments & "#" & tmpToken.Arg2.DefString
651+
End If
652+
Else
653+
n = n + 1
654+
End If
655+
Else
656+
If Not AbstractValidate(tmpToken.Arg1.DefString) Then
657+
n = n + 1
658+
End If
659+
If AbstractValidate(tmpToken.Arg2.DefString) Then
660+
tmpStrAssignments = tmpStrAssignments & "#" & tmpToken.Arg2.DefString
661+
Else
662+
n = n + 1
648663
End If
649664
End If
650-
i = i + 1
665+
Else
666+
Exit Do
667+
End If
668+
Loop
669+
If n Then 'Isolate assigments
670+
If n < 2 Then
671+
tmpResult(0) = tmpStrAssignments
672+
tmpResult(1) = Replace(strToEvaluate, Join$(Split(tmpStrAssignments, _
673+
"#"), op_equal) & op_equal, _
674+
vbNullString)
675+
Else 'Expressions cannot be assigned a value.
676+
tmpResult(0) = e_InvalidAssignment
677+
tmpResult(1) = e_InvalidAssignment
651678
End If
652-
n = n + 1
653-
Loop While n - 1 < tkUB
654-
If j = n Then 'Full assigment
655-
ReDim Preserve EvalTree(0 To tUB - 1)
656-
Else 'j < n
657-
ReDim Preserve EvalTree(tUB).Storage(0 To tkUB - j)
658-
EvalTree(tUB).index = EvalTree(tUB).index - j
659-
EvalTree(tUB).Capacity = EvalTree(tUB).Capacity - j
679+
Else
680+
tmpResult(0) = e_NAError
681+
tmpResult(1) = strToEvaluate
660682
End If
661-
End Sub
683+
AbstractAssignments = tmpResult
684+
End Function
685+
Private Function AbstractValidate(strAssignments As String) As Boolean
686+
Dim i As Long
687+
Dim L As Long
688+
Dim tmpResult As Boolean
689+
690+
L = Len(d_FullGrammar)
691+
i = 1
692+
Do
693+
tmpResult = (InStr(1, strAssignments, Mid(d_FullGrammar, i, 1)) = 0)
694+
i = i + 1
695+
Loop While i <= L And tmpResult
696+
AbstractValidate = tmpResult
697+
End Function
662698

663699
Private Function aCeiling(ByRef expression As String, ByRef fName As String) As String
664700
On Error GoTo err_Handler
@@ -4044,42 +4080,49 @@ Private Function GetCBItemIdx(ByRef cbBuffer As ClusterBuffer, ByRef ItemName As
40444080
End If
40454081
End Function
40464082

4047-
Private Function GetEvalToken(ByRef expression As String) As token
4083+
Private Sub ExtractEvalToken(ByRef expression As String, _
4084+
ByRef aToken As token, ByRef TokenDet As TokenInfo)
40484085
Dim TokenStart As Long
40494086
Dim TokenEnd As Long
4050-
Dim TokenDet As TokenInfo
40514087
Dim tmpArgs() As String
40524088

4053-
TokenDet = GetTokenInfo(expression)
40544089
If TokenDet.Position > 2 Then
40554090
'@--------------------------------------------------------------------
40564091
' Delimit token
40574092
GetTokenStart expression, TokenDet.Position, TokenStart
40584093
GetTokenEnd expression, TokenDet.Position, TokenDet.OperatorLen, TokenEnd
4059-
GetEvalToken.DefString = MidB$(expression, TokenStart, TokenEnd - TokenStart + 2)
4060-
GetEvalToken.OperationToken = TokenDet.OperationToken
4061-
SplitToken GetEvalToken.DefString, tmpArgs, GetEvalToken.OperationToken
4062-
GetEvalToken.Logical = TokenDet.LogicalToken
4094+
aToken.DefString = MidB$(expression, TokenStart, TokenEnd - TokenStart + 2)
4095+
aToken.OperationToken = TokenDet.OperationToken
4096+
SplitToken aToken.DefString, tmpArgs, aToken.OperationToken
4097+
aToken.Logical = TokenDet.LogicalToken
40634098
'@--------------------------------------------------------------------
40644099
' Define arguments
4065-
GetEvalToken.Arg1.DefString = tmpArgs(LBound(tmpArgs))
4066-
GetEvalToken.Arg2.DefString = tmpArgs(UBound(tmpArgs))
4100+
aToken.Arg1.DefString = tmpArgs(LBound(tmpArgs))
4101+
aToken.Arg2.DefString = tmpArgs(UBound(tmpArgs))
40674102
'@--------------------------------------------------------------------
40684103
' Fill arguments data
4069-
FillTokenArgProps GetEvalToken.Arg1
4070-
FillTokenArgProps GetEvalToken.Arg2
4104+
FillTokenArgProps aToken.Arg1
4105+
FillTokenArgProps aToken.Arg2
40714106
Else 'Retun values
4072-
GetEvalToken.DefString = expression
4073-
GetEvalToken.OperationToken = OperatorToken.otNull
4074-
GetEvalToken.Logical = TokenDet.LogicalToken
4107+
aToken.DefString = expression
4108+
aToken.OperationToken = OperatorToken.otNull
4109+
aToken.Logical = TokenDet.LogicalToken
40754110
'@--------------------------------------------------------------------
40764111
' Define argument
4077-
GetEvalToken.Arg1.DefString = expression
4112+
aToken.Arg1.DefString = expression
40784113
'@--------------------------------------------------------------------
40794114
' Fill argument data
4080-
FillTokenArgProps GetEvalToken.Arg1
4081-
FillTokenArgProps GetEvalToken.Arg2, True
4115+
FillTokenArgProps aToken.Arg1
4116+
FillTokenArgProps aToken.Arg2, True
40824117
End If
4118+
End Sub
4119+
Private Function GetEvalToken(ByRef expression As String) As token
4120+
Dim TokenDet As TokenInfo
4121+
Dim tmpResult As token
4122+
4123+
TokenDet = GetTokenInfo(expression)
4124+
ExtractEvalToken expression, tmpResult, TokenDet
4125+
GetEvalToken = tmpResult
40834126
End Function
40844127

40854128
Private Function GetFunctionName(ByRef expression As String) As String

0 commit comments

Comments
 (0)