@ersmith It appears the variable "cnt" is defined somewhere within the bowels of the compiler.
Example code:
var cnt = 3
print "This is a test"
print cnt
Running this code produces: "warning: definition of cnt hides a member variable".
Looking at the FlexBASIC docs it appears cnt is reserved since it appears on Page 7 under "LANGUAGE SYNTAX 7 / Predefined functions and variables". But that is the only mention of "cnt" in the entire manual (except for its use as a normal variable in some of the examples).
So the question is, is cnt an orphan from days gone past, a hint of a new feature as yet unimplemented, or is it a keyword/feature/function that got missed and should be documented?
EDIT: After a bit of noodling, it appears that cnt() is an undocumented alias for the getCnt() function.
Less undocumented, more of a Spin1-ism that somehow (intentionally?) finds its way into P2 BASIC
Thats what I think too.
Honestly, I rather like Cnt() over GetCnt() because the “get” sort of implies to a new coder there might be a SetCnt() lurking somewhere. But it is all good as long as it is documented.
The compiler has historically handled this juggling nicely so it was a non-issue until Eric implemented the -Wall option. Now we have much more information about potential conflicts at out disposal. (It was an eyeopener to see page after page of warnings issued by 4.2.5 compiling my libraries that had long been considered as “tested and good”).
Warnings are a good thing. What would be even better is some sort of "show definition of this" function. In Code::Blocks I can right click on any identifier and choose "show declaration" or "show implementation" from the popup menu. This is especially useful for C where the namespace is flat and it's sometimes not easy to find out where an identifier has already declared before if you have a large project or include a large library.
@ersmith It appears the variable "cnt" is defined somewhere within the bowels of the compiler.
Yes, and the warning about re-defining it is bogus (you should be able to redefine weak aliases of this sort). I'll fix that in the next release. Meanwhile, just ignore the warning.
Warnings are a good thing. What would be even better is some sort of "show definition of this" function. In Code::Blocks I can right click on any identifier and choose "show declaration" or "show implementation" from the popup menu. This is especially useful for C where the namespace is flat and it's sometimes not easy to find out where an identifier has already declared before if you have a large project or include a large library.
FlexGUI is a poor IDE, no question about that. I think it would be nice if someone would take Code::Blocks or Visual Studio Code or some proper IDE like that and adapt it to use fastspin as the compiler.
VS Code already supports fastspin!... By way of not really supporting any compiler in particular and not really knowing or caring about your build system. You just set up a task with the commands to compile/run your project and off you go.
For example, this is the task I use to compile+run the PC version of that game for which I have no good title yet:
Notice how it just calls the "run" task on my Rakefile. This could be literally any command.
Now the C++ extension (which contains all the IDE features like definition lookup) is a bit more involved and needs a bunch of information about the compiler to perform at it's best, but as far as I could tell in a quick test, seems to do reasonably fine without any. It will just assume whatever defaults it has for things like sizeof(void*) though. If you do give it a compiler path, it will apparently somehow gather this information from it. Not sure how that exactly works, but it probably requires a gcc-like commandline interface. I assume it compiles some code and then tries to inspect the resulting binary? IDK.
The big problem here is that it will all go haywire if you use the more... distinct... fastspin-isms, like struct __using, fastspin-style unquoted inline asm, etc, because the tools it uses internally only understand GCC/clang/VisualC++ brand nonstandard syntax. One will also have to explicitly define all the builtins somewhere, oterwise it'll be very sad when you use them.
@ersmith It appears that PI is pre-defined in FlexBASIC (weak alias), but this feature isn't reflected in the docs. Perhaps add a mention in the next release cycle?
@ersmith It appears that PI is pre-defined in FlexBASIC (weak alias), but this feature isn't reflected in the docs. Perhaps add a mention in the next release cycle?
What looks good about it is that it is nearly instant and doesn't affect Spin or PASM timing barely at all.
Also, you can turn it all off and on very easily. That's maybe the best part.
Yeah having a printf capability accessible from PASM should be pretty helpful if the overhead is low. Timing critical PASM may be impacted but I could certainly see a use for it during initial development of PASM objects where the code's logic might be wrong and you are hunting down a bug. It probably would have been very good in debugging my memory driver with a couple of issues I ran into where I had resorted to LEDs to pinpoint problems (still a usable technique but a little slower to use sometimes and hard to show actual data/address values).
A full interactive debugger would be cool too. If we do get self hosted setups one day it might even be possible to integrate directly instead of needing an external PC and we could have minimal delay and direct memory access from a debug COG. It would be nice to have something like we had with the old TurboDebugger app on a PC where the dev tool and debugger is fairly nicely integrated with full symbols/source/regs etc. Of course this is mostly pie in the sky stuff and we should also have external serial debuggers, probably as the first priority.
Yeah having a printf capability accessible from PASM should be pretty helpful if the overhead is low. Timing critical PASM may be impacted but I could certainly see a use for it during initial development of PASM objects where the code's logic might be wrong and you are hunting down a bug. It probably would have been very good in debugging my memory driver with a couple of issues I ran into where I had resorted to LEDs to pinpoint problems (still a usable technique but a little slower to use sometimes and hard to show actual data/address values)..
I've been thinking there may be useful middle ground between LEDs and printf's
The P2 smart pins can send up to 32 bits, with in-line loading.
You could use that, with some simple packing, to send position tags and up to 3 bytes of data over the standard UART link, in a very fast and compact 'no polling' scheme and a fast UART
[StartBit] + 8+1 +1+8+1 + 1+8 + [Stop] = 28 bits of data, for 3 bytes, 1 stop bit
[StartBit] + 8+2 +1+8+2 + 1+8+1 + [Stop] = 31 bits of data, for 3 bytes, 2 Stop bits, eg UB3 6Mbd and 8MBd settings.
Transmit window (min time before next debug tag) is >= 4.125us at 8M.N.2
A smarter terminal could collect debug messages and display those strings given the 3 byte ID P2 sends - that removes the message overhead entirely from P2 and slashes the time and size of inserted emit-debug messages.
Yeah that's a good idea too jmg. Also if this ESP32 is present for remote access/download etc it could also be employed to accumulate/ format some data over a SPI slave pin at very high speed and then pass up to a centralized debugger via a network which could offload the P2 from doing some of this. Of course that adds more complexity and SPI would need further smartpin clock control etc vs simple a serial interface, but it might then run faster and allow even more data to be passed in real time - it could be good thing for a debug COG to talk to perhaps.
Yes its a good idea. I think someone else was also packing 3 bytes + start/stop into a long, though I didn't think it would be possible with the UB3 needing 2 stop bits, so thats good
On the SPI clocking it should be possible to kick off a matching series of clock pulses using the toggle (transitions) mode
Eric,
Found a problem with v4.2.6 whereas v4.2.4 works. Update: 4.2.5 also fails.
The problem is in the _FAT32 object in the calls listentries("N") and listdirectory("A") which is called from OS226x1 line 207
repeat while(buffer := taf.listEntries("N"))
I have stripped out as much code as I easily can. There are listings for both 4.2.4 and 4.2.6 fastspin versions.
The code requires a P2Eval with a FAT32 formatted card. Download and run the program and when SD:> appears type DIR<cr>.
The faulty code displays the filenames and then blanks filenames until the sort table has been filled (I reduced this to 32). The correct code just displays the correct filenames and returns to the SD:> prompt.
This could be the offending code
PRI isDIRNotEnd() : result
result or= blockToByte(currentByte)
I note that it is always returning $FFFFFFFF (when in error) even when blockToByte(currentByte) is 0.
BTW I don't understand the or= function ???
RESULT always starts out as zero when a function is called.
result or= blockToByte(currentByte)
is the same as
result := 0 or blockToByte(currentByte)
which is the same as
result := NOT NOT blockToByte(currentByte)
Basically, it returns -1 if blockToByte returns non-zero
Thanks. I knew result is initialised as zero. It’s the true/false statement of the or= that I didn’t get although I knew that was what was happening. It’s these shortcuts is what I dislike in C (and spin).
In Spin weird shortcuts are kinda common (especially in my code...) as it actually makes the code faster and smaller in non-fastpin compilers (and of course, there's similar weird patterns where fastspin can be made to emit smaller code by transforming something like
if condition
obj_var := string("abc")
else
obj_var := @something + x
Just listend (well, still in the Q&A section) the C Live Forum and Eric brought up that he might want to rename the suite because he's bad at names.
I have some internal tools that use a "multi-" prefix (they're called MultiRASM and MultiXMM), but since they aren't public at the moment, I can give that prefix to you if you want it
In general, I personally like puns (see JET Engine and all the Ventilator-stuff.. Homespun also, heh)... Would have to think about a good one that hasn't been used yet though.
I've uploaded a new binary release (4.2.8) to the usual places. This is a bug fix release; the only new feature is an option -Werror to turn warnings into errors.
I need to wrap my head around github's CI and what the implications are, but I'll take a look at it.
It basically just runs some commands on a cloud server somewhere every time you push a commit. It doesn't really do anything else. Well, by default it sends you an email if you pushed something that fails to build/test.
@ersmith (or anyone): Is there any way, at runtime, to determine the type of a variable that is passed to a SUB or FUNCTION in FlexBASIC? Example:
FUNCTION WhatAmI(a as any) as string
if a = type_string then return "It's a string"
... (more of the same) ...
if a = type_long then return "It's a long"
END FUNCTION
Comments
Example code: Running this code produces: "warning: definition of cnt hides a member variable".
Looking at the FlexBASIC docs it appears cnt is reserved since it appears on Page 7 under "LANGUAGE SYNTAX 7 / Predefined functions and variables". But that is the only mention of "cnt" in the entire manual (except for its use as a normal variable in some of the examples).
So the question is, is cnt an orphan from days gone past, a hint of a new feature as yet unimplemented, or is it a keyword/feature/function that got missed and should be documented?
EDIT: After a bit of noodling, it appears that cnt() is an undocumented alias for the getCnt() function.
Thats what I think too.
Honestly, I rather like Cnt() over GetCnt() because the “get” sort of implies to a new coder there might be a SetCnt() lurking somewhere. But it is all good as long as it is documented.
The compiler has historically handled this juggling nicely so it was a non-issue until Eric implemented the -Wall option. Now we have much more information about potential conflicts at out disposal. (It was an eyeopener to see page after page of warnings issued by 4.2.5 compiling my libraries that had long been considered as “tested and good”).
Yes, and the warning about re-defining it is bogus (you should be able to redefine weak aliases of this sort). I'll fix that in the next release. Meanwhile, just ignore the warning.
FlexGUI is a poor IDE, no question about that. I think it would be nice if someone would take Code::Blocks or Visual Studio Code or some proper IDE like that and adapt it to use fastspin as the compiler.
For example, this is the task I use to compile+run the PC version of that game for which I have no good title yet: Notice how it just calls the "run" task on my Rakefile. This could be literally any command.
Now the C++ extension (which contains all the IDE features like definition lookup) is a bit more involved and needs a bunch of information about the compiler to perform at it's best, but as far as I could tell in a quick test, seems to do reasonably fine without any. It will just assume whatever defaults it has for things like sizeof(void*) though. If you do give it a compiler path, it will apparently somehow gather this information from it. Not sure how that exactly works, but it probably requires a gcc-like commandline interface. I assume it compiles some code and then tries to inspect the resulting binary? IDK.
The big problem here is that it will all go haywire if you use the more... distinct... fastspin-isms, like struct __using, fastspin-style unquoted inline asm, etc, because the tools it uses internally only understand GCC/clang/VisualC++ brand nonstandard syntax. One will also have to explicitly define all the builtins somewhere, oterwise it'll be very sad when you use them.
It looks useful to me...
I forgot about that, thanks.
It's just a fancy printf. For PASM it's nice, but for Spin it doesn't add very much.
What I'd really like to see is an interactive debugger.
Also, you can turn it all off and on very easily. That's maybe the best part.
A full interactive debugger would be cool too. If we do get self hosted setups one day it might even be possible to integrate directly instead of needing an external PC and we could have minimal delay and direct memory access from a debug COG. It would be nice to have something like we had with the old TurboDebugger app on a PC where the dev tool and debugger is fairly nicely integrated with full symbols/source/regs etc. Of course this is mostly pie in the sky stuff and we should also have external serial debuggers, probably as the first priority.
I've been thinking there may be useful middle ground between LEDs and printf's
The P2 smart pins can send up to 32 bits, with in-line loading.
You could use that, with some simple packing, to send position tags and up to 3 bytes of data over the standard UART link, in a very fast and compact 'no polling' scheme and a fast UART
A smarter terminal could collect debug messages and display those strings given the 3 byte ID P2 sends - that removes the message overhead entirely from P2 and slashes the time and size of inserted emit-debug messages.
On the SPI clocking it should be possible to kick off a matching series of clock pulses using the toggle (transitions) mode
Found a problem with v4.2.6 whereas v4.2.4 works. Update: 4.2.5 also fails.
The problem is in the _FAT32 object in the calls listentries("N") and listdirectory("A") which is called from OS226x1 line 207
repeat while(buffer := taf.listEntries("N"))
I have stripped out as much code as I easily can. There are listings for both 4.2.4 and 4.2.6 fastspin versions.
The code requires a P2Eval with a FAT32 formatted card. Download and run the program and when SD:> appears type DIR<cr>.
The faulty code displays the filenames and then blanks filenames until the sort table has been filled (I reduced this to 32). The correct code just displays the correct filenames and returns to the SD:> prompt.
This could be the offending code
I note that it is always returning $FFFFFFFF (when in error) even when blockToByte(currentByte) is 0.
BTW I don't understand the or= function ???
Can you explain what This is doing please
result or= blockToByte(currentByte)
I know that whenever blockToByte(currentByte) > 0 the function returns $FFFFFFFF (ie -1) and when 0 returns 0. I just don't understand why.
Basically, it returns -1 if blockToByte returns non-zero
Not as common in C/C++ anymore since the major compilers got really good at optimizing.
I'm gonna try fiddling with GitHub's CI thing to see if I can get it to build fresh fastspins for each commit. That'd solve that problem.
Doneski. PR submitted, should "just work" after merging
I have some internal tools that use a "multi-" prefix (they're called MultiRASM and MultiXMM), but since they aren't public at the moment, I can give that prefix to you if you want it
In general, I personally like puns (see JET Engine and all the Ventilator-stuff.. Homespun also, heh)... Would have to think about a good one that hasn't been used yet though.
Thanks, @Wuerfel_21 . I need to wrap my head around github's CI and what the implications are, but I'll take a look at it.
It basically just runs some commands on a cloud server somewhere every time you push a commit. It doesn't really do anything else. Well, by default it sends you an email if you pushed something that fails to build/test.