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
'Specificboardtypes(select1)'-------------------------------------------------------------// #Define NEW_BRD ' Add new board here// #Define LED_KEY 'for "LED&KEY" module board (Common Cathode display & Btn re-Map)#DefineQYF_TM1638'for"QYF-TM1638"board(CommonAnodedisplay&rev.digits)'------------------------------------------------------------#ScriptIFDEF(QYF_TM1638)Then#DefineCom_Anode'CADisplayupto10x7-segdigits#DefineRevDig'Reversedisplaydigits(needforrevwireddigitsWarning"====== QYF_TM1638 board Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(LED_KEY)Then#DefineButn_Map1Warning"====== LED_KEY Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(NEW_BRD)Then'addhereENDIF#EndScript
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 constantSCRIPT_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
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
#ScriptIFDEF(QYF_TM1638)ThenCom_Anode=""'CADisplayupto10x7-segdigitsRevDig=""'Reversedisplaydigits(needforrevwireddigitsWarning"====== QYF_TM1638 board Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(LED_KEY)ThenButn_Map1=""Warning"====== LED_KEY Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(NEW_BRD)Then'addhereENDIF#EndScript
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
#ScriptIFDEF(Const1)Then#DEFINECom_Anode'CADisplayupto10x7-segdigits#DEFINERevDig'Reversedisplaydigits(needforrevwireddigitsWarning"====== QYF_TM1638 board Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(LED_KEY)Then#DEFINEButn_Map1Warning"====== LED_KEY Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(NEW_BRD)Then'#DEFINEButn_Map2ENDIF#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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
#ScriptIFDEF(Const1)ThenCom_Anode=""'CADisplayupto10x7-segdigitsRevDig=""'Reversedisplaydigits(needforrevwireddigitsWarning"====== QYF_TM1638 board Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(LED_KEY)ThenButn_Map1=""Warning"====== LED_KEY Selected OK ======"'<TestingDEFIFDEFENDIFIFDEF(NEW_BRD)Then'#DEFINEButn_Map2ENDIF#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 ExplicitDimvar1,var2,var3asByte#DEFINE CONST1#DEFINE LED_KEY#ScriptIFDEF(CONST1)ThenCOM_ANODE=""' CA Display up to 10x 7-seg digitsREVDIG=""' Reverse display digits (need for rev wired digitsWarning"====== QYF_TM1638 board Selected OK ======"'< Testing DEF IFDEFENDIFIFDEF(LED_KEY)ThenBUTN_MAP1=""Warning"====== LED_KEY Selected OK ======"'< Testing DEF IFDEFENDIFIFDEF(NEW_BRD)Then' #DEFINE Butn_Map2ENDIF#EndScript#IFDEF CONST1var1=1#ELSEvar3=9#ENDIF#IFDEF COM_ANODEvar2=11#ELSEvar2=19#ENDIF#IFDEF REVDIGvar3=21#ELSEvar3=29#ENDIF#IFDEF LED_KEYvar3=31#ELSEvar3=39#ENDIFDoLoop
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.
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
IFDEF(Com_Anode)ThenWarning"Please delete constant COM_ANODE from the user program"ENDIF
.... rest of code adding the check
~~~~
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I use the following now to set default constants...
' Default Constants ( Set if not #Define in Main)#ScriptIFNODEF(TM_DispLen)ThenTM_DispLen=8' 7seg display No. of digitsENDIFIFNODEF(TM_LEDs)ThenTM_LEDs=0' LEDs other than 7Seg display (use high buffer bytes)ENDIFIFNODEF(Com_Cathode)AndNODEF(Com_Anode)Then' Set const "Com_Cathode"Com_Cathode=""ENDIFIFNODEF(TMDly)ThenTMdly=10' clk <-> DIO delay usENDIFIFNODEF(KeyMap)ThenKeyMap=ButnMap1' Sensible button mapENDIF#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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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
The script construct is
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
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.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:
Then test which constant name exist "IF DEF(Const1)" & create specific constant(s) in the test:
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 stopButn_Map1
being defined.I have tried putting the line
#Define Const1 '< 1 defined constant
inside the script but same issue.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.
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
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.
I hope this helps. Sorry this is hard stuff to explain.
Last edit: Anobium 2022-09-13
PS - I add the VAR1-VAR4 assignments so you can see in the ASM the results of your script.
Thanks heaps,
I will digest, rewrite & test
Works perfectly, Thanks.
I see now
Com_Anode = ""
creates a constant with null value.And, I did not know this until today... "" creates with a null.
Did you see the CDF file? Should be useful.
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
.... rest of code adding the check
~~~~
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
You must Add conditionaldebugfile = "sourcefileame".gcb to the [gcbasic] section of USE.INI this will enable the creation of "sourcefileame".cdf file.
thanks (memory leak again :-)
I use the following now to set default constants...
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
ok. You can see these being created in the CDF report.
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