SPIN2PASM translator idea
T Chap
Posts: 4,223
Here is an idea I have been kicking around for my own use. I do not have time to learn PASM, but have found that if I can see snippets of code with Spin equivalents then I can put together a very simple library of 'modules' in a text file, and use them quite easily when needed.
The idea of the app is to have modules available as separate text files in a Lib folder. The modules gets loaded in the "Load Module From Lib" menu. The content of the module is shown in the Enter/Display Module Content text pane. The names of the module are translated to current names with the Assign Names. The Translate button converts the module to the PASM equivalent (same names of current vars etc). Send Result To Block copies the translated content to the Compose From Modules pane. All panes can be edited manually, then copied and pasted to BST or PropTool. The result can be inserted anywhere in the block where the mouse is placed. A new module can be created by entering the Spin version in the Enter New Module Name, then entering the translation in the PASM Enter/Display pane, and saving the module. Any module can be updated or deleted or saved as a new module name. It is possible to set modules into different folders for specific uses, to avoid scrolling through a single list.
The concept being that anyone can create a module and post it, anyone can download a module and drag it to their Lib folder for future use.
Many modules can be created from the manual alone.
Anyways, just an idea I may develop for my own use. If there is interest and others would contribute modules, I would post it. Mac and PC versions identical.
I will change the name to btw since there is some copyright infriengement going on [noparse]:)[/noparse]
Post Edited (TChapman) : 8/26/2009 5:30:27 PM GMT
The idea of the app is to have modules available as separate text files in a Lib folder. The modules gets loaded in the "Load Module From Lib" menu. The content of the module is shown in the Enter/Display Module Content text pane. The names of the module are translated to current names with the Assign Names. The Translate button converts the module to the PASM equivalent (same names of current vars etc). Send Result To Block copies the translated content to the Compose From Modules pane. All panes can be edited manually, then copied and pasted to BST or PropTool. The result can be inserted anywhere in the block where the mouse is placed. A new module can be created by entering the Spin version in the Enter New Module Name, then entering the translation in the PASM Enter/Display pane, and saving the module. Any module can be updated or deleted or saved as a new module name. It is possible to set modules into different folders for specific uses, to avoid scrolling through a single list.
The concept being that anyone can create a module and post it, anyone can download a module and drag it to their Lib folder for future use.
Many modules can be created from the manual alone.
Anyways, just an idea I may develop for my own use. If there is interest and others would contribute modules, I would post it. Mac and PC versions identical.
I will change the name to btw since there is some copyright infriengement going on [noparse]:)[/noparse]
Post Edited (TChapman) : 8/26/2009 5:30:27 PM GMT
Comments
While there are many common elements between Spin and Pasm, I also think there are enough differences in both language and program architecture that simple module type substitution doesn't really address...· I'm thinking that the choice to use Pasm might often be dictated by speed requirments, where fine tuning and use of tricks such as self modifying code are key to a good Pasm program.· I'm not sure those aspects can be emulated by a module swapping ideology.
This is just personal opinion.· Your suggestion might serve as a good introduction to how Pasm operates, but if you are only plugging in modules to creat your Pasm code I think you may be missing a big part of the picture.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Most people here know Spin, and those who don't pick it up fast. It seems that some people are afraid of PASM, but really should not be. Building a library of equivalents as you are suggesting may be better than creating some kind of a compiler/interpreter/translator for learning since people have to put their fingers in it to make it work. There are some challenges though especially are in how to use registers effectively as variables or subroutine parameters and how to glue together pieces. There is a method for parameter passing that allows something generic, but it is a bit wasteful. COGs naturally require thrifty thinking.
What is your GUI environment? I've been looking at Python/Tkinter hoping to serve all users transparently. I know Java, but there is always something difficult about that for some reason. Sorry Phil, Perl/CPAN was a long, daunting install :<
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
- Propalyzer: Propeller PC Logic Analyzer
- BMA: An on-chip PASM Debugger
- SPUD: Spin Source Level Debugger
Post Edited (jazzed) : 8/27/2009 3:27:30 AM GMTCertainly I know very little about PASM, this is more tool to drop in SPIN > PASM examples when such a side by side analogy is doable.
I recently had someone translate a SPIN project, and they left the SPIN as comments, making it very easy for me to go in and edit, add parts, delete parts, even create brand new PASM code for other uses with copy and paste. That experience being the inspiration behind putting in the most commonly used basics from the manual for reference in a menu list. Surely I have no delusions about a compiler or even faux complier.
like
an if condition
a loop that is n times repeated
is shown how it is coded in ASM and EVERY dammed detail - and if I say EVERY dammed detail -
I mean E V E R Y dammed detail !!!
of what the ASM-code is doing
like
add t3,txbuff
command "add":
add the following
HUB-RAM adress ... contains value x
HUB-RAM adress ::: contains value y
t3 contains value .... which means take value x (stored in HUB-RAM-adress ....
txbuff contains value ::: which means take value y (stored in HUB-RAM-adress ::: add x to y
store result of the addition in HUB-RAM-adress ... so after executing the commadline in HUB-RAM-adress ... the new value is x+y
and this will become well understandable when CONCRETE values are filled in for EVERYTHING and the values of all RAM-adresses are shown before and after
executing the command.
I haven't used any PASM-debugger yet. And I guess (sorry if I'm wrong) the examples and documentation of the available debuggers
is NOT as detailed as I described it above. And I think this is the only reason why people that are new to ASM find it difficult to understand.
If the manual slows down its "speed" of explanation down to this REALLY low level it will become very easy to understand.
@ the authors of the debuggers: If you take your explanation of your debugger to this level you will be a hero even abroad of the propeller-community
as then your manual explains things so easy to understand that it will be useful for a lot of other MCUs too !
best regards
Stefan
Consider·SX/B for example. As you know, one of the neat things Bean and JonnyMac, et. al., did is having it seemlessly present the SASM code. It really helps me to learn and work with SASM. You can write an algorithm in the 'higher level' SX/"Basic" and see what SASM it generates. Then take the SASM and dork with it, breaking it, fixing it, tweaking it to little bits... the more you tweek, the more you learn ... just as you say.·
At some point, you get to know the SASM well enough to crank it out directly·- or know when to reuse older code.· Bean's and Johhny's·SX/B to SASM generator produces tight, clean code - doing things I would have never thought of had I not seen them do it first.
Think of it like a Canned Wizard - A Code Wizard, Mr.Wizard
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
- Propalyzer: Propeller PC Logic Analyzer
- BMA: An on-chip PASM Debugger
- SPUD: Spin Source Level Debugger
Post Edited (jazzed) : 8/27/2009 3:27:19 AM GMTThe speed disparity between PASM and Spin is *SO* great that there probably would be some use for this, but it's going to be very memory intensive (PASM takes a lot more RAM than Spin even when optimized). Something like the loop requested downforum to count the similar bits in two arguments might be do-able this way. But if the autoPASM code is at all Spin-friendly it's not going to be much like real PASM code; in PASM you must use inefficient Hub instructions to access Hub RAM whereas in PASM you can do all kinds of complex operations with tests all at once on cog registers/memlocs. I tend to feel the work invested in creating the tool would be better spent learning to write PASM code from scratch.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
- Propalyzer: Propeller PC Logic Analyzer
- BMA: An on-chip PASM Debugger
- SPUD: Spin Source Level Debugger
Post Edited (jazzed) : 8/27/2009 3:27:40 AM GMT@TChapman, let me know how I can help with your project.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
- Propalyzer: Propeller PC Logic Analyzer
- BMA: An on-chip PASM Debugger
- SPUD: Spin Source Level Debugger
Post Edited (jazzed) : 8/27/2009 3:26:39 AM GMTGood idea. I would take this a step further and both write a commented version in as much detailed as you wish, then write the version to be used in the module for translation, delimit the two sets of info, show the comment and notes section in a separate pane.
It is just a simple text file per module, with a file name, with two sets of info inside delimited by some marker to split it.
Like I mentioned before, I personally can't put time into learning PASM other than a cursory glance. This tool would be written by someone else when I figure out what it should do, then just use it to learn over the coming months or years as needed, for me on a need to know basis is ideal.
Surely this doesn't handle many problems. In the least, a condensed SPIN > PASM reference (for what can exist side by side) under a menu seems appealing.
I feel your pain re PASM. There is nothing inherently complicated about it per-se. It is just that all assembly languages are complicated to learn. Or at least, learn well enough to code without thinking too much. The only way I was able to learn Z80 assembly was to write a compiler. And having done that, I know that learning another form of assembly will be hard.
But most assembly ends up similar, which is where compilers like TASM come in, as they are able to compile many types of assembly using tables. TASM is a generic assembly compiler.
Then there are cheeky projects that convert one form of assembly to another, eg Z80 to PIC www.geocities.com/dinceraydin/pic/z80like.html
But getting back to your original suggestion, I've done something similar in the N8VEM IDE for assembly, where you have library blocks that you drop into the code at the cursor location. Eg string handling, floating point math, file I/O, loops. Then you don't need to think in assembly. Think 'I want to open a file, save 'hello world', and close the file. Well, that will be the file library and the string library. Copy them into the codespace and the program is 90% written. It works even better if you have both the code block, and an example of how to use it as well (in the comments section). The example also needs to be completely self contained, eg you copy the code example in, uncomment the 'how to use' and it will then run as a complete program. No "extra" bits to add and it is a good way to learn a language to by seeing little examples that are totally self contained and fit on a single page. Eg the Basic equivalent of MID$() in assembly.
I think you are definitely on to something here. Please keep us posted.
Post Edited (Dr_Acula) : 8/27/2009 7:07:51 AM GMT
It could translate small snippets of spin into pasm
or
Create an entire pasm program skeleton that is then filled in with pasm
code as the user just answers questions about what s/he would like to do.
These are rather complex programs to create unless they are very limited in scope.
It's nice that you get to write it for a pc to run instead of a controller
Even a very limited pasm generator app would be useful for beginners.
A well written pasm generator would be superior to any compiler for the prop
because of the prop's very limited memory. You would end up with a pure
pasm program that could then be tweaked by hand for max speed.
The prop requires pasm to operate at full potential in any application that
approaches the prop's limits.
If the generator had both a spin to pasm and a C to pasm mode it would be
instantly usable to those coming over from other controllers like AVR, ARM.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- Some mornings I wake up cranky.....but usually I just let him sleep in -
Post Edited (HollyMinkowski) : 8/27/2009 12:41:26 PM GMT
Are having templates available worthwhile? If so, what would be the foundation of a template? How many templates for a starter kit? If having templates are a god idea to call up from a menu, then the template would be a .tmp file and get stored in a separate folder.
With a limited knowledge of PASM, it appears on the surface that there are two main ways of doing something. Either a) reading Long from outside the cog or b) reading a variable or constant from the cog. If reading a Long that is being affected in another program, what I can tell is that you would send a pointer to that Long as a parameter, then assign the pointer to a Long within the cog. At least that's how I perceive it.
The point being, there needs to be a definitions area that translates the initial module's SPIN formula to the PASM version. In the mock up at the top of the thread, I simply called this "Assign Names", which means what names in the module are to be substituted in the PASM version. What I think really needs to happen for the very simple starting point, is that there would be two sets of Assigns, or definitions rather. One set that deals with Longs from hub (the Longs referenced by the pointers passed to it the cog, and the cog memory (possibly constants and vars). So maybe 3 then, if you have to count constants differently, which is an unknown right now.
The point being, that if there is a basic math problem, X := Y in the module named "X := Y", then the translation needs to know where these values in PASM are coming from, if a RDLONG is required to read the hub memory into cog memory, then that translation requires a few extra steps.
An example of using RDLONG to get the value of a variable that is being updated outside the cog:
SPIN module name "if X > Y" using HUB
PASM output
There needs to be a way to determine if the X an Y are hub or cog. The above example is where x and y are hub, being updated in another program for use by the PASM program.
So perhaps if there were a button for translating using hub or cog, and then the definitions are set as to what are the equivalent temp vars in PASM, you could press one button to translate using hub, and one to translate using cog, and define what the hub pointers are and cog vars are.
The cog version being simpler:
SPIN module name "if X > Y" using COG
PASM output
Anyways, this is what I think the beginning stages would entail, some input would be great. Obviously this is a challenge, but if it only solved very basic translations it would be fun and a great learning experience.
Thoughts, corrections, input welcome.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
I am thinking to leave ' for comments, and...
<CODEBLOCK>
as a place holder. Possibly placeholders with a number <CODEBLOCK1>, so that a future translation can be assigned to replace a specific block if desired. Everything on a same line including and following a ' will get removed in the result, with maybe an option to include comments?
Repeat 10
<CODEBLOCK2>
Will the djnzindex long 0 Long instance be manual or automatic? If auto, then it will have to placed it in the right area. Probably easier for now to predefine some vars in the cog for use, then just use the definitions input to set the var to use in the output.
Having your template use a CODEBLOCK enumerated identifier is a good idea. This way, you only need to increment the block number for each template copied. It can also be extended to variable names, etc....
You could write 2 files while you're building the solution: one for code and another for variables. Then at the end you could concatenate the variables. Keeping track of the number of lines of code and number of variables will be important so you can let the user know if the 512 long bound is exceeded.
Sometimes longs need to be defined like $ffff (or $7ff0) and would be a common thing, so special variables like this should be reused and not enumerated. Not sure how one could do that though.
There may be a way you could eliminate redundant use variables, but the approach being used seems to cry for unique variables. You could have the user specify temporary variables, but that would require user's to know for sure that the variable is not used in a subroutine call.
There is a way to stuff parameters for "call" that Phil mentioned in Tricks & Traps. It uses up longs, but I think there is no choice but do that for a generic solution.
The REPEAT infinitely code block does not need an index of course [noparse]:)[/noparse] Following your convention ....
Another common thing in PASM is a jump table for commands. The only spin equivalent I can think of is a CASE statement, if ... elseif ... elseif ... else, or maybe obj.method call. I'll explore that later.
Enjoy your trip.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
Just kidding. I've done some PCB stuff, but I don't love it enough to be any kind of threat. Fact is though, hardware is where you can make money in this little universe. Software is too easy to write. There are some things I want to finish like my XMM board and the PocketProp PCB. I'd like to get BigSpinVMM working (an extension of the debugger) though so that XMM is useful for Spin also. So many distractions!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools