Shop OBEX P1 Docs P2 Docs Learn Events
SPIN2PASM translator idea — Parallax Forums

SPIN2PASM translator idea

T ChapT Chap Posts: 4,223
edited 2009-08-28 01:52 in Propeller 1
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
888 x 616 - 127K

Comments

  • Agent420Agent420 Posts: 439
    edited 2009-08-26 18:05
    I'm not a Pasm expert yet (though I've machine coded other platforms)... this seems like a manually operated compiler system of sorts.· C compilers operate a bit like this, but usually incorporate some strategic logic to get the smallest or fastest code.

    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.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • jazzedjazzed Posts: 11,803
    edited 2009-08-26 18:29
    I like what you're suggesting .... hope that doesn't kill the thread [noparse]:)[/noparse]

    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 Post Edited (jazzed) : 8/27/2009 3:27:30 AM GMT
  • T ChapT Chap Posts: 4,223
    edited 2009-08-26 18:54
    I looked at PERL once per Phils suggestion, couldn't even figure out how to run it. I like Realbasic and find that it will do anything I have tasked it to do. There is a fantastic forum for it and instant response for most questions much like Parallax.

    Certainly 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.
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-08-26 20:50
    I think doing small things in SPIN
    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
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-26 21:28
    Steve (jazzed) said...

    ... ·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....
    Yes,·but that also might be a good reason to support TChapman's suggestion.

    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 wink.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • jazzedjazzed Posts: 11,803
    edited 2009-08-26 21:55
    Howard, I thought I was being supportive of the TChapman idea [noparse]:)[/noparse] Yes, I do remember working with the SX. It's a nice little chip.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools Post Edited (jazzed) : 8/27/2009 3:27:19 AM GMT
  • localrogerlocalroger Posts: 3,452
    edited 2009-08-26 22:35
    I've written a number of interpreters and (admittedly half-derriered) compilers for my own use. The main problem I see with this module approach is that cogs only have 496 instructions to play with, so you will at best get very limited functionality out of these modular routines. Remember you will have some overhead because PASM can't be inline with SPIN; you need some overhead to leave a command for the PASM code in a running cog, wait for the result, and collect it, or you must COGNEW (takes 8,000 cycles or about 20-40 Spin instructions to start) and still wait for the result when the cog stops itself.

    The 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.
  • CounterRotatingPropsCounterRotatingProps Posts: 1,132
    edited 2009-08-26 22:47
    OH, sorry Steve ... Yes indeed, my bad - I misread your reply ... %^))

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • jazzedjazzed Posts: 11,803
    edited 2009-08-26 22:58
    @localroger, etal: When I was working on my version of a PASM debugger stub, it occured to me that one could throw some PASM into a COG and run it on demand. I'm doing that in a way for getting the Carry and Zero flags now, but the process requires building an instruction in one location that can be executed with a jmp. A more generic "code runner" could be devised for in-lining PASM with Spin, but I fear it would be harder to use than PASM because special things might need to be done to the PASM to make it work. If anyone cares about trying that though, a different thread of discussion would be appropriate.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools Post Edited (jazzed) : 8/27/2009 3:27:40 AM GMT
  • localrogerlocalroger Posts: 3,452
    edited 2009-08-26 23:58
    @jazzed... how would this be different from the LMM?
  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 00:41
    @localroger, At first glance it is very similar ... however "Pasmlets?" 1) would run at speed, 2) could be loaded in-COG on demand - code base/size specified by spin, pulled in and started by COG stub, 3) could use native jmp with adjustments, 4) would need relative source/destination location adjustments, 5) code could be located off chip - not unique but interesting, 6) could remain in COG if necessary, 7) need not be located in the same object file. Some of that may not be unique. Again this is off-topic, if there is further interest, we need to move to another thread.

    @TChapman, let me know how I can help with your project.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools Post Edited (jazzed) : 8/27/2009 3:26:39 AM GMT
  • T ChapT Chap Posts: 4,223
    edited 2009-08-27 00:52
    StefanL38 said...

    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


    Good 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.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2009-08-27 06:52
    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.

    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
  • HollyMinkowskiHollyMinkowski Posts: 1,398
    edited 2009-08-27 12:30
    A pasm generator program would be nice.

    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 smile.gif

    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
  • T ChapT Chap Posts: 4,223
    edited 2009-08-27 15:59
    I think there are a few things to sort out before building a very simple starter app.

    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

    PUB Tester( iradr) 
    radr := iradr
    return COGNEW( @cogstart, @cogstart )
    
    DAT 
    radr            LONG    0
    
                   RDLONG  ctmp1, radr        
                    MOV     ctmp2, radr        
                    ADD     ctmp2, #4              
                    RDLONG  ctmp2, ctmp2        
                    CMPS    ctmp2, ctmp1    WC  
        IF_NC   JMP     ??  'jmp or do something else with other module, or help instruction 
    
    ctmp1           RES     1              
    ctmp2           RES     1
    
    
    
    



    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

                    CMPS    tmp2, tmp1    WC    
        IF_NC   JMP     ??   'jmp or do something else   with other module  or help instruction       
    
    
    tmp1           RES     1              
    tmp2           RES     1 
    
    
    




    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.
  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 17:35
    So you need primitives? Ok, Here's one. Not a perfect template idea, but maybe a start.

    '-----------------------------------------------------------
    {{
    A PASM repeat Number loop ...
    Replace PAR with some hub address or other PASM variable.
    Put PASM in CODEBLOCK tag placeholder
    ====
    SPIN Equivalent:
      repeat N
        ' <CODEBLOCK>
        ' </CODEBLOCK>
    ====
    }}
    
      djnzindex long 0
      rdlong djnzindex, PAR
    :djnzloop
      ' <CODEBLOCK>
      ' </CODEBLOCK>
      djnz    djnzindex, #:djnzloop
    
    '-----------------------------------------------------------
    
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Steve

    Propeller Tools
  • T ChapT Chap Posts: 4,223
    edited 2009-08-27 18:11
    Thanks Jazzed, I think we need both N and a fixed repeat example. See if this is ok. I will start plugging in some of the basic examples over the weekend and post the app soon. Traveling tomorrow through Monday so time will be limited till I return.

    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>


    
      djnzindex long 0
    
      mov djnzindex, #10
    :djnzloop
      <CODEBLOCK1>
      djnz    djnzindex, #:djnzloop
    
    





    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.
  • jazzedjazzed Posts: 11,803
    edited 2009-08-27 18:53
    Having djnzindex in the code itself is probably a bad idea since it may eventually become something other than a NOP smile.gif It's best to put the variables at the end.

    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 ....

    '-----------------------------------------------------------
    {{
    A PASM repeat loop ...
    Put PASM in CODEBLOCK tag placeholder
    ====
    SPIN Equivalent:
      repeat
        <CODEBLOCK>
    ====
    }}
    
    :jmploop
      <CODEBLOCK>
      jmp #:jmploop
    
    '-----------------------------------------------------------
    
    



    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
  • RaymanRayman Posts: 14,849
    edited 2009-08-28 01:01
    Jazzed: You seem to have already done all the cool programming stuff I'd do if I had the time! (except for a BASIC compiler, of course). I'm just glad you aren't too much into PCB layout yet... Then, I know I'll be in trouble!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    My Prop Info&Apps: ·http://www.rayslogic.com/propeller/propeller.htm
  • jazzedjazzed Posts: 11,803
    edited 2009-08-28 01:52
    Rayman said...
    Jazzed: You seem to have already done all the cool programming stuff I'd do if I had the time! (except for a BASIC compiler, of course). I'm just glad you aren't too much into PCB layout yet... Then, I know I'll be in trouble!
    You're NEXT devil.gif

    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
Sign In or Register to comment.