Eric,
Were there changes to loadp2 from version 3.9.31 to 3.9.33?
v3.9.33 fails to run programs that run fine with v3.9.31
pnut compiles and loads/runs fine. I have compared the fastspin and pnut binarys and they are fine.
Yes, there were changes to support the new P2 ES boards. My original P2 ES board still works though.
What problems exactly are you having? What command line are you using for loadp2, and what symptoms do you see? Does the -SINGLE mode (using the ROM loader work for you)?
Looks like the compile error message format was changed, right?
Yes, this was intentional. The old code had a mix of compiler error messages -- the preprocessor used one format and the main compiler used a different one. I changed the main compiler to match the preprocessor, which also happens to match the format used by GCC and other C compilers, so it's somewhat standard.
In flexgui to find error lines I look for "error:" and then back up to look at preceding ":" to find the line number and file name.
Eric,
Were there changes to loadp2 from version 3.9.31 to 3.9.33?
v3.9.33 fails to run programs that run fine with v3.9.31
pnut compiles and loads/runs fine. I have compared the fastspin and pnut binarys and they are fine.
Yes, there were changes to support the new P2 ES boards. My original P2 ES board still works though.
What problems exactly are you having? What command line are you using for loadp2, and what symptoms do you see? Does the -SINGLE mode (using the ROM loader work for you)?
I recompiled this simple program with pnut.
If pnut or loadp2 (called L31.exe) load this obj file then the P56 LED flashes and a message is output every second.
I looadp2 (called L33.exe) load this object, the LED flashes but there is no serial output (on the loadp2 terminal or PST)
The program is NOT sending serial as there is no tiny flash on the P62 LED. I've found other instances where my test led is not flashing.
Seems like a download corruption even tho no errors are reported.
l33 autodetect_p2ev.obj -b115200 -t
This works..
l33 autodetect_p2ev.obj -b115200 -t -SINGLE
I use the serial and debug code in ROM. It is the same program as I posted above with this change to force P2EV detection.
@ersmith When using FlexGui version 3.9.33 and writing in FlexBASIC:
If you DIM a variable at the module level, it is initialized appropriately, ie, an INTEGER or LONG type gets set to zero, and a string is set to a zero-length/empty string (i.e ""). This is the expected behavior. However, if you DIM a variable in a SUB or FUNCTION, it is not initialized at all and will contain whatever was in that memory location before it was allocated.
Can we make variable initialization behavior symmetrical between the module-level code and the SUB/FUNCTION level code? In otherwords, always set numerics to zero and strings to zero-length/empty when they are DIM'd?
I recompiled this simple program with pnut.
If pnut or loadp2 (called L31.exe) load this obj file then the P56 LED flashes and a message is output every second.
I looadp2 (called L33.exe) load this object, the LED flashes but there is no serial output (on the loadp2 terminal or PST)
The program is NOT sending serial as there is no tiny flash on the P62 LED. I've found other instances where my test led is not flashing.
Seems like a download corruption even tho no errors are reported.
It looks like there are some timing problems with the fast download path. Sometimes the downloader misses the first few bytes of the download and hangs waiting for the rest (so your program never starts).
I'm trying to figure out why this is happening -- it seems to be much more frequent at 115200 baud, I hadn't seen it at 230400 before, although there are a few strange glitches sometimes that may be the same thing.
@ersmith When using FlexGui version 3.9.33 and writing in FlexBASIC:
If you DIM a variable at the module level, it is initialized appropriately, ie, an INTEGER or LONG type gets set to zero, and a string is set to a zero-length/empty string (i.e ""). This is the expected behavior. However, if you DIM a variable in a SUB or FUNCTION, it is not initialized at all and will contain whatever was in that memory location before it was allocated.
There's never any guarantee of what's in a variable -- if you want it to be zero you should set it to zero explicitly. Most of memory happens to be zero, so that's what you've seen, but that's not guaranteed by the language.
Changing functions to always initialize variables to 0 would probably increase code size and slow things down.
@ersmith When using FlexGui version 3.9.33 and writing in FlexBASIC:
If you DIM a variable at the module level, it is initialized appropriately, ie, an INTEGER or LONG type gets set to zero, and a string is set to a zero-length/empty string (i.e ""). This is the expected behavior. However, if you DIM a variable in a SUB or FUNCTION, it is not initialized at all and will contain whatever was in that memory location before it was allocated.
There's never any guarantee of what's in a variable -- if you want it to be zero you should set it to zero explicitly. Most of memory happens to be zero, so that's what you've seen, but that's not guaranteed by the language.
Changing functions to always initialize variables to 0 would probably increase code size and slow things down.
OK. That works for me. I was thinking you intended for FlexBASIC to behave in a manner similar to FreeBASIC, and this initialization is one of the behaviors that FreeBASIC exhibits. From the FBWiki at https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgDim:
"Arrays, variables, strings, and user defined types (UDTs) are initialized to zero (or False for Boolean) or null strings by default when they are created".
"To avoid the overhead of default variable initialization, the Any initializer can be used with Dim to tell the compiler to only reserve the place for the variable in memory but not initialize it, so the variable will contain garbage. In this case the programmer should not make assumptions about the initial values".
OK. That works for me. I was thinking you intended for FlexBASIC to behave in a manner similar to FreeBASIC, and this initialization is one of the behaviors that FreeBASIC exhibits. From the FBWiki at https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgDim: "Arrays, variables, strings, and user defined types (UDTs) are initialized to zero (or False for Boolean) or null strings by default when they are created".
"To avoid the overhead of default variable initialization, the Any initializer can be used with Dim to tell the compiler to only reserve the place for the variable in memory but not initialize it, so the variable will contain garbage. In this case the programmer should not make assumptions about the initial values".
It's fairly common, but not universal, for compilers to clear all VAR memory (eg up to stack) as part of INIT pass, so that will implicitly clear on startup.
That pass is separate from loading to values <> 0, if those are specified & `clear all` code can be very compact.
It's also common for compilers to treat local vars inside functions, as overlayable, and that means their initial value cannot be assumed for every call.
ie Only the first function call that uses that address will initially see a 0, later calls, and other functions, have ?? in the var address.
I recompiled this simple program with pnut.
If pnut or loadp2 (called L31.exe) load this obj file then the P56 LED flashes and a message is output every second.
I looadp2 (called L33.exe) load this object, the LED flashes but there is no serial output (on the loadp2 terminal or PST)
The program is NOT sending serial as there is no tiny flash on the P62 LED. I've found other instances where my test led is not flashing.
Seems like a download corruption even tho no errors are reported.
It looks like there are some timing problems with the fast download path. Sometimes the downloader misses the first few bytes of the download and hangs waiting for the rest (so your program never starts).
I'm trying to figure out why this is happening -- it seems to be much more frequent at 115200 baud, I hadn't seen it at 230400 before, although there are a few strange glitches sometimes that may be the same thing.
A few revisions ago I had problems with not sending the whole binary. This happened because I didn't wait for the serial buffer to fully empty before changing from the loader baud rate to the user baud rate. I added a wait_drain() function to handle this, which called tcdrain() on Linux systems and msleep(100) on Windows. The msleep(100) is not long enough for low baud rates. Maybe something changed between rev 31 and 32 that affected the timeouts.
IIRC correctly, hub is initialised to all 0's on powerup but a reset does not clear the hub so what was there remains.
There is no async reset on RAM (that costs too much die area) so any memory clear needs to be software based.
That means it should behave the same on reset, as on powerup ?
Compilers also often include code to clear the VAR space they use, which is in the startup before main() or the equiv.
Changing functions to always initialize variables to 0 would probably increase code size and slow things down.
That's ok... it just should be documented (-: in bold letters? :-) because it deviates from what we are used to e.g. in HomeSpun, BSTC and OpenSpin.
Edit 201909301100UTC: I mixed up zeroing at program start and zeroing on each function call here.
Changing functions to always initialize variables to 0 would probably increase code size and slow things down.
That's ok... it just should be documented (-: in bold letters? :-) because it deviates from what we are used to e.g. in HomeSpun, BSTC and OpenSpin.
I agree the documentation is the more important part. It isnt hard to programatically clear a variable, as long as you know that such an action is needed.
Assumptions are tricky things. I assumed since FlexBASIC was being implemented along the lines of FreeBASIC, that it would follow the same conventions. Compounding this belief was the anecdotal evidence that the compiler had been clearing variables. For weeks I had accidently gotten away with not clearing variables without ill effects. Today my good luck finally ran out.
I think this just needs a quick note in the docs to “fix” the “problem”. The fact that FlexBASIC does not clear memory or initialize variables may even be useful at some point.
yeah, my guess is that the stack in bytecode spin and all compilers is either zeroed or relies on being zero at boot time.
So the first call work. After that you don't now.
Basically the same with PASM. A res variable contains whatever is behind the DAT block in the Spin Image.
One thing is different here, GLOBAL vars you put into a VAR section in SPIN do get initialized to zero at program load.
I don't know why. That difference. I like the freebasic version somehow attribute ANY - but does it really makes a difference?
I think it does and explain:
You would need to write ANY for all the declarations to avoid code produced to init the variable. We are all lazy so we will not do that consequently and produce bigger binaries. But if you need to write code to init the var you think about if you really need that one - so smaller code.
...
I think this just needs a quick note in the docs to “fix” the “problem”. The fact that FlexBASIC does not clear memory or initialize variables may even be useful at some point.
Global (shared) variables may be accessed from anywhere in the program, and exist for the duration of the program. They are created with the dim shared declaration, and may be given an initial value.
Member variables are automatically initialized to 0, and may not be initialized to any other value.
Local variables may be initialized to values, but this initialization is done at run time so it has some overhead.
@ersmith : is it still true that member variables are initialized to 0?
When using FlexGui version 3.9.33 and writing in FlexBASIC:
const cTemp = 3_000.123456 <-- this works fine
const cTemp = 3000.123_456 <-- error: syntax error, unexpected identifier `_456', expecting $end or end of
line or end or ':'
var cTemp = 3_000.123456 <-- this works fine
var cTemp = 3000.123_456 <-- error: syntax error, unexpected identifier `_456', expecting $end or end of
line or end or ':'
The manual says:
Integers
Decimal integers are a sequence of digits, 0-9. Hexadecimal (base 16) integers start with the sequence "&h", "0h", or "0x" followed by digits and/or the letters A-F or a-f. Binary (base 2) integers start with the sequence "&b" or "0b" followed by the digits 0 and 1. Numbers may contain underscores anywhere to separate digits; those underscores are ignored.
The manual clearly references underscores only within the context of talking about "integers" (there is no similar discussion for floats/SINGLEs), so this really isn't a bug. However, since an underscore can appear to the left of the decimal, but not to the right of the decimal, it seems appropriate to raise this issue based on consistency.
Global (shared) variables may be accessed from anywhere in the program, and exist for the duration of the program. They are created with the dim shared declaration, and may be given an initial value.
Member variables are automatically initialized to 0, and may not be initialized to any other value.
Local variables may be initialized to values, but this initialization is done at run time so it has some overhead.
@ersmith : is it still true that member variables are initialized to 0?
Whoops, that line is mistaken -- it's based on an older version of FlexBASIC where there were only very limited uses possible for classes. Now that classes can be used for any kind of variable (including local variables within functions) it's no longer true that member variables are always initialized to 0. Thanks for pointing that out, I'll fix the documentation.
When using FlexGui version 3.9.33 and writing in FlexBASIC:
const cTemp = 3_000.123456 <-- this works fine
const cTemp = 3000.123_456 <-- error: syntax error, unexpected identifier `_456', expecting $end or end of
line or end or ':'
var cTemp = 3_000.123456 <-- this works fine
var cTemp = 3000.123_456 <-- error: syntax error, unexpected identifier `_456', expecting $end or end of
line or end or ':'
That's an oversight. Thanks for bringing it to my attention!
@ersmith Really minor stuff here, but I'll post it anyway in case you get inspired during the next release cycle.
1). The Undo/Redo in the FlexGUI editor seems to be broken. In the last revision there was one level of Undo/Redo that was functional (if memory serves). Undo/Redo seems to have no effect now.
2). Consider adding two things to FlexGUI's user interface:
- Add a "Replace" function to supplement the "Find" capability in the Search widget.
- When you right-click a file tab, add a "Close" function to the existing Cut/Copy/Paste/Undo/Save/Save As widget.
1). The Undo/Redo in the FlexGUI editor seems to be broken. In the last revision there was one level of Undo/Redo that was functional (if memory serves). Undo/Redo seems to have no effect now.
Whoops, a typo I think. There's a line in gui.tcl that reads:
(It's in the setupFramedText procedure, near line 440). If you add "-undo 1" to the end of that then the Undo/Redo should work again.
2). Consider adding two things to FlexGUI's user interface:
- Add a "Replace" function to supplement the "Find" capability in the Search widget.
- When you right-click a file tab, add a "Close" function to the existing Cut/Copy/Paste/Undo/Save/Save As widget.
The "Close" should be easy, it's just adding an entry to the .popup1 menu, something like:
@ersmith I've had some minor issues with flexgui, running on macOS. The buttons on the edit screen as well as the Configure Commands screen do not show up until I manipulate the UI (resize the window, click in the edit fields, etc.) with the mouse. So, on each execution of flexgui and selection of Configure Commands, the buttons need to be "resurrected" with the mouse... Seems to just happen on macOS, as I ran flexgui on Linux & WIN10 without the problems.
To temporarily fix the problems I added several small changes in gui.tcl that have gotten the buttons to display... Here's an example:
# added Tk requirement
package require Tk
#...
# added "ttk::" to each button creation
ttk::button .toolbar.compile -text "Compile" -command doCompile
ttk::button .toolbar.runBinary -text "Run Binary" -command doLoadRun
ttk::button .toolbar.compileRun -text "Compile & Run" -command doCompileRun
#...
ttk::button .runopts.change.p2a -text "P2a defaults" -command setShadowP2aDefaults
ttk::button .runopts.change.p2b -text "P2b defaults" -command setShadowP2bDefaults
ttk::button .runopts.change.p1 -text "P1 defaults" -command setShadowP1Defaults
#...
ttk::button .runopts.end.ok -text " OK " -command {copyShadowClose .runopts}
ttk::button .runopts.end.cancel -text " Cancel " -command {wm withdraw .runopts}
# one more minor issue is the small input fields for the Configure Commands compile & run options...
# expand width of input fields from 32 to 72 chars.
entry .runopts.a.compiletext -width 72 -textvariable shadow(compilecmd)
#...
entry .runopts.b.runtext -width 72 -textvariable shadow(runcmd)
Not sure if this was a good solution and how it might effect flexgui on other platforms. You may have a much better solution. The button issue is probably in the macOS version of Tcl/Tk, as I witnessed the same problem in other Tcl/Tk code on macOS.
Besides the fixes above, it has a new loadp2 that allows the loader and user program to have different baud rates on Linux. With that change the loader now defaults to 921600 baud download speed, which is nice. There are also some improvements to allow integration with the Windows desktop and to let flexgui run from a directory other than its "home" directory.
If you get a chance please try the preview out and let me know of any problems you find.
@ersmith When using FlexGui version 4.0.0-beta and writing in FlexBASIC for a P1:
A BASIC file that contains only FUNCTIONs and SUBs can not be compiled. This error results: error: could not find function program
This code will generate the error:
OPTION EXPLICIT
const cPI = 3.14159
FUNCTION Echo1(anyString as string) as string
'just return the string that was supplied
return AnyString
END FUNCTION
FUNCTION Echo2(anyString as string) as string
'just return the string that was supplied
return AnyString
END FUNCTION
The error does NOT occur if you put a single line of code in the main part of the program, like this:
OPTION EXPLICIT
const cPI = 3.14159
print "hi!" '<-- adding this line makes it all better. It could be anything, really...
FUNCTION Echo1(anyString as string) as string
'just return the string that was supplied
return AnyString
END FUNCTION
FUNCTION Echo2(anyString as string) as string
'just return the string that was supplied
return AnyString
END FUNCTION
My goal is to have standalone libraries ("StringLib.bas" for string handling, "Math.bas" for advanced math, etc) that contain routines (ATAN, SIN, INSTR$, etc) that can be called by other programs via #INCLUDE "myLib.bas". In order to fully debug these libraries, I need to do a test-compile on them as a final sanity check. Since libraries dont have a "main" routine per se, this error is problematic.
Includes and libraries are different concepts. Both won't get compiled on their own in FlexBASIC.
Libraries are external classes (objects):
File "basic-library.bas":
function martian_quotient(m as single, n as single) as single
martian_quotient = n / m
end function
File "basic-library-test.bas":
dim mars as class using "basic-library.bas"
print mars.martian_quotient(113, 355)
Build it:
$ fastspin basic-library-test.bas -o basic-library-test.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 4.0.0-beta-317bfbe5 Compiled on: Oct 5 2019
basic-library-test.bas
|-basic-library.bas
fmt.c
strcpy.c
strlen.c
basic-library-test.bas.pasm
Done.
Program size is 8352 bytes
Run it:
spinsim -b basic-library-test.bas.binary
3.1420
"#include" is just a text operation inlining the included files contents into the program. This will need no external compile either.
Functions from (external) classes have their own namespace, functions from #include files just are literally part of the program's namespace.
If you want to test compile a library which shall be used as #include file, just add some test code wrapped in e.g. "#ifdef selftest"/"#endif" and add defining "selftest" ("-D selftest") to the compiler options.
@ersmith When using FlexGui version 4.0.0-beta and writing in FlexBASIC for a P1:
A BASIC file that contains only FUNCTIONs and SUBs can not be compiled. This error results: error: could not find function program
My goal is to have standalone libraries ("StringLib.bas" for string handling, "Math.bas" for advanced math, etc) that contain routines (ATAN, SIN, INSTR$, etc) that can be called by other programs via #INCLUDE "myLib.bas". In order to fully debug these libraries, I need to do a test-compile on them as a final sanity check. Since libraries dont have a "main" routine per se, this error is problematic.
As @yeti suggested, the best way to do this is to provide some actual test code in the library file, and compile with that test code enabled. That way you can also test the functionality of the code, not just whether it compiles. (Since fastspin eliminates unused methods, even if you could compile a file with no actual functions it would produce an empty output and wouldn't do all the checking it could on the unused methods.)
If you're only using "class using" (and not #include) you can skip the #ifdef around test code. In that case anything in the top level of the library class will be put into a subroutine called "program". That is:
' mylib.bas
sub greet(msg as string)
print msg
end sub
greet "hello, world"
' main.bas
dim G as class using "mylib.bas"
G.greet("hello")
G.greet("goodbye")
In this case if you compile and run just "mylib.bas" it will print "hello, world" as a test. If you compile and run "main.bas" it will print "hello" and then "goodbye". The class G will contain two subroutines, G.greet and G.program. G.program is the test program that prints "hello, world". Since it isn't actually used in main.bas it will be removed automatically by the compiler (just like any unused subroutine).
@ersmith When using FlexGui version 4.0.0-beta and writing in FlexBASIC for a P1 under Win10:
The following program bricks the compiler and the editor, and after a few seconds causes Windows to give a "not responding" error:
CONST clkfreq = 80_000_000
print "hi"
Attempting to set CLKFREQ to a CONSTant is a programmer error, but ideally this should get trapped and throw a compile-time error instead of hanging FlexGUI.
Comments
Yes, there were changes to support the new P2 ES boards. My original P2 ES board still works though.
What problems exactly are you having? What command line are you using for loadp2, and what symptoms do you see? Does the -SINGLE mode (using the ROM loader work for you)?
In flexgui to find error lines I look for "error:" and then back up to look at preceding ":" to find the line number and file name.
I recompiled this simple program with pnut.
If pnut or loadp2 (called L31.exe) load this obj file then the P56 LED flashes and a message is output every second.
I looadp2 (called L33.exe) load this object, the LED flashes but there is no serial output (on the loadp2 terminal or PST)
The program is NOT sending serial as there is no tiny flash on the P62 LED. I've found other instances where my test led is not flashing.
Seems like a download corruption even tho no errors are reported.
l33 autodetect_p2ev.obj -b115200 -t
This works..
l33 autodetect_p2ev.obj -b115200 -t -SINGLE
I use the serial and debug code in ROM. It is the same program as I posted above with this change to force P2EV detection.
If you DIM a variable at the module level, it is initialized appropriately, ie, an INTEGER or LONG type gets set to zero, and a string is set to a zero-length/empty string (i.e ""). This is the expected behavior. However, if you DIM a variable in a SUB or FUNCTION, it is not initialized at all and will contain whatever was in that memory location before it was allocated.
Can we make variable initialization behavior symmetrical between the module-level code and the SUB/FUNCTION level code? In otherwords, always set numerics to zero and strings to zero-length/empty when they are DIM'd?
I'm trying to figure out why this is happening -- it seems to be much more frequent at 115200 baud, I hadn't seen it at 230400 before, although there are a few strange glitches sometimes that may be the same thing.
Changing functions to always initialize variables to 0 would probably increase code size and slow things down.
OK. That works for me. I was thinking you intended for FlexBASIC to behave in a manner similar to FreeBASIC, and this initialization is one of the behaviors that FreeBASIC exhibits. From the FBWiki at https://www.freebasic.net/wiki/wikka.php?wakka=KeyPgDim:
On to pillage!
It's fairly common, but not universal, for compilers to clear all VAR memory (eg up to stack) as part of INIT pass, so that will implicitly clear on startup.
That pass is separate from loading to values <> 0, if those are specified & `clear all` code can be very compact.
It's also common for compilers to treat local vars inside functions, as overlayable, and that means their initial value cannot be assumed for every call.
ie Only the first function call that uses that address will initially see a 0, later calls, and other functions, have ?? in the var address.
When you say 'happens to be zero' does that mean there is already a `clear RAM` pass done ?
There is no async reset on RAM (that costs too much die area) so any memory clear needs to be software based.
That means it should behave the same on reset, as on powerup ?
Compilers also often include code to clear the VAR space they use, which is in the startup before main() or the equiv.
Edit 201909301100UTC: I mixed up zeroing at program start and zeroing on each function call here.
Actually no.
Spin does not set local variables to anything, except RESULT which is set to 0.
Mike
I agree the documentation is the more important part. It isnt hard to programatically clear a variable, as long as you know that such an action is needed.
Assumptions are tricky things. I assumed since FlexBASIC was being implemented along the lines of FreeBASIC, that it would follow the same conventions. Compounding this belief was the anecdotal evidence that the compiler had been clearing variables. For weeks I had accidently gotten away with not clearing variables without ill effects. Today my good luck finally ran out.
I think this just needs a quick note in the docs to “fix” the “problem”. The fact that FlexBASIC does not clear memory or initialize variables may even be useful at some point.
So the first call work. After that you don't now.
Basically the same with PASM. A res variable contains whatever is behind the DAT block in the Spin Image.
One thing is different here, GLOBAL vars you put into a VAR section in SPIN do get initialized to zero at program load.
I don't know why. That difference. I like the freebasic version somehow attribute ANY - but does it really makes a difference?
I think it does and explain:
You would need to write ANY for all the declarations to avoid code produced to init the variable. We are all lazy so we will not do that consequently and produce bigger binaries. But if you need to write code to init the var you think about if you really need that one - so smaller code.
Mike
https://github.com/totalspectrum/spin2cpp/blob/af4ed633585275b3da391c73a5ef7a412860a876/doc/basic.md#global-member-and-local-variables
@ersmith : is it still true that member variables are initialized to 0?
The manual says: The manual clearly references underscores only within the context of talking about "integers" (there is no similar discussion for floats/SINGLEs), so this really isn't a bug. However, since an underscore can appear to the left of the decimal, but not to the right of the decimal, it seems appropriate to raise this issue based on consistency.
Whoops, that line is mistaken -- it's based on an older version of FlexBASIC where there were only very limited uses possible for classes. Now that classes can be used for any kind of variable (including local variables within functions) it's no longer true that member variables are always initialized to 0. Thanks for pointing that out, I'll fix the documentation.
@ersmith Really minor stuff here, but I'll post it anyway in case you get inspired during the next release cycle.
1). The Undo/Redo in the FlexGUI editor seems to be broken. In the last revision there was one level of Undo/Redo that was functional (if memory serves). Undo/Redo seems to have no effect now.
2). Consider adding two things to FlexGUI's user interface:
- Add a "Replace" function to supplement the "Find" capability in the Search widget.
- When you right-click a file tab, add a "Close" function to the existing Cut/Copy/Paste/Undo/Save/Save As widget.
The "Close" should be easy, it's just adding an entry to the .popup1 menu, something like: Not sure about the replace function, but the searchrep widget seems to have that functionality, so I'll look into that.
To temporarily fix the problems I added several small changes in gui.tcl that have gotten the buttons to display... Here's an example:
Not sure if this was a good solution and how it might effect flexgui on other platforms. You may have a much better solution. The button issue is probably in the macOS version of Tcl/Tk, as I witnessed the same problem in other Tcl/Tk code on macOS.
Thanks,
dgately
@JRoark: I have a simple replace function that seems to work now. It's in the preview release (see below).
All: I've posted a 4.0.0-preview release to
https://github.com/totalspectrum/flexgui/releases
Besides the fixes above, it has a new loadp2 that allows the loader and user program to have different baud rates on Linux. With that change the loader now defaults to 921600 baud download speed, which is nice. There are also some improvements to allow integration with the Windows desktop and to let flexgui run from a directory other than its "home" directory.
If you get a chance please try the preview out and let me know of any problems you find.
A BASIC file that contains only FUNCTIONs and SUBs can not be compiled. This error results: error: could not find function program
This code will generate the error:
The error does NOT occur if you put a single line of code in the main part of the program, like this:
My goal is to have standalone libraries ("StringLib.bas" for string handling, "Math.bas" for advanced math, etc) that contain routines (ATAN, SIN, INSTR$, etc) that can be called by other programs via #INCLUDE "myLib.bas". In order to fully debug these libraries, I need to do a test-compile on them as a final sanity check. Since libraries dont have a "main" routine per se, this error is problematic.
Libraries are external classes (objects):
File "basic-library.bas": File "basic-library-test.bas": Build it: Run it:
"#include" is just a text operation inlining the included files contents into the program. This will need no external compile either.
Functions from (external) classes have their own namespace, functions from #include files just are literally part of the program's namespace.
If you want to test compile a library which shall be used as #include file, just add some test code wrapped in e.g. "#ifdef selftest"/"#endif" and add defining "selftest" ("-D selftest") to the compiler options.
As @yeti suggested, the best way to do this is to provide some actual test code in the library file, and compile with that test code enabled. That way you can also test the functionality of the code, not just whether it compiles. (Since fastspin eliminates unused methods, even if you could compile a file with no actual functions it would produce an empty output and wouldn't do all the checking it could on the unused methods.)
If you're only using "class using" (and not #include) you can skip the #ifdef around test code. In that case anything in the top level of the library class will be put into a subroutine called "program". That is: In this case if you compile and run just "mylib.bas" it will print "hello, world" as a test. If you compile and run "main.bas" it will print "hello" and then "goodbye". The class G will contain two subroutines, G.greet and G.program. G.program is the test program that prints "hello, world". Since it isn't actually used in main.bas it will be removed automatically by the compiler (just like any unused subroutine).
The following program bricks the compiler and the editor, and after a few seconds causes Windows to give a "not responding" error: Attempting to set CLKFREQ to a CONSTant is a programmer error, but ideally this should get trapped and throw a compile-time error instead of hanging FlexGUI.
FWIW, I'm *really* liking the 4.0.0-beta!
Thanks for the bug report!