Shop OBEX P1 Docs P2 Docs Learn Events
Please add a conditional compile feature to the SPIN parser. — Parallax Forums

Please add a conditional compile feature to the SPIN parser.

epmoyerepmoyer Posts: 314
edited 2007-05-24 18:05 in Propeller 1
Parallax,

I would love to see a conditional compile feature added to the SPIN parser. I am developing music playback drivers for the HYDRA platform ( http://forums.parallax.com/showthread.php?p=650114 ) and constantly find myself wishing I could add some features that I know not everyone will use. Since Hydra developers are generally very pressed for RAM I don't want to clutter their precious code space with unused options. Support for even the most rudimentary of conditional compile syntax in the Propeller IDE would solve this problem. I'd love to be able to write something like:


CON

  SUPPORT_EEPROM_PLAYBACK = TRUE

VAR

  #IF SUPPORT_EEPROM_PLAYBACK 
  long eeprom_ptr
  #ENDIF

  #IF !SUPPORT_EEPROM_PLAYBACK 
  long ram_ptr
  #ENDIF

  long command

PUB start_player()
  
  #IF SUPPORT_EEPROM_PLAYBACK 
  eeprom.start()
  #ENDIF  

  ...





I don't care what the actual syntax ends up being, so long as blocks of code can be conditionally included and excluded based on some global flags defined at the top of the source code.

What do you think?

Post Edited (epmoyer) : 5/22/2007 10:45:46 PM GMT

Comments

  • mynet43mynet43 Posts: 644
    edited 2007-05-22 19:54
    I second that request.

    I often find myself wasting valuable storage because I want to leave in some test code or data to make it easy to debug if I change something later.

    I can skip over the code but the storage is still wasted.

    There are many other good examples for wanting this.

    It can't be that hard...
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-05-22 20:02
    I'm with you there. But Chip is likely too busy to implement such a feature in the compiler right now. What would be nice is if the IDE could be modularized to the point that the compiler be a separate entity, called from the IDE as a command-line task, and with a documented interface. Or, the IDE could provide an option to run the source through a user's own filter program before the compiler sees it. In either event, at least, someone else would have a chance to implement and interpose a preprocessor for such things as conditional compilation and macros.

    Guys?

    -Phil
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-22 22:00
    While several of us have pressed the cause and there has been much discussion on the topic, there are no plans to adding conditional compilation to the compiler in the near future.

    Something which is much more likely because it has a greater utility is a command line interface to the tool which provides no-GUI back end to the compiler. This hasn't been placed on the queue yet though we will press for it's addition in the coming weeks, if so it will likely become the 3rd item (after the revision of the Stamps and the debug terminal feature for the Propeller Tool). This means it will be sometime mid to late summer assuming no other high priority items intervene.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • epmoyerepmoyer Posts: 314
    edited 2007-05-22 22:11
    Paul,

    I am sorry to hear that sad.gif
    I'd love to have it and it seems easy.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-22 22:30
    Easy is in the eye of the beholder, it would require a fairly extensive rewrite of the compiler. Considering this would have to be done by Chip and he is presently busy designing the next Propeller, bumping the development cycle is not something we take lightly. On top of this he isn't pursuaded of it's need, and yes we have brought up all of the issues where conditional compilation would be handy if not nessesary. Another issue is his overarching desire to keep the language simple and elegant, and conditional compilation definitely complicates the code both in structure and readability.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • epmoyerepmoyer Posts: 314
    edited 2007-05-22 22:37
    Ok propeller community, we can solve this one ourselves temporarily until Parallax has more time to work on it. Let me propose the following:

    What if we decide on a conditional compile syntax of our own like the one I detailed above, and write a stand-alone parser tool that would walk through a .spin file and selectively add braces "{ ... }" around code that was conditionally compiled out, and remove them from code which was conditionally compiled in. So...

    CON
    
      SUPPORT_EEPROM_PLAYBACK = TRUE
    
    VAR
    
      '#IF SUPPORT_EEPROM_PLAYBACK 
      long eeprom_ptr
      '#ENDIF
    
      '#IF !SUPPORT_EEPROM_PLAYBACK 
      long ram_ptr
      '#ENDIF
    
      long command
    
    PUB start_player()
      
      '#IF SUPPORT_EEPROM_PLAYBACK 
      eeprom.start()
      '#ENDIF  
    
      ...
    



    Would become...


    CON
    
      SUPPORT_EEPROM_PLAYBACK = TRUE
    
    VAR
    
      '#IF SUPPORT_EEPROM_PLAYBACK 
      long eeprom_ptr
      '#ENDIF
    
      '#IF !SUPPORT_EEPROM_PLAYBACK 
      { 'Removed by preprocessor
      long ram_ptr
      }' Removed by preprocessor
      '#ENDIF
    
      long command
    
    PUB start_player()
      
      '#IF SUPPORT_EEPROM_PLAYBACK 
      eeprom.start()
      '#ENDIF  
    
      ...
    



    The syntax restrictions would be very simplistic. You can only define preprocessor directive constants as true of false, and the only valid inclusion/exclusion syntaxes would be '#IF <constant> and '#IF !<constant> (The single quote has to go in front of them so the IDE ignores them as comments).

    Using that method:
    1) The "preprocessor" is simple. I'll write us one in an hour.
    2) You only have to run the external "preprocessor" if you change your preprocessing directives, so the fact that the IDE won't do it for you is only a minor annoyance. We can still use the method to distribute code with conditional sections and users can do a one-time configuration pass with the preprocessor to build the version they need.
    3) You can still edit your code in the IDE and compile it like normal.
    4) When Parallax gets around to supporting preprocessor directives the code will be forward compatible with the new preprocessor (assuming they adopt the same syntax).

    What do you all think?

    Paul, does Parallax have a preferred syntax that they would like to used if/when preprocessor directives are natively supported?
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-22 23:17
    Sorry, we haven't had any discussions on a prefered syntax, and any determination would be subject to change if/when we started to implement it.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • epmoyerepmoyer Posts: 314
    edited 2007-05-22 23:29
    Ok, I'm not sure yet if I prefer the syntax

    CON
    
      SUPPORT_EEPROM_PLAYBACK = TRUE
    
    
    



    or

    CON
    
      '#DEFINE SUPPORT_EEPROM_PLAYBACK TRUE
    
    
    



    The second one is easier to parse, but the first one is a little easier to read because of the way the IDE colors the text. The second one can go anywhere (like in the starting comment block), whereas the first one has to go in the CON section. I'll probably go with the second for simplicity. The second also is clearly a preprocessor directive and not related to the regular spin code, whereas the first is a bit ambiguous. Hmm, now that I say that, one of the advantages of the first is that regular spin code has access to behave conditionally on the flag as well (though you could accomplish the same thing by putting #IF's around some constants if you like, and then checking those constants in your code.

    Please let me hear your opinions out there. I won't get to write the preprocessor until I finish my upcoming HDMF release, which is still a couple days away.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-05-23 02:50
    Paul Baker (Parallax) said...
    Something which is much more likely because it has a greater utility is a command line interface to the tool which provides no-GUI back end to the compiler.
    Paul, this would be great. I'm all for empowering the user with whatever program hooks you can provide. It gives the fittest preprocessors a chance to thrive, and the users an opportunity to demonstrate by example what we really want. Now, if you can include these hooks in the IDE, so we don't have to do a "DOS two-step" just to make it work, that would be even better!

    -Phil
  • potatoheadpotatohead Posts: 10,255
    edited 2007-05-23 05:08
    I think any syntax used at this point, should be transparent to the IDE. That way, the pre-processor directives will be ignored in future versions of the Parallax tool, and the pre-processor to be created now would eventually just be able to convert code written for it to whatever syntax does evolve in the future from Parallax.
  • Tom WalkerTom Walker Posts: 509
    edited 2007-05-23 12:55
    epmoyer,
    It seems to me that your point 2), above, would have to be predicated on the fact that one is editing the post-processed code to begin with. Or am I mis-interpreting what you are saying?

    I like the idea, though...

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Truly Understand the Fundamentals and the Path will be so much easier...
  • epmoyerepmoyer Posts: 314
    edited 2007-05-23 15:07
    The Pre/Post nomenclature is not quite appropriate to what I am proposing.

    A standard "PREprocessor" runs when you hit "compile", turns your source (A) into an intermediate file which you generally don't ever see (B), and that file gets compiled. You always edit the source (A) and file B is a transient entity which disappears after the compile.

    What I am proposing is perhaps more aptly named a "Configuration Management" utility. It will take source (A) and non-destructively add and remove block comments (braces) to generate a new version of the source (A) that gets saved on top of the old one (and yes, it will save a copy as .bak or something just to be safe).

    Now, if you want to use this proposed Spin Configuration Managment (SCuM!) utility on your code you have to...
    1) Modify your '#DEFINE statements
    2) Close the source in the SPIN IDE
    3) Run SCuM on the file (will support drag and drop to make that as quick and painless as possible)
    4) Open the source in the SPIN IDE
    5) Compile

    So there are 4 steps (2-5 above) in place of what ideally would be one step (hit compile), but it seems like a livable interim solution to me.

    Because SCuM never destroys, deletes, or modifies any of the original source code (it only adds and removes comment braces) you can turn the #DEFINE flags on and off as many times as you like, run SCuM as many times as needed, and you always edit the same source file.
  • Mark SwannMark Swann Posts: 124
    edited 2007-05-23 15:32
    Paul Baker (Parallax) said...
    Easy is in the eye of the beholder, it would require a fairly extensive rewrite of the compiler. Considering this would have to be done by Chip and he is presently busy designing the next Propeller, bumping the development cycle is not something we take lightly. On top of this he isn't pursuaded of it's need, and yes we have brought up all of the issues where conditional compilation would be handy if not nessesary. Another issue is his overarching desire to keep the language simple and elegant, and conditional compilation definitely complicates the code both in structure and readability.

    The compiler should need little modification. Simply pass the source through a pre-processor before handing it to the compiler. That is how C and C++ compilers have been doing since, well ..., since Kernighan and Richie. That is why they are called "pre-processor directives".
  • epmoyerepmoyer Posts: 314
    edited 2007-05-23 15:52
    Lucidman,

    Well, if I play devil's advocate for a moment I can see Paul's point. If you are Parallax and you are dedicated to making an integrated environment that is clear and easy to use for your customers then adding pre-processor directives ends up causing you to create a long list of action items to support, like:

    1) Preprocessor syntax checking
    2) Reporting preprocessor errors back to the IDE
    3) Handling nested preprocessor directives
    4) Coloring preprocessor blocks appropriately in the IDE (w/ nesting?)

    I do think you could could keep it pretty simple for a first pass, but you would have to document it, and integrate it into the current build schedule, and test it, and support it. Then since you're running a business you have to look at it along with everything else on your plate and say "does this (yes, possibly cool and useful) feature drive my business forward more than the other features / tasks on my plate?".

    For us the job is much easier. We want it, we throw it together, we use it with caution and poke at it until we're confident it works well, and we have nobody to answer to if we screw up. Unfortunately the best we can do is an external utility. Now if only the IDE were open source....
  • AribaAriba Posts: 2,682
    edited 2007-05-23 17:51
    Hello epmoyer

    How about this syntax:
    CON
    
      SUPPORT_EEPROM_PLAYBACK = TRUE     '#DEFINE 
    
    or
    
    '#DEFINE   SUPPORT_EEPROM_PLAYBACK = TRUE
    
    


    both version should be allowed. That is easy to parse (only check if a line contains '#DEFINE) and the user can choose if spin knows the constant too, or not.

    Andy
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-23 17:57
    Thanks Eric, you understand the situation quite well. Some of our resources are more precious than others, and two of our most precious resources are Chip's time (he wrote the compiler) and Jeff's time (he wrote the IDE). Chip is busy designing the next Propeller, since this will hopefully become the life-blood of the company at some point in the future, something really serious has to come up in order for him to put aside it's development. And Jeff is the head programmer, he is responsible for pretty much all engineering issues with the Stamps (product maintaince, IDE and firmware) and the Propeller Tool. He has been busy the last month+ dealing with issues on the Stamp series. Since this is the current life-blood of the company, there is nothing which is a higher priority.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-23 18:11
    Phil, no guarentees about the hooks bit, I don't know if you remember but both you and I were lobbying for it when I was still a customer and we were in the beta forum. The command line is alot more justifiable because of all the possible uses of it, the hooks are harder to place in the queue because it is a very specific item and it goes against the goal of simplicity.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • BaggersBaggers Posts: 3,019
    edited 2007-05-23 19:56
    I too would like conditional compiling, but i'd much prefer the gui, as like Paul says, it opens MUCH more options.
    That way, we could add our own batch programs that pre-modify the '#IFs into a temp file then compiles that.
    like in ManicMiner I have two keyboard objects in, but depending on a CON value depends which one is used, I have three configs and i just uncomment which config I want.

    'uncomment the '{ block which suites your system.
    { Hydra Defines
    _CLKMODE = xtal1 + pll8x
    _XINFREQ = 10_000_000 + 0000

    USE_SDCARD_INSTEAD_OF_HIEEPROM = 0 ' 0 for level files taken from HIEEPROM or 1 for level files taken from SD Card root
    USE_SOUND_BITS_FOR_STEREO = 1 ' usually 3 for Proto/Demo boards and 1 for Hydra ... 1 for mono and 3 for stereo
    USE_SOUND_PINS = 7 ' usually 10 for Proto/Demo boards and 7 for Hydra
    USE_HYDRA_KEYBAORD = 1 ' usually 0 for Proto/Demo boards ( key.start(26,27) ) and 1 for Hydra ( keyhydra.start(3) )
    USE_TV_ON_PIN_24 = 1 ' usually 0 for Proto/Demo boards ( JBSpecGfx.Start(12) ) and 1 for Hydra ( JBSpecGfx.Start(24) )
    '}
    { Proto/Demoboard Defines - No SD card installed
    _CLKMODE = xtal1 + pll16x
    _XINFREQ = 5_000_000 + 0000

    USE_SDCARD_INSTEAD_OF_HIEEPROM = 0 ' 0 for level files taken from HIEEPROM or 1 for level files taken from SD Card root
    USE_SOUND_BITS_FOR_STEREO = 3 ' usually 3 for Proto/Demo boards and 1 for Hydra ... 1 for mono and 3 for stereo
    USE_SOUND_PINS = 10 ' usually 10 for Proto/Demo boards and 7 for Hydra
    USE_HYDRA_KEYBAORD = 0 ' usually 0 for Proto/Demo boards ( key.start(26,27) ) and 1 for Hydra ( keyhydra.start(3) )
    USE_TV_ON_PIN_24 = 0 ' usually 0 for Proto/Demo boards ( JBSpecGfx.Start(12) ) and 1 for Hydra ( JBSpecGfx.Start(24) )
    '}
    '{ Proto/Demoboard Defines - SD card installed on pin 0-3
    _CLKMODE = xtal1 + pll16x
    _XINFREQ = 5_000_000 + 0000

    USE_SDCARD_INSTEAD_OF_HIEEPROM = 1 ' 0 for level files taken from HIEEPROM or 1 for level files taken from SD Card root
    USE_SOUND_BITS_FOR_STEREO = 3 ' usually 3 for Proto/Demo boards and 1 for Hydra ... 1 for mono and 3 for stereo
    USE_SOUND_PINS = 10 ' usually 10 for Proto/Demo boards and 7 for Hydra
    USE_HYDRA_KEYBAORD = 0 ' usually 0 for Proto/Demo boards ( key.start(26,27) ) and 1 for Hydra ( keyhydra.start(3) )
    USE_TV_ON_PIN_24 = 0 ' usually 0 for Proto/Demo boards ( JBSpecGfx.Start(12) ) and 1 for Hydra ( JBSpecGfx.Start(24) )
    '}


    So although conditional would be nice I think CommandLine is the best way to go [noparse]:)[/noparse] but then Parallax don't just come up with great hardware without having good ideas too :P

    My 2p's worth.

    Baggers
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-23 20:10
    Ive thought about this some and my personal favorite (so dont think this is an official Parallax opinion) is using a current IDE compatible format, like:
    CON
       DEBUG = true
     
     
    {DEBUG
     
       'some code related to debug
     
    }
     
    {!DEBUG
     
       'some code to execute when not debugging
     
    }
     
    

    This method leaves open the option of doing this type of code

    if DEBUG
       print.str(@debug_str)
    else
       print.str(@alt_str)
    

    Which is currently what I do when I need versions, but the above {CONSTANT method enables the use of conditional compilation in non-code sections such as VAR, CON, DAT·and especially useful in OBJ (I like to write code which supports multiple types of displays). If you wanted to get uber fancy you could search the code for "if CONSTANT" and·"if !CONSTANT"·code sections and do dead code optimization be removing always false code.·

    And if I had my druthers the configuration management utility would leave a false condtional exactly how it is and in a true conditional would simply turn the {CONSTANT into 'CONSTANT and remove the trailing }, this way it still stays readable and IDE compatible. It would basically do an automatic uncomment of the appropriate sections like shown by Baggers.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 5/23/2007 8:19:46 PM GMT
  • epmoyerepmoyer Posts: 314
    edited 2007-05-23 22:45
    Paul,

    If we do it that way I don't see how the preprocessor can tell where a block of preprocessor switched code ends if it is currently "active" (i.e. has no braces around it). If I write:

      'DEBUG
      a := b
      c := d
      e := f
    



    ..then there is no way to tell that I meant for the first two lines to be part of the conditional block and the last line not to be. I suppose you could indent, but that means you have extraneous indents (as seen by the IDE/compiler) and I'm not sure that the compiler does the right thing (probably does) and that the IDE coloring/indent highlighting does the right thing (probably doesn't; too lazy to go try[noparse]:)[/noparse]. Writing this:

      '#IF DEBUG
      a := b
      c := d
      '#ENDIF
      e:=f
    



    would be unambiguous both in it's included form and in its excluded form:

      '#IF DEBUG
      { 'Removed by preprocessor
      a := b
      c := d
      } 'Removed by preprocessor
      '#ENDIF
      e:=f
    



    Andy,

    Your suggested syntax would be a bit harder to parse, and I think is a bit harder for people to read. I'd rather keep it simple. The syntax above always allows you to achieve the same end by putting a standard define inside your conditional preprocessor statements like:

    CON
      '#IF DEBUG
      DEBUGGING_ON = TRUE
      '#ELSE
      DEBUGGING_ON = FALSE
      '#ENDIF
    
    



    Keeping it simple both keeps users from making mistakes but also keeps me from making mistakes in implementing the parser.
  • Tom BamptonTom Bampton Posts: 29
    edited 2007-05-24 05:58
    You can just use the C pre-processor if you have a C compiler installed. If not, there are plenty of free options.

    If you have Visual C++ 2005 (of which there is a free version) installed, then you can use the following in a command prompt to pre-process the file:

    cl /EP InputFilename.spin >OutputFilename.spin
    
    



    Then you can use all the C pre-processor facilities; including include files, conditionals, macros, etc. You can also use C style comments, since the pre-processor will strip those out for you.

    If you have gcc installed, the pre-processor command is cpp. You'll have to check the docs for the arguments, I don't remember them off hand.

    T.
  • epmoyerepmoyer Posts: 314
    edited 2007-05-24 07:05
    The problem with using a standard pre-processor is that you have to maintain 2 versions of your file; 1 which contains pre-processor directive (but which will not compile in the propeller IDE because of those directives), and a processed one. The problem is, if you're going to work on the code you're going to have to work with the second (processed) one, and any changes you make in the edit/compile/test cycle in the IDE will have to get manually fed back into the original file. OR, you have to live with a close#2>Open#1>Edit#1>Close#1>Run Preprocessor on #1>Open #2>Compile #2>Test#2>Repeat cycle which sounds very painful to me.

    The advantage of the syntax and parser proposed above is that you have 1 file to work with, and that file is always editable/compilable in the IDE. You only need to exit and run the preprocessor when/if you modify the preprocessor directives.
  • Tom BamptonTom Bampton Posts: 29
    edited 2007-05-24 11:30
    Yeh, it's not without it's annoyances. But the main advantage is that it is a solution that works now, which is all that really matters if you are doing things that need a pre-processor.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2007-05-24 16:42
    Paul,

    The "hooks" could be quite simple. I have an editor (UltraEdit) that uses F9 as "run" button, which will execute any command line I specify when I press it. The Propeller IDE could easily be set up this way, with the following as a default command line:

    spin.exe %f
    
    
    


    where %f specifies the file name of the Spin program. But, given the facility to change the default command line, I might prefer something like this:

    mypreprocessor.exe %f
    
    
    


    In this example, mypreprocessor.exe would read %f and its subobject files, massage them, then output them to temporary files. Next it would invoke spin.exe, giving it the name of the top-level temporary file it created. Assuming spin.exe reports errors/success in some documented format, mypreprocessor.exe would retrieve this info and reformat it so errors would show up in the correct locations in the IDE. The compiler itself would not have to be touched.

    -Phil
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-05-24 18:05
    Hi guys,

    We recognize the need for pre-processing capabilities, however to arrive at the best solution we will need to spend some time deliberating on it.

    With feature requests in general from now on I will be recording them into a wish list and only make a brief acknowlegement of the request rather than going into an in-depth discussion. This doesn't mean we won't take the requests seriously, it just means we will deliberate and prioritize them internally.

    Thanks,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
Sign In or Register to comment.