Mixing PNut and flexspin specific code
flexspin and "standard" Spin2 are mostly compatible, but there are a few things (like how to do COG resident functions) that are different between them, mainly because of assumptions about the memory layout of the interpreter.
It'd be really nice if Spin2 had some basic preprocessor commands as standard (like #define and #ifdef). But until it does, there is a work-around in flexspin. You can include flexspin specific code in a comment that has a very specific form, namely a line starting with:
{$flexspin
If flexspin sees such a comment it ignores the first $flexspin in the comment and then re-processes the rest of the comment as if it were ordinary input. This can include preprocessor commands like #ifdef, so you can keep PNut specific code from being compiled in flexspin. For example:
CON _clkfreq = 160_000_000 PUB main() {$flexspin #ifdef __FLEXSPIN__ ' this code is for flexspin only DEBUG("hello from flexspin", 13, 10) #else ' code after this is for PNut/PropTool only } DEBUG("hello from PNut", 13, 10) ' end the PNut only section {$flexspin #endif} DEBUG("hello from both", 13, 10)
Will output:
Cog0 hello from flexspin Cog 0 hello from both
when compiled with flexspin, but
Cog0 hello from PNut Cog 0 hello from both
when compiled with PNut or PropTool.
Comments
Cool! Making that compatible with Pnut is the real trick.
Same again but formatting variation:
@ersmith , adding Pascal-style
{$...}
versions of all the C-style preprocessor directives might be a good way to do what @evanh is suggesting.Do you mean like this?
Problem is that won't compile in Pnut. As Eric stated, ideally Pnut/PropTool gets a preprocessor instead.
Thank you, that looks much cleaner!
Unless PNut is changed to understand those it wouldn't help us to mix PNut and flexspin only code.
I also should point out that this isn't a proposal, it's a feature that's already in flexspin (and has been for a little while). I can't control what PNut sees, except that I know that PNut ignores comments. So I added the
$flexspin
comment to provide a way to include flexspin only code that PNut will ignore. The neat part is that you can use the flexspin preprocessor inside those comments to make it possible to have PNut only code that flexspin will ignore.I'm saying that you could more cleanly combine the existing
{$flexspin
directives with my proposed{$...}
directives than you could with C-style directives, since Pascal-style ones are supposed to work anywhere in a line, while C ones are really only supposed to occur at the beginning of lines.Also, I imagine Chip would be less unwilling to implement a Pascal-style preprocessor than a C-style one.
Might want to give an example.
The same as your first example, but with
{$...}
instead of#...\n
. It seems cleaner this way because then you don't have C-style preprocessor directives embedded in the middle of the line, with other stuff before or after which the parser has to somehow understand isn't part of the directive even though the newline that normally delimits C-style preprocessor directives isn't there.This way, it's obvious where the directives start and end because these ones don't care about newlines.
Comments inside comments aren't doing it for me. Eric's look is cleaner at the moment.
Looking up FreePascal reference I get:
{comment}
for comments ... and{$DEFINE name comment}
and{$IFDEF name comment}
and{$IF expr comment}
and{$ELSE comment}
and{$ENDIF comment}
for preprocessor macros with optional comments.So Chip would likely implement this:
I think I can do that. I am finishing the debugger right now.
Cool.
@cgracey, @evanh : OpenSpin and FlexSpin already implement the #define / #ifdef / #endif preprocessor. Is it really necessary to introduce a different syntax (namely ($define} and such)? If PNut could understand the #define form that would do everything we want.
I'm easy. So, Chip, that'd be:
And commenting stays within curly braces.
But the Pascal syntax looks better because Spin uses curly braces for comments, like Pascal. It should be trivial to make Flexspin and OpenSpin (and PNut, for that matter, once it understands either) understand both syntaxes - the stuff inside the
{$...}
works exactly the same as what goes inside C-style#...\n
.But, these aren't actually comments, nor are they directives that may be ignored. They matter!
Embedding semantically important information (like #ifdef) inside comments is dangerous. Older versions of the compiler will just ignore the directives, which means that the code will not compile correctly and worse will not produce any errors or warnings. At least with a new syntax like
#ifdef
the older compiler will reject the code completely instead of silently mis-compiling it.Moreover, as I pointed out, several existing compilers already support the #ifdef syntax. Rather than changing all of those, it seems more parsimonious to use that syntax when adding the feature to PNut.
I only added the
{$flexspin
directive because it was the only way to add conditional code that was compatible with PNut. If Chip can add #ifdef then the{$flexspin
won't be necessary any more.Good point. We should make sure @cgracey is aware of this argument.
#ifdef is easiest to implement.
Do it! You'll get a JPEG of a cookie! (need to open a pack for Rayman soon, anyways)
Yes please! We really will need something like this if we want drivers to be compatible with both sets of environments. Ideally nesting is supported too because it will support more complex logic and multiple feature sets.
Even though I only tend to use Propeller Tool, I want this so that I can selectively include or exclude objects and code.
Yes it will help reduce the bloat. I've wanted to write libraries of graphics functions etc with lots of useful features for some time and only enable the required portions of it so it won't bloat, but without dead code elimination in PropTool it's not realistic so I didn't proceed. This is next best thing for realizing that.
I would love to have that, too. I have a P1 project in which I'm forced to use BST so that I can get the code to fit by eliminating unused functions.
Ada has added P1 bytecode support to flexspin, so you could use that now instead of BST.
Thanks, Eric, I will give it a try.