xsharp.eu • MEMVAR variable naming
Page 1 of 1

MEMVAR variable naming

Posted: Wed Jul 20, 2022 11:19 pm
by boonnam
I just ran into something interesting about MEMVAR variable naming. You cannot have underscore as part of the variable name. Here is my sample console program:

Code: Select all

USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text

FUNCTION Start() AS VOID STRICT

local cFilter, cFilter2 as string
local cPolicy as string
memvar cOpt_Filter_Var
memvar cOptFilterVar

cPolicy := "100L"
cOpt_Filter_Var := cPolicy
cOptFilterVar := cPolicy

cFilter := StrEvaluate('mpolicy == "&cOpt_Filter_Var"')
cFilter2 := StrEvaluate('mpolicy == "&cOptFilterVar"')

console.WriteLine("cFilter: " + cFilter)
console.WriteLine("cFilter2: " + cFilter2)
console.ReadKey()
Here is the result:

Code: Select all

cFilter:  mpolicy == "cOpt_Filter_Var"
cFilter2: mpolicy =="100L"

MEMVAR variable naming

Posted: Thu Jul 21, 2022 5:40 am
by Chris
Hi Boonam,

Thanks for the report, this is a small bug in the StrEvaluate() function, it does not take underscores into account.

If you need a quick solution, please put this function in one of your base libraries, rebuild and it should work now:

Code: Select all

FUNCTION StrEvaluate( cString AS STRING ) AS STRING
    IF cString:IndexOf("&") > 0
        LOCAL cVariableName AS STRING
        LOCAL lInVariable   AS LOGIC
        LOCAL evalMacro     AS LOGIC
        LOCAL lAddChar      AS LOGIC
        lInVariable := evalMacro := FALSE
        cVariableName := ""
        VAR sb := System.Text.StringBuilder{cString:Length}
        FOREACH VAR cChar IN cString
            lAddChar := TRUE
            SWITCH cChar
                CASE c'&'
                    lInVariable   := TRUE
                    cVariableName := ""
                    lAddChar     := FALSE
                CASE c' '
                CASE c't'
                    IF lInVariable
                        lInVariable := FALSE
                        evalMacro   := TRUE
                    ENDIF
                CASE c'.'
                    IF lInVariable
                        lInVariable := FALSE
                        evalMacro   := TRUE
                        lAddChar     := FALSE
                    ENDIF
                OTHERWISE
                    IF lInVariable
                        IF Char.IsLetterOrDigit(cChar) .or. cChar == c'_'
                            cVariableName += cChar:ToString()
                            lAddChar     := FALSE
                        ELSE
                            lInVariable := FALSE
                            evalMacro   := TRUE
                        ENDIF
                    ENDIF
            END SWITCH
            IF evalMacro
                VAR result := StrEvaluateMemVarGet(cVariableName)
                sb:Append(result)
                evalMacro := FALSE
            ENDIF
            IF lAddChar
                sb:Append(cChar)
            ENDIF
        NEXT
        IF lInVariable
            VAR result := StrEvaluateMemVarGet(cVariableName)
            sb:Append(result)
        ENDIF
        cString := sb:ToString()
    ENDIF
    RETURN cString


INTERNAL FUNCTION StrEvaluateMemVarGet(cVariableName AS STRING) AS STRING
    TRY
        VAR oMemVar := XSharp.MemVar.PrivateFind(cVariableName)
        IF oMemVar == NULL
            oMemVar := XSharp.MemVar.PublicFind(cVariableName)
        ENDIF
        IF oMemVar != NULL
            RETURN oMemVar:Value:ToString()
        ENDIF
    CATCH
        // Memvar not found ?
    END TRY
    RETURN cVariableName
.