Menu

Code review - Resolves ConstantString+ConstandString concat issue

Anobium
2021-10-09
2021-10-09
  • Anobium

    Anobium - 2021-10-09

    This code resolves the ConstantString+ConstandString concat issue reported a long time ago.

    Thoughts and comments?

    This is a highly complex issue and I do not blame Hugh for not fixing. The following use case shows the issue.
    The issue is very obvious on AVR and will happen on PICs as the RAM memory gets consumed.

    HSerPrint "a"+"123" 'yields a13
    

    I am using HSerPrint as the example. There are many more commands that exhibit the same issue.

    The error is happening as system string variable is created with the length of the first constant. In this case a value of 1. Then, the compile correctly creating ASM adding together two tables "a"+"123" but then places the result of the string concat into the system string variable memory space that is 1 byte long not 4. And, then, things go wrong when the HSerPrint is passed the system string variable.

    However, this is one of many use cases that have this type of issue.

    1. constant_string + constant_string
    2. constant_string + variable_string
    3. variable_string + constant_string
    4. constant_string + constant_string + constant_string + constant_string
    5. many more....

    To resolve I have added the following code.

    1. Determine if there is a single constant_string - if so, not worries - set the system string variable memory to the correct size.
    2. Determine if there is are two constant_strings - if so, determine the size of the two two constant_strings and set the system string variable memory to the correct size.
    3. If any string variable is concatenated then create a system string variable memory to the maximum for the chip, as this can be a large system string variable see the next line
      - I cannot guess the size of the string variable
      - I cannot determine a method to work out the size of string variable - I have asked Hugh}
      - If a system string variable memory to the maximum size then a warning is now issued - use the following constant to resolve
    4. If any string variable is concatenated then create a system string variable memory to the size specified by the constant. SYSDEFAULTCONCATSTRING

    In all cases the ASM shows the action taken.


    After looking at this issue - I would advice no-one to use CONCAT as shown above. It is VERY inefficient. Consider using a string variable. Complete the CONCAT then HSerPrint. Why have the compiler create large system string variables (and there many be many) when they can be totally avoided.


    Evan


    Code - first and last lines are the as-is code.

    Part of the CompileSubCall() method.

                StringConstCount += 1
    
                'Need to ensure a concat is resolved
                StringConCatLengthAdapted = 0
                'Declare a local variables
                'Search for the second string constant parameter
                 Dim As Integer SecondParam = Instr(UCASE(.Param(CD, 1)), ";+;STRING")
                 Dim As String  StringConCatString = ""
    
                If HashMapGet(Constants, "SYSDEFAULTCONCATSTRING" ) > 0 then
                  'Always use this if defined constant      
                  StringConstLen = val(HashMapGetStr(Constants, "SYSDEFAULTCONCATSTRING" ))
                  StringConCatString = ";1. Used SYSDEFAULTCONCATSTRING constant to create SYSSTRINGPARAM"+ str(StringConstCount)+" string of length " + str(StringConstLen) + " to cater for constant_string + constant_string Concatenation"
                  StringConCatLengthAdapted = -1
    
                Else
    
                   If SecondParam > 0 and CountOccur ( .Param(CD, 1),"+") = 1  Then
                      'Found only second constant string, so, extract the lenth.  Does not handle string variables
                      StringConstLen = StringConstLen + Len(GetString(mid(.Param(CD, 1),SecondParam+2), 0))
                      StringConCatString = ";2. DIMensioned SYSSTRINGPARAM"+ str(StringConstCount)+" with string of length " + str(StringConstLen)
                      StringConCatLengthAdapted = -1
    
                   Else
                        'Must involve a string variable or this is a tad too complex, so, set to maximum of chip
                        StringConstLen = GetTypeSize("String")
                        StringConCatString = ";3. DIMensioned string SYSSTRINGPARAM"+ str(StringConstCount)+" * " + str(StringConstLen)
                        StringConCatLengthAdapted = -1
                        Temp = Message("UseSYSDEFAULTCONCATSTRING")
    
                        Replace temp, "%param1%", str(StringConstCount)
                        Replace temp, "%param2%", str(StringConstLen)
                                  LogWarning temp,.Origin
                   End If
    
                End if
    
    
                If StringConCatLengthAdapted = -1 then
                    LinkedListInsert(BeforePos,StringConCatString)
                End if
    
                BeforePos = LinkedListInsert(BeforePos, "SYSSTRINGPARAM" + Str(StringConstCount) + "=" + .Param(CD, 1) + .Origin)
    
     
  • Anobium

    Anobium - 2021-10-09

    A simpler approach as I cannot resolve the functions and string additions.

    It is simple. If the issue happens - create the constant SYSDEFAULTCONCATSTRING.

    Evan

                StringConstCount += 1
    
               'print StringConstLen, *.Called.Params(CD).Name, .Param(CD, 1)
               'Need to ensure a concat is resolved
                StringConCatLengthAdapted = 0
               'Declare a local variables
                Dim As String  StringConCatString = ""
    
                If HashMapGet(Constants, "SYSDEFAULTCONCATSTRING" ) > 0  then
                  'Always use this if defined constant
                  StringConstLen = val(HashMapGetStr(Constants, "SYSDEFAULTCONCATSTRING" ))
                  StringConCatString = ";1. Used SYSDEFAULTCONCATSTRING constant to create SYSSTRINGPARAM"+ str(StringConstCount)+" string of length " + str(StringConstLen) + " to cater for constant_string + constant_string Concatenation"
                  StringConCatLengthAdapted = -1
    
                End If
    
                If StringConCatLengthAdapted = -1 then
                    LinkedListInsert(BeforePos,StringConCatString)
                End if
                BeforePos = LinkedListInsert(BeforePos, "SYSSTRINGPARAM" + Str(StringConstCount) + "=" + .Param(CD, 1) + .Origin)
    
     

Log in to post a comment.