Spin Language Extensions (A Humble Request)
Phil Pilgrim (PhiPi)
Posts: 23,514
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:
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:
you could write:
I may add to or modify this list from time to time. Everyone is welcome to chime in.
Thanks,
-Phil
Update (2009.12.3): Added #5: using blocks.
Post Edited (Phil Pilgrim (PhiPi)) : 12/3/2009 11:39:43 PM GMT
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.
Thanks,
-Phil
Update (2009.12.3): Added #5: using blocks.
Post Edited (Phil Pilgrim (PhiPi)) : 12/3/2009 11:39:43 PM GMT
Comments
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.
Leon
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Amateur radio callsign: G1HSM
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
OBC
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?
Visit the: The Propeller Pages @ Warranty Void.
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
OBC
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?
Visit the: The Propeller Pages @ Warranty Void.
Any early preview of 32 bit Spin would be greatly appreciated [noparse]:)[/noparse]
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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
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.
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.
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.
Project specific search paths can achieve this nicely. A bit like search paths being specified in the Makefile.
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.
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
This would be wonderful - best would be some mechanism like CPAN for the OBEX ... but that's probably too wishful thinking !
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
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.
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
Samuel
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.
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.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
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.
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.
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.
Wow, you try telling them that [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
For me, the past is not over yet.
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.
even if it's just one directory deep, it would be helpful.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
http://www.propgfx.co.uk/forum/·home of the PropGFX Lite
·
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
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
Post Edited (Pavel) : 12/1/2009 8:33:18 PM GMT