Menu

#Define in #script If DEF() issue

Help
ToniG
2022-09-12
2023-09-16
  • ToniG

    ToniG - 2022-09-12

    I am having some trouble with #defines in a script.
    The IF DEF() are ok as expected, using a warning "message" to see working.
    But getting unexpected behavior, #Define Butn_Map1 is active (but should be excluded) .

    Example code snippet below,
    When compile program I get the wrong hex file checksum. In .asm can see the Table ButnMap1
    The correct Warning "message" is shown from script but #Define Butn_Map1 is active.
    If I comment the second IF DEF() block it compiles with correct checksum & run ok.
    This IF DEF() block shouldn't be active.

    I tried newer build Version_99_02_1165 = same result.

    Attached files:
    Reference_NoScript.zip - - - - Reference ok with no script - LED_Key & QYF_TM1638
    Script_3xIF.zip - - - - - - - - - - - Issue
    Script_Comment2ndIF.zip - - ok Commented second IF DEF

    '        Specific board types (select 1)
    '-------------------------------------------------------------
    // #Define NEW_BRD    ' Add new board here
    // #Define LED_KEY        'for "LED&KEY" module board (Common Cathode display & Btn re-Map)
     #Define QYF_TM1638   'for "QYF-TM1638"  board (Common Anode display & rev. digits)
    '------------------------------------------------------------
    
    #Script
      IF DEF(QYF_TM1638) Then
        #Define Com_Anode    ' CA Display up to 10x 7-seg digits
        #Define RevDig       ' Reverse display digits (need for rev wired digits
        Warning "====== QYF_TM1638 board Selected OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(LED_KEY) Then
        #Define Butn_Map1 
        Warning "====== LED_KEY Selected  OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(NEW_BRD) Then
    '     add here
      END IF
    #EndScript
    
     
  • Anobium

    Anobium - 2022-09-13

    See Example script within a library at the bottom for the quick answer.


    Taken from the Help

    A constant is a value that cannot be altered by the program during normal execution.

    Within Great Cow BASIC there are two ways to create constants. 1. with the #DEFINE instruction, or, 2. via `#SCRIPT .. #ENDSCRIPT'.

    Within a script constants can be created and changed as the script execution is part of the preprocessor. Therefore, A script is process that is executed prior to the Great Cow BASIC source program is processing the main user program.

    An example of using #DEFINE is

    #DEFINE TIME_DELAY_VALUE    10
    

    The script construct is

    #SCRIPT
    'Create a constant
    SCRIPT_TIME_REPEAT_VALUE  =  10
    #ENDSCRIPT
    

    Guide for constants

    The following rules are recommended.

    1 - All CONSTANTS are capitalized
    2 - Do not define a constant in a library unless required
    3 - Create all library constants within a script ( see example below Constrain a Constant Example on how to constrain a constant)
    2 - Underscores are permitted in constant names within Scripts **
    3 - No prefix is required when a CONSTANT is PUBLIC. A PUBLIC constant is one that the user sets or the user can use.
    4 - Prefix CONSTANTS with SCRIPT_ when the CONSTANT is used outside of the library specific script section AND ARE NOT EXPOSED AS PUBLIC Constants.
    5 - Prefix CONSTANTS with __ (two underscores) when the CONSTANT is ONLY used inside the library specific script section
    6 - For PUBLIC prefix CONSTANTS with the capability name, _ (one underscore) and then a meaningful title, as follows GLCD_HEIGHT SPISRAM_TYPE
    7 - All scripts within a specific library should be the first major section the library. Scripts within methods ( Sub, Functions) should not be used.
    8 - All scripts within a specific library should be the first major section the library. Scripts within methods ( Sub, Functions) should not be used.
    9 - Other naming recommendations. Do not use underscores in subroutine, function or variable names

    Example script within a library

     #SCRIPT  'Calculate Delay Time
             __LCD_DELAY  = ( __LCD_TIMEPERIOD - __LCD_DELAYS) - (INT((4/ChipMHZ) * __LCD_INSTRUCTIONS))
            SCRIPT_LCD_POSTWRITEDELAY = __LCD_DELAY
            SCRIPT_LCD_CHECKBUSYFLAG = TRUE
     #ENDSCRIPT
    

    Note: The creation of a constant within a script is similar to creating a variable. In the above example _LCD_DELAY, SCRIPT_LCD_POSTWRITEDELAY, SCRIPT_LCD_CHECKBUSYFLAG are all created.

     
  • Anobium

    Anobium - 2022-09-13

    Maybe this is what you want

    #Script
      IF DEF(QYF_TM1638) Then
        Com_Anode = ""     ' CA Display up to 10x 7-seg digits
        RevDig   = ""    ' Reverse display digits (need for rev wired digits
        Warning "====== QYF_TM1638 board Selected OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(LED_KEY) Then
        Butn_Map1 = ""
        Warning "====== LED_KEY Selected  OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(NEW_BRD) Then
    '     add here
      END IF
    #EndScript
    
     
  • ToniG

    ToniG - 2022-09-13

    "Maybe this is what you want"

    Not really...
    I am not assigning any values to the constants, just the constant name.

    I want to create new constant(s) inside only 1 IF DEF() .... End If block based on 1 defined constant. (so only 1 IF DEF will be true)

    By...
    commenting unwanted #Define:

     #Define Const1 '< 1 previous defined constant.
    // #Const2
    // #Const3
    

    Then test which constant name exist "IF DEF(Const1)" & create specific constant(s) in the test:

    #Script
      IF DEF(Const1) Then
        #DEFINE Com_Anode     ' CA Display up to 10x 7-seg digits
        #DEFINE RevDig       ' Reverse display digits (need for rev wired digits
        Warning "====== QYF_TM1638 board Selected OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(LED_KEY) Then
          #DEFINE Butn_Map1
        Warning "====== LED_KEY Selected  OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(NEW_BRD) Then
    '    #DEFINE Butn_Map2
      END IF
    #EndScript
    

    I know the IF DEF works so there is no issue here. (confirmed with warning messsage)

    So the magic question is: Why is constant Butn_Map1 being created when the second IF DEF is false ?

    To confirm this I comment line #DEFINE Butn_Map1 to stop Butn_Map1 being defined.

    I have tried putting the line #Define Const1 '< 1 defined constant inside the script but same issue.

     
  • Anobium

    Anobium - 2022-09-13

    OK. You cannot use #DEFINE in a script. The #DEFINE will extracted and processed before the script is run. So, you must use an assignment, and, you need to use a null string to create an empty constant.

    #Script
      IF DEF(Const1) Then  
        Com_Anode = ""    ' CA Display up to 10x 7-seg digits
        RevDig = ""       ' Reverse display digits (need for rev wired digits
        Warning "====== QYF_TM1638 board Selected OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(LED_KEY) Then
          Butn_Map1 = ""
        Warning "====== LED_KEY Selected  OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(NEW_BRD) Then
    '    #DEFINE Butn_Map2
      END IF
    #EndScript
    

    Remember, that you are not creating variables within the script but you are creating constants.

    So, is the case above if CONST1 exists then COM_ANODE and REDIG

    Some code to help

    'Chip Settings.
    #CHIP 16F18075
    #OPTION Explicit
    
    Dim var1, var2, var3 as Byte
    
    #DEFINE CONST1
    #DEFINE LED_KEY
    
    
    #Script
      IF DEF(CONST1) Then
        COM_ANODE = ""    ' CA Display up to 10x 7-seg digits
        REVDIG = ""       ' Reverse display digits (need for rev wired digits
        Warning "====== QYF_TM1638 board Selected OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(LED_KEY) Then
          BUTN_MAP1 = ""
        Warning "====== LED_KEY Selected  OK ======"  '< Testing DEF IFDEF
      END IF
      IF DEF(NEW_BRD) Then
    '    #DEFINE Butn_Map2
      END IF
    #EndScript
    
    #IFDEF CONST1
        var1 = 1
    #ELSE
        var3 = 9
    #ENDIF
    
    #IFDEF COM_ANODE
        var2 = 11
    #ELSE
        var2 = 19
    #ENDIF
    
    #IFDEF REVDIG
        var3 = 21
    #ELSE
        var3 = 29
    #ENDIF
    
    #IFDEF LED_KEY
        var3 = 31
    #ELSE
        var3 = 39
    #ENDIF
    
    Do
    Loop
    

    If the latest build you may not be aware but I added a debugger to help.

    Adding conditionaldebugfile = "sourcefileame".gcb to the [gcbasic] section of USE.INI will create an "sourcefileame".cdf file.

    The CDF shows how constants are created, and, now the scripts create constants. and how the conditional statements are processed in the specific source file.

    In the source above you will find a section where the script adds the three constants COM_ANODE, REVDIG and BUTN_MAP1. Later in the CDF you will see the conditional statement results.

    SCRIPT/AddSymbol:   COM_ANODE                                                                                   -1
    SCRIPT/AddSymbol:   REVDIG                                                                                      -1
    SCRIPT/AddSymbol:   BUTN_MAP1         
    

    I hope this helps. Sorry this is hard stuff to explain.

     

    Last edit: Anobium 2022-09-13
  • Anobium

    Anobium - 2022-09-13

    PS - I add the VAR1-VAR4 assignments so you can see in the ASM the results of your script.

     
  • ToniG

    ToniG - 2022-09-13

    Thanks heaps,
    I will digest, rewrite & test

     
  • ToniG

    ToniG - 2022-09-13

    Works perfectly, Thanks.
    I see now Com_Anode = "" creates a constant with null value.

    '        Specific board types (select 1)
    '-------------------------------------------------------------
    // #Define LED_KEY    'for "LED&KEY" module board (Common Cathode display & Btn re-Map)
     #Define QYF_TM1638  'for "QYF-TM1638"  board (Common Anode display & rev. digits)
    // #Define NEW_BRD       '< Add new board here & edit #Script
    '------------------------------------------------------------
    
    #Script
      IF DEF(QYF_TM1638) Then
         Com_Anode = ""    ' CA Display up to 10x 7-seg digits
         RevDig = ""       ' Reverse display digits (need for rev wired digits
      END IF
      IF DEF(LED_KEY) Then
        Com_Cathode = ""
        Butn_Map1 = ""
      END IF
      IF DEF(NEW_BRD) Then
    '     add NEW_Board here
      END IF
    #EndScript
    
     
    • Anobium

      Anobium - 2022-09-13

      And, I did not know this until today... "" creates with a null.

      Did you see the CDF file? Should be useful.

       
  • Anobium

    Anobium - 2022-09-13

    Toni,

    To get the result you want - consider this..

    If the user creates a constant called COM_ANODE is there a risk?

    Without the NODEF(COM_ANODE) the constant within the script will be ignored with a silent failure. It will be shown in the CDF file. The user constant is always processed first until the put in a #IF.. conditional statement ( which is not very likely!).

    ~~~

    Script

    IF DEF(QYF_TM1638) Then
    IF NODEF(Com_Anode) Then
    Com_Anode = "" ' CA Display up to 10x 7-seg digits
    END IF

      IF DEF(Com_Anode) Then 
             Warning "Please delete constant COM_ANODE from the user program"
       END IF
    

    .... rest of code adding the check

    ~~~~

     
  • ToniG

    ToniG - 2022-09-13

    Build 1165

    I don't see a CDF file in my working folder or where the Errors.txt file is .
    & I will look at the NO DEF to check for existing constant
    Thanks

     
  • Anobium

    Anobium - 2022-09-13

    You must Add conditionaldebugfile = "sourcefileame".gcb to the [gcbasic] section of USE.INI this will enable the creation of "sourcefileame".cdf file.

     
  • ToniG

    ToniG - 2022-09-13

    thanks (memory leak again :-)

     
  • ToniG

    ToniG - 2022-09-14

    I use the following now to set default constants...

    ' Default Constants            ( Set if not #Define in Main)
    
    #Script
      IF NODEF(TM_DispLen) Then
        TM_DispLen=8    ' 7seg display No. of digits
      END IF
      IF NODEF(TM_LEDs) Then
        TM_LEDs=0       ' LEDs other than 7Seg display (use high buffer bytes)
      END IF
      IF NODEF(Com_Cathode) And NODEF(Com_Anode) Then ' Set const "Com_Cathode"
        Com_Cathode=""
      END IF
      IF NODEF(TMDly) Then
        TMdly=10       ' clk <-> DIO delay us
      END IF
      IF NODEF(KeyMap) Then
        KeyMap=ButnMap1   ' Sensible button map
      END IF
    #EndScript
    

    Edit:
    This is to address any silent failure from how constants were previously set , thanks for the advise.
    I need to apply this also to the new TMxxx lib files & will update when done.

     

    Last edit: ToniG 2022-09-14
  • Anobium

    Anobium - 2022-09-14

    ok. You can see these being created in the CDF report.

     
  • Anobium

    Anobium - 2023-09-16

    CDF file - How to manage in Preferences Editor and what is in the CDF.

    A short video showing using the Preferences Editor to manage the production of the Constants&Configuration Definition File (CDF).

    Build 1283, or later, exposes the CDF management in the Preferences Editor.


    YouTube URL:


    The CDF provide insights into how the compiler creates and manages Constants, which Scripts are creating and managing Constants, and how Conditional Compilation is executing specific segments of your program and the libraries.

    The information provided is:

    CODE/Constant - constants defined in a user program or library
    SCRIPT/AddConstant constants defined in a #script/#endscript construct
    SCRIPT/CurrentValue - constants already defined then redefined in another #script/#endscript construct
    CHECKSYSVARDEF - expansion of a mutli-condition conditional test.

    The remainder of CDF report is the user program or libaries code remaining post conditional processing.

     

    Last edit: Anobium 2023-09-16

Log in to post a comment.