Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC:

DO/CASE limits? 27 Feb 2023 21:51 #25414

  • stefan.ungemach
  • stefan.ungemach's Avatar
  • Topic Author


  • Posts: 14
  • Is there a known limit to the number of CASEs in a DO/CASE construct? I have a simple construct like

    DO CASE
    CASE symField == #A4HHST
    symClass := #HHST
    (...)
    ENDCASE
    where the compiler crashes if I have more than 668 CASE conditions (reproducable). Since this is a strange number I'm not sure about some violated boundaries. Is there a known limit, and is there possibly a better way to deal with the need of processing several thousand of these translations?

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 27 Feb 2023 22:13 #25416

    • Chris
    • Chris's Avatar


  • Posts: 3981
  • Hi Stefan,

    There is (was) no such known limit, but I just managed to reproduce the problem here, although in my case I needed to use 1500 case conditions!

    This is a compiler bug, but of course indeed this is not the most efficient thing to do this. If all your CASE statements are like those in your code snippet, I would use a hastable/dictionary, which would make the code perform extremely fast and make it more readable I think. Something like:

    USING System.Collections.Generic
    
    FUNCTION CreateTable() AS Dictionary<SYMBOL,SYMBOL>
    	LOCAL oTable AS Dictionary<SYMBOL,SYMBOL>
    	oTable := Dictionary<SYMBOL,SYMBOL>{1000}
    	oTable:Add(#A4HHST, #HHST)
    	oTable:Add(#ANOTHER, #RESULT)
    	oTable:Add(#FOO, #BAR)
    	// ....
    RETURN oTable
    
    FUNCTION GetClassFromField(symField AS SYMBOL) AS SYMBOL
    STATIC LOCAL oTable := CreateTable() AS Dictionary<SYMBOL,SYMBOL>
    IF oTable:ContainsKey(symField)
    	RETURN oTable[symField]
    END IF
    RETURN null_SYMBOL
    
    
    FUNCTION Start() AS VOID
    LOCAL symField,symClass AS SYMBOL
    
    symField := #A4HHST
    symClass := GetClassFromField(symField)
    ? symClass
    
    symField := #FOO
    symClass := GetClassFromField(symField)
    ? symClass

    Just make sure that the hashtable is created only once! (hence the STATIC local in my sample).

    Another option would be to use SWITCH instead of DO CASE, but I think the hashtable is a more elegant solution.
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 27 Feb 2023 22:45 #25417

    • stefan.ungemach
    • stefan.ungemach's Avatar
    • Topic Author


  • Posts: 14
  • Thank you Chris,

    the hashtable is a much smarter solution - especially because we're talking of generated code here which leads to several thousand elements. I have several use cases for this :)

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 27 Feb 2023 23:02 #25418

    • Chris
    • Chris's Avatar


  • Posts: 3981
  • You're welcome!

    Just for completeness, using a SWITCH instead of a DO CASE, will also generate code that internally uses a hash table, so it will also be very fast. But not so readable/elegant, when you have so many cases.
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 28 Feb 2023 08:07 #25419

    • robert
    • robert's Avatar


  • Posts: 3600
  • Chris,

    Hi Stefan,

    There is (was) no such known limit, but I just managed to reproduce the problem here, although in my case I needed to use 1500 case conditions!

    Do you convert your test code into a Github issue?
    And maybe I should fix it by displaying an error message about "bad code quality"?

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 28 Feb 2023 08:09 #25420

    • leon-ts
    • leon-ts's Avatar


  • Posts: 280
  • Hi guys,
    I would also suggest using the TryGetValue method in this particular case to immediately check and get the value if it is in the dictionary:
    IF oTable:TryGetValue(symField, OUT symFoundClass AS SYMBOL)
    	RETURN symFoundClass
    END IF

    Best regards,
    Leonid
    Best regards,
    Leonid

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 28 Feb 2023 08:44 #25421

    • Chris
    • Chris's Avatar


  • Posts: 3981
  • Robert, done! :)

    Leonid, good point!

    And note to myself, a SWITCH command does not allow a SYMBOL for its expression

    .
    XSharp Development Team
    chris(at)xsharp.eu

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 28 Feb 2023 11:11 #25423

    • stefan.ungemach
    • stefan.ungemach's Avatar
    • Topic Author


  • Posts: 14
  • Thanks again to all. I have chosen Leonid's approach.

    Please Log in or Create an account to join the conversation.

    DO/CASE limits? 28 Feb 2023 12:15 #25425

    • robert
    • robert's Avatar


  • Posts: 3600
  • Chris,

    Robert, done! :)
    And note to myself, a SWITCH command does not allow a SYMBOL for its expression
    .

    In that case use Symbol2String() on the symbol and compare with (uppercase) literal strings,.
    The compiler will compare hashcodes, so that is relatively fast.

    Robert
    XSharp Development Team
    The Netherlands

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1