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.
Determine if there is a single constant_string - if so, not worries - set the system string variable memory to the correct size.
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.
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
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 resolvedStringConCatLengthAdapted=0'Declare a local variables'Search for the second string constant parameterDimAsIntegerSecondParam=Instr(UCASE(.Param(CD,1)),";+;STRING")DimAsStringStringConCatString=""IfHashMapGet(Constants,"SYSDEFAULTCONCATSTRING")>0then'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=-1ElseIfSecondParam>0andCountOccur(.Param(CD,1),"+")=1Then'Found only second constant string, so, extract the lenth. Does not handle string variablesStringConstLen=StringConstLen+Len(GetString(mid(.Param(CD,1),SecondParam+2),0))StringConCatString=";2. DIMensioned SYSSTRINGPARAM"+str(StringConstCount)+" with string of length "+str(StringConstLen)StringConCatLengthAdapted=-1Else'Must involve a string variable or this is a tad too complex, so, set to maximum of chipStringConstLen=GetTypeSize("String")StringConCatString=";3. DIMensioned string SYSSTRINGPARAM"+str(StringConstCount)+" * "+str(StringConstLen)StringConCatLengthAdapted=-1Temp=Message("UseSYSDEFAULTCONCATSTRING")Replacetemp,"%param1%",str(StringConstCount)Replacetemp,"%param2%",str(StringConstLen)LogWarningtemp,.OriginEndIfEndifIfStringConCatLengthAdapted=-1thenLinkedListInsert(BeforePos,StringConCatString)EndifBeforePos=LinkedListInsert(BeforePos,"SYSSTRINGPARAM"+Str(StringConstCount)+"="+.Param(CD,1)+.Origin)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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 resolvedStringConCatLengthAdapted=0'Declare a local variablesDimAsStringStringConCatString=""IfHashMapGet(Constants,"SYSDEFAULTCONCATSTRING")>0then'Always use this if defined constantStringConstLen=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=-1EndIfIfStringConCatLengthAdapted=-1thenLinkedListInsert(BeforePos,StringConCatString)EndifBeforePos=LinkedListInsert(BeforePos,"SYSSTRINGPARAM"+Str(StringConstCount)+"="+.Param(CD,1)+.Origin)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
To resolve I have added the following code.
- 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
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.
See https://sourceforge.net/p/gcbasic/discussion/596084/thread/054d9bfde2/?limit=250#5c29 for report of the issue.
See the attachments for example code of the issue.
All examples will exhibit the bug.
A simpler approach as I cannot resolve the functions and string additions.
It is simple. If the issue happens - create the constant SYSDEFAULTCONCATSTRING.
Evan