Shop OBEX P1 Docs P2 Docs Learn Events
Spin Language Extensions (A Humble Request) — Parallax Forums

Spin Language Extensions (A Humble Request)

Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
edited 2009-12-04 01:23 in Propeller 1
Since the Prop II is in gestation, and Chip and Jeff will be working on the Compiler/IDE in the near future (if not already), I'd like to make some suggestions for useful language extensions. These can also be applied to the Prop I tool as well, all without having to modify the bytecode interpreter:

1. Please, please, PLEASE allow subdirectory references in the OBJ section. My Propeller source directory is a monolithic mess with 456 Spin files (and counting) with no logical way (that I know of) to organize it.

2. Macros and/or hooks to external preprocessors.

3. Lazy evaluation of conditionals. Currently all subexpressions in an AND/OR/NOT expression get evaluated, whether they affect the outcome or not. I would propose the addition of && and || (with the following precedence: comparisons > && > || > NOT > AND > OR). The way && would operate is that if the left operand is false, the right operand is not evaluated. The value returned for a && b is a (i.e. 0) if a == 0, else b. Likewise for ||: if the left operand is true, the right operand is not evaluated. The value returned for a || b is a if a <> 0, else b. This would permit very concise conditionals, both in IF statements and inline, without undesired side effects (e.g. if one of the subexpresisons includes a function call that shouldn't be called due to a prior condition). Inline, these operators could be used as "short circuit" IFs:

result := i > 0 && (do_this(i, x) || do_that(i, x))

'Same as:

if (result := i > 0)
  ifnot (result := do_this(i, x))
    result := do_that(i, x)




4. Inline ternary conditionals: condition ? evaluate_if_true : evaluate_if_false. These expressions would have precedence between || and NOT.

5. using blocks. Instead of the more verbose:

tv.start(12)
tv.out(0)
tv.str(string("x = "))
tv.dec(x)
tv.out(13)




you could write:

[b]using[/b] tv
  start(12)
  out(0)
  str(string("x = "))
  dec(x)
  out(13)




I may add to or modify this list from time to time. Everyone is welcome to chime in. smile.gif

Thanks,
-Phil

Update (2009.12.3): Added #5: using blocks.

Post Edited (Phil Pilgrim (PhiPi)) : 12/3/2009 11:39:43 PM GMT
«1

Comments

  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2009-11-30 21:34
    Phil Pilgrim (PhiPi) said...


    1. Please, please, PLEASE allow subdirectory references in the OBJ section. My Propeller source directory is a monolithic mess with 456 Spin files (and counting) with no logical way (that I know of) to organize it.

    Egads! There will be some scary code posted with that feature! How about just an inclusion of multiple search paths in the IDE itself?

    OBC

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    New to the Propeller?

    Visit the: The Propeller Pages @ Warranty Void.
  • LeonLeon Posts: 7,620
    edited 2009-11-30 21:37
    Just run the code through a macro-processor like m4. You can do almost anything with it.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-11-30 21:51
    OBC,

    A problem with just using paths exists if objects in two subdirectories have the same name. Rather than constantly fiddling with the path order, it's easier just to specify the subdirectory directly. If an object is not found in the requested subdirectory, or if the subdirectory doesn't exist, the compiler can then search for it in the specified path. This would make posted code easier to deal with, since there's a default escape route.

    Leon,

    True enough. Running the code through a macro processor would be easier, of course, if #2 (preprocessor hooks) were implemented. I still think a hierarchical grouping of objects should be native to the language, though. A one-level grouping already exists in the OBEX. Such a hierarchy works just fine for Perl modules, BTW. So I can't see why it wouldn't work for Spin.

    -Phil
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2009-11-30 21:58
    As long as the "archive" process removes the sub-directories from the source during packaging, then it would prevent issues. [noparse]:)[/noparse]

    OBC

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    New to the Propeller?

    Visit the: The Propeller Pages @ Warranty Void.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-11-30 22:11
    OBC,

    It's possible for zip files to include directory info. I think that it should be okay for unzip to create directories for the archived sub-objects, so long as they're relative to the top-level directory that's being unzipped to. I would probably draw the line at absolute references in the OBJ specs anyway.

    -Phil
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2009-11-30 22:14
    Now that we've hammered down the specifics of the requested feature we need to twist Jeff Martin's arm a little. [noparse]:)[/noparse]

    OBC

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    New to the Propeller?

    Visit the: The Propeller Pages @ Warranty Void.
  • jazzedjazzed Posts: 11,803
    edited 2009-11-30 22:18
    Library paths are very important to large projects and code sharing ... especially when the tool version changes and one has to manually move their library. I hope "specified paths" is not taken as a "one or the other" substitute.

    Any early preview of 32 bit Spin would be greatly appreciated [noparse]:)[/noparse]
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-11-30 22:21
    Oldbitcollector said...
    Now that we've hammered down the specifics of the requested feature we need to twist Jeff Martin's arm a little. [noparse]:)[/noparse]
    I dunno, man; it's not the first time I've brought this up. (Actually, Chip might have to get involved in this one, since it's a language feature more than an IDE feature.) At one time, I thought it was in the Spin project queue; but priorities change, I guess.

    -Phil
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-11-30 22:32
    RE point 1 (sort of 2) - wouldn't an #include directive with sub-dirs allowed also be useful (not just in the OBJ section, but anywhere) ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • AribaAriba Posts: 2,690
    edited 2009-11-30 23:12
    Yes, #INCLUDE and conditional compiling without an external preprocessor would be nice.

    And the option for an external loader. The IDE should just write the compiler result to a file, and call then a
    specified external program, which loads the code in the Propeller.
    This allows wireless Loaders and Software-USB loaders with the adequate boot code in the EEPROM.

    Andy
  • SRLMSRLM Posts: 5,045
    edited 2009-11-30 23:37
    Conditional compiling would be extremely useful. When working with robotics, I have two different modes of debug: a 4x20 LCD on the robot and PST. The first is used when the robot is moving around, and the second is used when the robot is at the bench. These two destinations require different styles of debugging in order to best display the information, so I need different blocks of code for each. As it stands, I have to comment out one set of code and uncomment the other.

    The commenting quickly becomes tedious and error prone. A better solution would be to change a single line, and have the compiler ignore one or the other.
  • rokickirokicki Posts: 1,000
    edited 2009-11-30 23:43
    For this, you might want to look at the "sysdep.spin" file supplied with fsrw.

    It's made to support different environments; the sysdep.spin provides "console I/O" and some other
    things and you just tweak it once for whatever environment you want.

    This way you only need change a single file rather than a bunch of commands.

    You can see the file here:

    http://fsrw.hg.sourceforge.net/hgweb/fsrw/fsrw/file/71b4036e58f9/sysdep_demo_ser.spin

    and our example usage is here:

    http://fsrw.hg.sourceforge.net/hgweb/fsrw/fsrw/file/71b4036e58f9/test.spin

    Of course conditional compilation is even better, but this hack is useful.
  • BradCBradC Posts: 2,601
    edited 2009-11-30 23:45
    Phil Pilgrim (PhiPi) said...

    A problem with just using paths exists if objects in two subdirectories have the same name.

    That's a pretty easy thing to fix. Just don't use the same name in two library paths. Operating systems have done this since /lib was invented.
    Phil Pilgrim (PhiPi) said...

    Rather than constantly fiddling with the path order, it's easier just to specify the subdirectory directly.

    Project specific search paths can achieve this nicely. A bit like search paths being specified in the Makefile.
    Phil Pilgrim (PhiPi) said...

    If an object is not found in the requested subdirectory, or if the subdirectory doesn't exist, the compiler can then search for it in the specified path. This would make posted code easier to deal with, since there's a default escape route.

    This is a *nasty* way for things to work. If you specify a path directly and the path does not exist, it's an error. The last thing you want is the compiler trawling search paths trying to guess what you really meant.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-12-01 00:25
    BradC said...
    This is a *nasty* way for things to work. If you specify a path directly and the path does not exist, it's an error. The last thing you want is the compiler trawling search paths trying to guess what you really meant.
    Fair enough. This was admittedly a kludge to address the archive issue. But having unzip create the requisite subdirectories is a better solution anyway.

    Path specs are not an adequate substitute for an object-by-object subdirectory specification. They're only a starting point for for finding the main object directory. Perl, for example, uses all three search trajectories: global path, local path (spec'd in the source file), and individual module hierarchies, relative to the first two. This is what I'd like to see for Spin as well, although I consider the local path optional.

    -Phil
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-12-01 00:29
    PERL has spoiled you, Phil :-P

    This would be wonderful - best would be some mechanism like CPAN for the OBEX ... but that's probably too wishful thinking !

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • BradCBradC Posts: 2,601
    edited 2009-12-01 00:45
    Phil Pilgrim (PhiPi) said...
    BradC said...
    This is a *nasty* way for things to work. If you specify a path directly and the path does not exist, it's an error. The last thing you want is the compiler trawling search paths trying to guess what you really meant.
    Fair enough. This was admittedly a kludge to address the archive issue. But having unzip create the requisite subdirectories is a better solution anyway.

    Path specs are not an adequate substitute for an object-by-object subdirectory specification. They're only a starting point for for finding the main object directory. Perl, for example, uses all three search trajectories: global path, local path (spec'd in the source file), and individual module hierarchies, relative to the first two. This is what I'd like to see for Spin as well, although I consider the local path optional.

    One thing that would be handy is recursive searching of a library directory. I'm not sure how best to handle that though. You don't want (or maybe you do) a recursive search of '.'.

    I'd have thought in the context of spin, "local path" meant the directory the top object file was located in. Have I got my wires crossed?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-12-01 01:16
    CounterRotatingProps said...
    This would be wonderful - best would be some mechanism like CPAN for the OBEX ... but that's probably too wishful thinking !
    It would be nice, certainly, but CPAN requires an enormous amount of labor to enforce consistency in the hierarchies that modules are assigned to. It's rather more than I would expect Parallax to take on.
    BradC said...
    I'd have thought in the context of spin, "local path" meant the directory the top object file was located in. Have I got my wires crossed?
    That's why I said it could be optional. I very seldom use that feature in Perl. Frankly, the only reason it exists there is that module references default to the global Perl library. To look for them elsewhere, you have to prepend a different path. When your script is run on a hosted server, you can't add your path to the global path; you have to do it locally in the source. It's different in Spin, since the editor tabs and top-level directory take precedence over the library. For this reason, I might suggest the pseudodirectory names $lib and $local, which could be used in OBJ to supercede the path order, if necessary.

    -Phil

    Post Edited (Phil Pilgrim (PhiPi)) : 12/1/2009 1:21:14 AM GMT
  • SamMishalSamMishal Posts: 468
    edited 2009-12-01 06:34
    I would like to see a TIMEOUT WaitPeq() and WaitPNe()

    Samuel
  • BradCBradC Posts: 2,601
    edited 2009-12-01 07:10
    SamMishal said...
    I would like to see a TIMEOUT WaitPeq() and WaitPNe()

    That's not a language extension so much as a complete re-work of those opcodes in the chip itself. I believe I recall Chip mentioning timeouts in passing during the last little flurry of Prop2 thread.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • BradCBradC Posts: 2,601
    edited 2009-12-01 07:13
    Phil Pilgrim (PhiPi) said...
    My Propeller source directory is a monolithic mess with 456 Spin files (and counting) with no logical way (that I know of) to organize it.

    I keep re-reading this, and I keep wondering what is special about your code that requires it all be dumped in a single directory. I've got mine nicely separated into a couple of library directories (Parallax and the rest) and then each project has its own subdirectory under my project tree.

    If I *need* to share a file between projects and I don't want to commit it to one of the library directories I just make a symlink between the two.

    I'm about the least organised person on the planet.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • heaterheater Posts: 3,370
    edited 2009-12-01 07:18
    Windows guys don't have the luxury of symlinks if I understand correctly.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • jazzedjazzed Posts: 11,803
    edited 2009-12-01 07:31
    Cygwin makes symlinks that Windows can follow [noparse]:)[/noparse]
  • BradCBradC Posts: 2,601
    edited 2009-12-01 09:58
    heater said...
    Windows guys don't have the luxury of symlinks if I understand correctly.

    Ok, but they are the exception rather than the rule. I think I've used them 2 or 3 times at most. My point was more about finding a way to organise the code rather than dumping it in an unmanageable pile. I must be missing something.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • Clock LoopClock Loop Posts: 2,069
    edited 2009-12-01 10:08
    I found myself running into the object directory issue also.

    My main spin folder has hundreds of objects in it too. I ended up making subdirectories for each project and copying the spin files into each directory.


    But the issue with this is if you want to update all of your FULLDUPLEXSERIAL.SPIN files to the latest version, depending on how many copies you have in your subdirectories, you might be busy for a while.



    I would like being able to specifiy subdirectories so I can have objects in their own subfolder, and only a single copy, even if 20 of my projects use it, instead of having to copy it 20 times into each projects folder.
  • BradCBradC Posts: 2,601
    edited 2009-12-01 10:11
    Clock Loop said...

    I would like being able to specifiy subdirectories so I can have objects in their own subfolder, and only a single copy, even if 20 of my projects use it, instead of having to copy it 20 times into each projects folder.

    Even the Propeller Tool has one library folder. Put them there next to the Parallax libraries.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    If you always do what you always did, you always get what you always got.
  • heaterheater Posts: 3,370
    edited 2009-12-01 10:22
    BradC: "Ok, but they are the exception rather than the rule"

    Wow, you try telling them that [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • Clock LoopClock Loop Posts: 2,069
    edited 2009-12-01 10:46
    BradC said...


    Even the Propeller Tool has one library folder. Put them there next to the Parallax libraries.


    This dosen't solve the organization issue at all, the reason behind having subfolders is so one does not have to look through 100+ objects in ANY single folder.
  • BaggersBaggers Posts: 3,019
    edited 2009-12-01 10:49
    I'd also like to offer a suggestion, the "FILE" command being able to chose a file from a sub-directory, thus tidily keeping binaries away from the sources. [noparse]:)[/noparse]
    even if it's just one directory deep, it would be helpful.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    http://www.propgfx.co.uk/forum/·home of the PropGFX Lite

    ·
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-12-01 20:15
    BradC said...
    ... and then each project has its own subdirectory under my project tree.
    LOL! Sorry, 'don't mean to poke fun, but that's the way I used to organize my electronic components: by project. 'Worked fine when there were only a few projects; but as the number of active projects grew, I found I was losing track of which project a certain part was stored with, and I ended up making duplicate purchases. Now, however, all my components are organized by category and value, each with its own bag/box/drawer (i.e. subdirectory). When I need an LM7805, I know to look for it in the Voltage Regulator ziplock bag in the Semiconductors box. And life is good.

    This does raise an interesting question, though, about organizing projects. Partitioning top-level files into project groups destroys the strict hierarchy between top-level files and library files. I think someone suggested allowing ".." in the OBJect path, which could solve this to some extent, without resorting to absolute paths. Pseudodirectory names, like "$lib" and "$local" might also be part of the solution.

    There are still some open implementation questions, I guess; but I'm convinced it's a worthy pursuit.

    -Phil
  • PavelPavel Posts: 43
    edited 2009-12-01 20:28
    If you use source control system such as Perforce or CVS (you all are, right?), you can put the common objects that you want to share across several projects into repository, use the checkout to put local copies in each project's directory and use the source control to keep them in sync. I understand that this sounds rather incomprehensible if you are not well versed in source control, but it's actually quite simple (at least with Perforce source control, I haven't tried the CVS).

    Granted it's a kludge and Propeller tool is really lacking in this department (I'd actually rather have include paths, save on compile, built-in terminal and conditional compilation in the Propeller Tool than the rumored Propeller II chip). I guess I'm rather software oriented smile.gif

    Post Edited (Pavel) : 12/1/2009 8:33:18 PM GMT
Sign In or Register to comment.