Shop Learn P1 Docs P2 Docs
PNut/Spin2 Latest Version (v37 - OBJ parameterization, field pointers, locals cleared, plus more) - Page 56 — Parallax Forums

PNut/Spin2 Latest Version (v37 - OBJ parameterization, field pointers, locals cleared, plus more)

15253545658

Comments

  • @cgracey said:
    What would you all think about Spin2 starting to clear local variables upon method entry?

    I've always appreciated this behavior in other languages. Simple and predictable.

    Like others, I too look forward to the Spin2 specification being stamped with a label such as "official Spin v2.0" that sort of grounds all the available tools in a common language specification. Of course, I also wish to see the release of v2.1, v2.2, v3.0, etc. Parallax Inc. should be the canonical source for defining the contents of these version labels. Having the Spin interpreter be a sustainable open source project under Parallax's governance is a very helpful step toward this, IMHO.

  • cgraceycgracey Posts: 13,873
    edited 2022-09-25 23:32

    I've been thinking about the ripple effects of changes that I will be making.

    Adding a file system is going to shift things from being an embedded system to an interactive system. Disparate Spin2 programs will be able to run simultaneously. This will entail lots of tweaks to everything, and maybe even introduce some memory management.

    I want to keep doing my work just like you guys want to keep doing your work.

  • ersmithersmith Posts: 5,514

    @cgracey said:
    What would you all think about Spin2 starting to clear local variables upon method entry? It would only take a few extra clocks, but would save frequent code within methods that's needed to clear local variables before use. All local variables (except parameters) would start out at zero. Currently, return values start out at zero, but local variables start out undefined. I know this would simplify a lot of my own Spin2 code. I wish I had implemented this clearing in the first place.

    I think that's a bad idea:

    (1) It slows the program down in the not uncommon case where some of the locals need to be initialized to non-zero values (or get initialized in loops);
    (2) No other languages (including Spin1) do this, so it's going to encourage bad programming practices in learners and they'll be quite surprised when they try to move on to any other programming apart from Spin2.

  • whickerwhicker Posts: 740
    edited 2022-09-26 00:37

    When are the preprocessor commands #ifdef, #ifndef, and #end going to be added?

    ```
    #ifdef FLEXSPIN
    DEBUG("hello from flexspin", 13, 10)
    #else
    DEBUG("hello from PNut", 13, 10)
    #endif

  • cgraceycgracey Posts: 13,873

    @whicker said:
    When are the preprocessor commands #ifdef, #ifndef, and #end going to be added?

    ```
    #ifdef FLEXSPIN
    DEBUG("hello from flexspin", 13, 10)
    #else
    DEBUG("hello from PNut", 13, 10)
    #endif

    I will think about this.

  • JonnyMacJonnyMac Posts: 8,311

    We have conditional compilation in the BASIC Stamp editor, it would be nice to have it with the Propeller (P1 & P2). For me it would make the "removal" of objects easier with a switch constant. It would be nice not to have some code compiled into the program image when not needed.

  • cgraceycgracey Posts: 13,873
    edited 2022-09-26 04:41

    Is this the complete set?

    #ifdef <or> #ifndef
    #else
    #end
    

    And should they be nestable?

  • cgraceycgracey Posts: 13,873
    edited 2022-09-26 05:22

    @ersmith said:

    @cgracey said:
    What would you all think about Spin2 starting to clear local variables upon method entry? It would only take a few extra clocks, but would save frequent code within methods that's needed to clear local variables before use. All local variables (except parameters) would start out at zero. Currently, return values start out at zero, but local variables start out undefined. I know this would simplify a lot of my own Spin2 code. I wish I had implemented this clearing in the first place.

    I think that's a bad idea:

    (1) It slows the program down in the not uncommon case where some of the locals need to be initialized to non-zero values (or get initialized in loops);
    (2) No other languages (including Spin1) do this, so it's going to encourage bad programming practices in learners and they'll be quite surprised when they try to move on to any other programming apart from Spin2.

    When my friend Tom Mornini was here a few weeks ago, we started writing a model of the SPI flash file system in Google's GO language. GO initializes all variables to zero. One thing that does is prevent intermittent bugs stemming from random-state uninitialized variables. So, it has utility. In the Spin2 interpreter, the time taken to perform the local-variable clearing is 2..9 clocks plus 1 clock per local long variable. In the case where there are a few local variables, it adds about 3% to the time it takes to perform a function call.

    One other thing GO does that is really cool is that if you assign a variable using ":=", it recognizes that as a variable declaration, as well. Subsequent assignments can use just "=". That is a feature that keeps the method declaration much cleaner. I love ideas like these.

  • evanhevanh Posts: 13,849
    edited 2022-09-26 05:35

    @cgracey said:
    Is this the complete set?

    #ifdef <or> #ifndef
    #else
    #end
    

    And should they be nestable?

    C has #if as well as #ifdef, although FlexC doesn't. #if provides numerical compare of numerical strings. It can do simple maths similar to Spin's CON section.

    Nestable, yes.

  • Wuerfel_21Wuerfel_21 Posts: 3,310
    edited 2022-09-26 07:17

    @cgracey said:
    Is this the complete set?

    #ifdef <or> #ifndef
    #else
    #end
    

    No, it's #endif, not #end. Also, there's #elseifdef and #elseifndef. Of course, you also need #define and the all-important #include. Maybe #undef, too, but I never use that one. Perhaps also recognize/ignore #pragma.

  • @ersmith said:

    @cgracey said:
    What would you all think about Spin2 starting to clear local variables upon method entry?

    I think that's a bad idea:
    (1) It slows the program down in the not uncommon case where some of the locals need to be initialized to non-zero values (or get initialized in loops);
    (2) No other languages (including Spin1) do this, so it's going to encourage bad programming practices in learners and they'll be quite surprised when they try to move on to any other programming apart from Spin2.

    I disagree. Making something more robust and less error-prone does NOT break any existing code. It's always a good idea to avoid any "undefined" cases whenever possible. The performance penalties are much less severe compared to the time we all spend on debugging.

    Clearing all variables to zero may tempt programmers to use "bad programming practices" but it turns most heisen-bugs into bohr-bugs that are MUCH easier to find. I still remember the times when I programmed in Oberon on my Amiga. The compiler had a garbage collector and by default cleared all memory allocated from the heap before use. That avoided almost any dangling pointer or undefined value problems and saved me a real lot of time. Oberon programs just never crash. The sensless "optimisations" of C is the most important reason for my strong antipathy for that language although I have to use it, these days.

    Spend the time saved by avoided bugs on optimizing your algorithms and you won't have performance problems. If the high-level language is too slow you have to code in assembler anyway.

  • maccamacca Posts: 507

    @cgracey said:
    What would you all think about Spin2 starting to clear local variables upon method entry? It would only take a few extra clocks, but would save frequent code within methods that's needed to clear local variables before use. All local variables (except parameters) would start out at zero. Currently, return values start out at zero, but local variables start out undefined. I know this would simplify a lot of my own Spin2 code. I wish I had implemented this clearing in the first place.

    Are there cases where local variables are not initialized and used "as is" ?
    I mean, by definition, a local variable will be always initialized somewhere into the method, like assigned from a function call or initialized with a loop count, or something.
    Having global and return variables initialized is good, but local variables haven't much sense to me, even if the performance impact is negligible.
    Using an uninitialized local variable is a programming error, always.

  • DiverBobDiverBob Posts: 1,009

    How about having the option for the programmer to declare an initial value to a global variable when the variable is declared? Then the variable can be set to 0 or any other initial run time value? Not necessarily a good idea but thought I’d throw that one into the ring!

    I like the idea of being able to use something like #ifdef to remove debugging statements from being compiled without having to actually removing/commenting out the DEBUG entries.

  • whickerwhicker Posts: 740
    edited 2022-09-26 15:19

    @Wuerfel_21 said:

    @cgracey said:
    Is this the complete set?

    #ifdef <or> #ifndef
    #else
    #end
    

    No, it's #endif, not #end. Also, there's #elseifdef and #elseifndef. Of course, you also need #define and the all-important #include. Maybe #undef, too, but I never use that one. Perhaps also recognize/ignore #pragma.

    Please calm down. Take a breath.

    If just these below were added, does this get us to solving 99% of the use cases?

    #define symbol optional_value
    #undef symbol

    #ifdef symbol ' shorthand for #if defined( )
    #ifndef symbol ' shorthand for #if !defined( )

    #else

    #endif

  • @whicker said:

    @Wuerfel_21 said:

    @cgracey said:
    Is this the complete set?

    #ifdef <or> #ifndef
    #else
    #end
    

    No, it's #endif, not #end. Also, there's #elseifdef and #elseifndef. Of course, you also need #define and the all-important #include. Maybe #undef, too, but I never use that one. Perhaps also recognize/ignore #pragma.

    Please calm down. Take a breath.

    If just these below were added, does this get us to solving 99% of the use cases?

    #define symbol optional_value
    #undef symbol

    #ifdef symbol ' shorthand for #if defined( )
    #ifndef symbol ' shorthand for #if !defined( )

    #else

    #endif

    Nah, need #elseifdef to not be a total mess. And #include is kinda important as well. What's not really needed is actual text substitution (i.e. #define as flags only, no values). I think a lot of the Spin1 compilers don't implement it.

  • So can we agree that the purpose is to blank out some source code lines before they get to the compiler?

    Wouldn't it be best if the line numbers before and after these preprocessor commands still were the same?

    1. Executed # commands get converted to comments, with the normal carriage return. This is for ease of reference.
    2. For the path taken, emit the code as is, until a # terminator is found (#else, #endif, etc.)
    3. For the path not taken, emit each source code line as a blank line. Any nested # commands that aren't actually executed, just emit them as blank lines too.

    Agree that substituting text (macro stuff) is not the purpose. But #include is basically a form of immediate text substitution.

    Anything after #include, and the source code line numbers won't align anymore. It is a discontinuity between what the programmer sees in the editor, and what the compiler sees.

  • @whicker said:
    Anything after #include, and the source code line numbers won't align anymore. It is a discontinuity between what the programmer sees in the editor, and what the compiler sees.

    This is a long-solved problem. You just keep track of which lines came from the include file.

  • ersmithersmith Posts: 5,514

    @whicker said:
    When are the preprocessor commands #ifdef, #ifndef, and #end going to be added?

    ```
    #ifdef FLEXSPIN
    DEBUG("hello from flexspin", 13, 10)
    #else
    DEBUG("hello from PNut", 13, 10)
    #endif

    Preprocessor commands would certainly be useful, as evidenced by all the other Spin compilers that implement them (bstc, flexspin, openspin). But there is a way to do what you want already, namely:

    {$flexspin #ifdef __FLEXSPIN__
       DEBUG("hello from flexspin", 13, 10)
    #else}
       DEBUG("hello from PNut", 13, 10)
    {$flexspin #endif}
    

    Flexspin understands that everything inside a {$flexspin ...} comment is meant to be compiled by it, whereas other compilers will ignore the comment.

  • ersmithersmith Posts: 5,514

    @evanh said:

    @cgracey said:
    Is this the complete set?

    #ifdef <or> #ifndef
    #else
    #end
    

    And should they be nestable?

    C has #if as well as #ifdef, although FlexC doesn't. #if provides numerical compare of numerical strings. It can do simple maths similar to Spin's CON section.

    Nestable, yes.

    FlexC has a standard C preprocessor and supports all of the directives (including #if). FlexSpin and FlexBASIC use a simpler preprocessor that only understands #ifdef, #ifndef, #else, #endif, #include, #error, #warning, #line, and #define (and only simple substitution, no arguments for #define macros). They are nestable. Oh, there are #elseifdef and #elseifndef directives too, but since directives are nestable those aren't strictly necessary. #line is used to specify the file name and line number for error messages; #include inserts appropriate #line directives to make sure error messages come from the correct places.

  • cgraceycgracey Posts: 13,873

    What preprocessing commands should reasonably be implemented? I don't want to spend too much time on this, but what could be done that would solve most of the problem?

  • jmgjmg Posts: 14,979

    @cgracey said:
    What preprocessing commands should reasonably be implemented? I don't want to spend too much time on this, but what could be done that would solve most of the problem?

    See #1661
    You just need the variants of ELSE and ELSIF and the ability to DEFINE and UNDEF for symmetry, and INCLUDE.

    The better editors track the defines where they can, and show the actually active code.

    As hinted above, those skipped lines can give source:compiled line count skews, which makes source level debug harder.
    Often compilers/linkers generate a debug reference file that relates full source file paths and actual source line numbers, with code generated.

  • cgraceycgracey Posts: 13,873
    edited 2022-09-26 20:46

    @jmg said:

    @cgracey said:
    What preprocessing commands should reasonably be implemented? I don't want to spend too much time on this, but what could be done that would solve most of the problem?

    See #1661
    You just need the variants of ELSE and ELSIF and the ability to DEFINE and UNDEF for symmetry, and INCLUDE.

    The better editors track the defines where they can, and show the actually active code.

    As hinted above, those skipped lines can give source:compiled line count skews, which makes source level debug harder.
    Often compilers/linkers generate a debug reference file that relates full source file paths and actual source line numbers, with code generated.

    I think INCLUDE is the hardest to implement.

  • evanhevanh Posts: 13,849

    @ersmith said:
    FlexC has a standard C preprocessor and supports all of the directives (including #if). FlexSpin and FlexBASIC use a simpler preprocessor that only understands #ifdef, #ifndef, #else, #endif, ...

    Got it. Thanks.

  • TonyB_TonyB_ Posts: 2,002
    edited 2022-09-26 23:55

    @cgracey said:

    @jmg said:

    @cgracey said:
    What preprocessing commands should reasonably be implemented? I don't want to spend too much time on this, but what could be done that would solve most of the problem?

    See #1661
    You just need the variants of ELSE and ELSIF and the ability to DEFINE and UNDEF for symmetry, and INCLUDE.

    The better editors track the defines where they can, and show the actually active code.

    As hinted above, those skipped lines can give source:compiled line count skews, which makes source level debug harder.
    Often compilers/linkers generate a debug reference file that relates full source file paths and actual source line numbers, with code generated.

    I think INCLUDE is the hardest to implement.

    I use #INCLUDE all the time with FlexSpin to handle auto-generated skip patterns. I've written a program that scans the source file for skip patterns and outputs SKIPF and EXECF bit string constants to file xxxx.SKP, with a #INCLUDE "xxxx.SKP" line immediately after CON in source file.

  • maccamacca Posts: 507
    edited 2022-09-27 05:28

    @cgracey said:
    What preprocessing commands should reasonably be implemented? I don't want to spend too much time on this, but what could be done that would solve most of the problem?

    For me, the most useful commands are #if , #elseif , #else, #endif. I believe this should solve most of the problems.
    These can be evaluated like the language statements with constant expressions, I think you can reuse the CON section expression evaluator.

    The #ifdef variant can be implemented with a defined(symbol) operator: #if defined(symbol), #if !defined(symbol).

    Symbols should include CON symbols definition, #define may be useful to define symbols without assigning a value to them.

    To be extremely useful, the compiler should allow to define symbols on the command line.

    '#include' may be useful to include common definitions, but I think it would be better implemented as an object that don't require a spin method (is that already allowed ?).

    That, of course, IMHO.

  • maccamacca Posts: 507

    @DiverBob said:
    How about having the option for the programmer to declare an initial value to a global variable when the variable is declared? Then the variable can be set to 0 or any other initial run time value? Not necessarily a good idea but thought I’d throw that one into the ring!

    That's a good suggestion, I forgot that global variables can't be assigned an initial value. I think this is much more useful to save setup statements than the local variable initialization.

  • ElectrodudeElectrodude Posts: 1,540
    edited 2022-09-27 13:24

    @macca said:

    @DiverBob said:
    How about having the option for the programmer to declare an initial value to a global variable when the variable is declared? Then the variable can be set to 0 or any other initial run time value? Not necessarily a good idea but thought I’d throw that one into the ring!

    That's a good suggestion, I forgot that global variables can't be assigned an initial value. I think this is much more useful to save setup statements than the local variable initialization.

    I second this. Remove local initialization and make it possible to initialize globals to particular values at compile time.

    I rescind my seconding of this. It brings us further from being able to instantiate dynamically allocated objects at runtime. But at any rate, please remove local initialization.

  • JonnyMacJonnyMac Posts: 8,311
    edited 2022-09-27 13:57

    How about having the option for the programmer to declare an initial value to a global variable when the variable is declared?

    I move those variables to a DAT section. They get initialized and no additional RAM is required to do it.

  • [I know this is the PNut thread, but seems a good place to post this]

    Hi P2 Team!

    I have a "Beta" release of Propeller Tool to share with you that includes the low-level debugger. It matches the debugger features included in PNut v36.

    I'm release it as an early beta so you can try it out. So far, it works great for me on my host machine, but fails to maintain P2 communication on my development VM (in much the same way the PNut does). Please report here if you notice it doesn't work on your machine (and compare it to PNut v36, please) and let me know of any issues you see.

    I'm attempting to resolve those final communication issues soon.

    You can download the archive here: https://github.com/parallaxinc/Propeller-Tool/releases/tag/v2.8.0_beta

    NOTE: This release does not include the installer or most resource files. It will run by itself, but for the best experience, place it into your current Propeller Tool installation folder for the time being. Thanks!

  • JonnyMacJonnyMac Posts: 8,311
    edited 2022-10-01 19:56

    Am I missing something, Jeff? I downloaded the ZIP from the link in your post.

    I did in fact extract to a folder -- there are only those two files in it. Same with the tar.gz archive.

Sign In or Register to comment.