Shop OBEX P1 Docs P2 Docs Learn Events
Is there a spin version of #include? — Parallax Forums

Is there a spin version of #include?

I'm writing what is starting to be a fairly sizable code and I've broken it up into individual objects. So now I have individual objects for things like my LCD, real time clock, SDcard etc. Several of the files call functions that are located inside other objects, such as the SDcard accessing the real time clock functions. Having multiple instances of the same objects is starting to reduce a significant amount of space I have available for my main code and I'm wondering if spin has some form of #include like C does. I've looked through other threads and wasn't able to find what I was looking for (or I didn't realize what I was looking at ) however I did fint the PreSpin file which is supposed to have the #include function. Unfortunatley my antivirus seems to be stopping that from opening and I can't disable the antivirus at the moment. Thanks in advance

Comments

  • I don't want to completely hijack your thread, so I'll make this short: there are plenty of users here (myself included) that would happily help you get started with C and/or C++ on the Propeller so that you can actually use #include.
  • Actually Spin is smart enough to remove duplicate objects. At least the code and data section will just remain once after compiling, but each copy of a object has its own VAR Section.

    So including objects multiple times does not hurt as much as you think.

    Sadly Spin does not offer a way to access sub objects from other sub objects. You have to build wrapper functions to archive that.

    Enjoy!

    Mike
  • JonnyMacJonnyMac Posts: 9,104
    edited 2016-09-07 00:42
    I, too, am one of those that would love #include and conditional compilation tools in Spin. Yes, I've tried C. I don't like it. Besides, Spin was designed for the Propeller's unique architecture. For my taste, and the work I do, Spin is far more elegant.

    I feel certain it's possible, as Parallax added conditional compilation (not #include, though) to PBASIC more than 15 years ago. For the moment I use constants as switches to run certain sections of code, but I'd really like to remove them from the compilation when not needed (e.g., debugging tools).

    There may be some unexposed tools lurking in the compiler used by PropellerIDE. I think what needs to happen is to allow the user to control compiler switches.
  • AribaAriba Posts: 2,690
    Here is the latest PreSpin-04 fresh compiled with a newer PureBasic version.
    I hope the Antivirus software will not have a problem with it anymore. Sometimes heuristic scanner methodes of Antivirus tools have a problem with compiled PureBasic programs.

    The example and description files are not included, you can download a full ZIP from:
    here

    Andy

  • Thanks, Andy, I didn't know about that. I will give it a try!
  • 1. Modern Spin compilers (openspin, fastspin, homespun) all have #include.

    2. #include may not help you. All it does is deposit a (literal) copy of the file into the source code. This can make programming repetitive things easier, but it won't save on code size.
  • JonnyMac wrote: »
    I, too, am one of those that would love #include and conditional compilation tools in Spin. Yes, I've tried C. I don't like it. Besides, Spin was designed for the Propeller's unique architecture. For my taste, and the work I do, Spin is far more elegant.

    I do kinda like Spin. In the past I've avoided C/C++ like the plague, but working with it on my Propeller bots (and a couple of other projects), I'm finding I rather prefer it to Spin.

    Amanda

  • Thanks everyone for the suggestions. Unfortunately I've done to much work in in spin to go back to C but that may happen for future projects. The links for the preSpin and openSpin are really cool, and I'm working into integrating preSpin into my project. Kudos to the people who wrote the programs that must have been a very painstaking process. I haven't been following the progress on the prop 2 chip to much but has there been any word on whether or not the #include will become a native part of the compiler? Using constants like JonnyMac is of course one way of navigating through multiple objects, or using preSpin to compile everything into one large file, but its not quite as elegant of a solution as the #include. For relatively new programmers like myself not having that function adds another chunk of complexity which hopefully will be removed in future revisions, but of course everything in due time.
  • ElectrodudeElectrodude Posts: 1,657
    edited 2016-09-08 17:28
    Are you thinking of using #include to copy code or headers? In other words, if you were doing this in C, would you be including a .c or a .h file? If you want to #include code, it will use more RAM because there will be multiple copies of each function. If you want to #include function headers, that's what objects are for - the Spin compiler will only ever emit one copy of an object's code, no matter how many different objects use it.

    #include is probably not a good idea for any Spin compiler, since including things via OBJ blocks will always use less memory than #including it. Spin is a very different language than C. The reason C has #include is because of how translation units work. Since Spin doesn't really have translation units, #include isn't necessary.

    Do you really need #include, or are you splitting your code into objects wrong?
  • I would still like to see conditional-compilation controls in Spin. Something like this:
    #define USE_TERMINAL
    
    #ifdef USE_TERMINAL
      term : FullDuplexSerial
    #endif
    
    Andy has some good examples of using PreSpin to conditionally select an output stream.

  • What I'm trying to do is include function headers, so spin took care of this problem for me then, that's nice :). That means I need to look into wrapper functions like msrobots was saying so my sub objects can interact with one another. In one of my previous threads Duane Degn was nice enough to send me a series of links that helped him get started with the spin. I've looked into wrapper functions before but my rookie status has sent me a bit in circles, could anyone suggest some readings on this subject?
  • JonnyMac wrote: »
    I would still like to see conditional-compilation controls in Spin. Something like this:
    #define USE_TERMINAL
    
    #ifdef USE_TERMINAL
      term : FullDuplexSerial
    #endif
    
    Andy has some good examples of using PreSpin to conditionally select an output stream.

    OpenSpin has #define / #ifdef. So do fastspin, bstc, and (I think) homespun.
  • Dave HeinDave Hein Posts: 6,347
    edited 2016-09-08 20:01
    vetter wrote: »
    What I'm trying to do is include function headers, so spin took care of this problem for me then, that's nice :). That means I need to look into wrapper functions like msrobots was saying so my sub objects can interact with one another. In one of my previous threads Duane Degn was nice enough to send me a series of links that helped him get started with the spin. I've looked into wrapper functions before but my rookie status has sent me a bit in circles, could anyone suggest some readings on this subject?
    Spin doesn't use function headers like C does. Spin only allows passing and returning 32-bit values, which are normally interpreted as integers but can also be used as pointers or floating-point values. The only thing the Spin compiler checks for is whether the caller is passing the correct number of parameters.

    Wrapper methods are useful if you want your objects to reference a small number of objects. However, the same number of objects will be loaded whether you use wrapper methods or not since the wrapper method will reference low-level methods. One feature of Spin is that an object can only reference objects located after it memory. You cannot reference a method in an object loaded before another object.

    As an example, let's say there are two objects -- A and B. A can call methods in B, but B cannot call methods in A. This would cause an infinite circular reference if it were allowed. You can work around this by creating a third object, C, that contains methods used by both A and B. In some cases I will include small duplicate methods in low-level object so I don't have to create another object.


  • Thanks Dave,that example clears up my confusion and I think, thanks to everyone input I know in which direction to proceed.
  • An include directive would be great for pin constants. Every board that got laid out could have a read-only pin file that was simply included into the top object. "Include" could also be used to incorporate DAT tables and other variants such as customer logos for display, where the program itself is identical but requires customer-specific information programmed in.

    Couple that with conditional compilation directives, and Prop tool would be the cat's meow.
  • Include directives and conditional compilation are the hallmark of lousy complier implementation. In the presence of even a trivially optimizing compiler, they serve no purpose other than to confuse the source code.

    There is no reason whatsoever to need conditional compilation to prevent the instantiation of an object. If the object is not referenced, it should be removed at link time.

    If-then-else and case statement folding when the predicates can be reduced to constants at compile time are far, far, far superior to any sort of conditional compilation hack.

    Similarly, theres no reason to use include directives for pin constants. Simply have an object with those named numbers and instantiate that object when the pin names are required.
  • kwinnkwinn Posts: 8,697
    ksltd wrote: »
    Include directives and conditional compilation are the hallmark of lousy complier implementation. In the presence of even a trivially optimizing compiler, they serve no purpose other than to confuse the source code.

    There is no reason whatsoever to need conditional compilation to prevent the instantiation of an object. If the object is not referenced, it should be removed at link time.

    If-then-else and case statement folding when the predicates can be reduced to constants at compile time are far, far, far superior to any sort of conditional compilation hack.

    Similarly, theres no reason to use include directives for pin constants. Simply have an object with those named numbers and instantiate that object when the pin names are required.

    Perhaps "if then else" and "case" statements are superior, but I would be happy to settle for "includes" to reduce the clutter the programmer has to wade through in the source code, and "conditional compilation" to simplify coding for different hardware and software options. I suspect includes and conditionals are also simpler to add to an existing compiler as well.
  • Dave HeinDave Hein Posts: 6,347
    edited 2016-09-09 17:16
    ksltd, the current Spin compilers don't have much code optimization. They just translate Spin code to bytecodes. I think that include directives and conditional compilation are reasonable enhancements to Spin compilers. BST does remove unused methods, and it folds constants plus a few other small tweaks. I don't think I would go so far as to call the current Spin compilers lousy compiler implementations.
  • Heater.Heater. Posts: 21,230
    ksltd,
    Include directives and conditional compilation are the hallmark of lousy complier implementation...
    I too dislike the uglyness of include and conditional compilation directives.

    But what is the alternative?

    If I want to compile my code for different operating systems or platforms or with different capabilities and features, then how else do we do it?

    It requires choices to be made at compile time.

    Arguably one could support that kind of configuration in the language syntax itself, rather than bolting on a pre-processor like C/C++. but it needs to be there. Somewhere.


  • Heater. wrote: »
    ksltd,
    Include directives and conditional compilation are the hallmark of lousy complier implementation...
    I too dislike the uglyness of include and conditional compilation directives.

    But what is the alternative?

    If I want to compile my code for different operating systems or platforms or with different capabilities and features, then how else do we do it?

    It requires choices to be made at compile time.

    Arguably one could support that kind of configuration in the language syntax itself, rather than bolting on a pre-processor like C/C++. but it needs to be there. Somewhere.

    I try to put all of the platform-specific code in a single file so it doesn't clutter up all of my generic source files. I suppose that assumes that you have generic source files though.

  • Heater.Heater. Posts: 21,230
    Yes indeed. Layers of abstraction is what makes things portable.

    Somewhere down in the bowels of your code it has to be built this way or that for different systems.

    Even at the higher levels one may want to include or exclude features.

    Include files and ifdef etc are a crude way of "meta programming" like that.

    I don't know what is better than that.




  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2016-09-09 23:16
    One solution is to create objects that are isomorphic with each other but that exhibit different behaviors -- or none at all. Then all you have to do is change the file reference to the object in the OBJ section to select the behavior you want. A null version of FullDuplexSerial, whose methods return without doing anything, would be one example.

    -Phil
  • One solution is to create objects that are isomorphic with each other but that exhibit different behaviors -- or none at all. Then all you have to do is change the file reference to the object in the OBJ section to select the behavior you want. A null version of FullDuplexSerial, whose methods return without doing anything, would be one example.

    -Phil
    Yeah but then you end up duplicating all of the higher level functions in each of the isomorphic objects. It would be nice to have a single implementation of stuff like DEC and HEX and share it among all of the terminal-like objects.

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2016-09-10 04:19
    David Betz wrote:
    It would be nice to have a single implementation of stuff like DEC and HEX and share it among all of the terminal-like objects.
    Oh, I totally agree with that. dec, hex, and others of their ilk do not belong in the I/O drivers. For output, char and str are all that you really need. Everything else can be handled with a universal formatting object.

    -Phil
  • Heater.Heater. Posts: 21,230
    Yes but changing the file reference to an object is changing the code. Where as the #ifdef etc mechanism can be controlled from outside the source code itself. With compiler options.

    I guess one could leave the code untouched and swap out the actual files being referenced.

    Or one could do some funky things with symbolic links to alternative files. On proper operating systems anyway.

  • max72max72 Posts: 1,155
    For PST OBC created a dummy object rather useful..
    http://forums.parallax.com/discussion/122321/pst-with-usb-cable-unplugged
    Simply change the name in the obj declaration.
    Maybe not what you re expecting, but it works fine.
    Massimo
Sign In or Register to comment.