Shop OBEX P1 Docs P2 Docs Learn Events
Spin to Basic — Parallax Forums

Spin to Basic

Dr_AculaDr_Acula Posts: 5,484
edited 2011-03-25 06:14 in Propeller 1
Next crazy project - a Spin to Basic converter!

The aim here is to take an existing object and split up the Spin code and convert it to Basic or C. Given that the BCX Basic to C converter is now working so well, and given that Spin is possibly closer to Basic than to C, I am thinking of writing a program to convert Spin to Basic. Then you can run it through BCX and get Spin to C as well.

The PASM part is already working by extracting it and running it through Homespun.

So the aim is to convert Spin to Basic eg
1) find and replace. Convert "Repeat" to "For" or Do Loops.
2) Convert the indents into blocks of code by inserting things like "End If" and "End For" at the end of the block.
3) Maths. Convert == to = Convert := to = Some things in BCX can even stay the same, eg += *=
4) Convert some things through to Catalina C directly, eg Bytemove gets converted to existing Peek and Poke functions, ditto reading the counter, reading pins.
5) Variable declarations - PUB mypub | a,b,c becomes
Sub mypub
Dim a As Integer
Dim b As Integer
Dim c As Integer

That is the theory anyway!

Next question is what program to write this in. Ideally it would be something that can run on both windows and linux. Heater found Qt recently which looks great. However, for quick programming I'd prefer Basic, so I thought I'd check out Basic programs that can run on both platforms. The 'universal' language out there seems to be Java, and on my Apad there is a great development platform called Basic4Android that takes Basic code and converts it to Java. So I figured maybe there is something similar we could use here that takes Basic and uses the power and universality of java behind the scenes.

I have managed to find this program http://www.jabaco.org/download.html

I must say that this program is the fastest program I've ever used from download to a Hello World. It will take longer to describe this than to actually do it, and I was wondering if some kind soul with a linux box can check if it works on linux too:

1) Website http://www.jabaco.org/download.html
2) Put in email and click register
3) Click the download button. About a 6 meg file
4) Install it
5) Email will have arrived by now with the registration. Copy and paste the number
6) Start with "SDI application"
7) Put a button on the form
8) Put a label on the form (the "A")
9) Double click the button which goes to the code view
10) type in Label1.Caption="Hello World"
11) Click the green triangle "run" button at the top
12) Click the button and it will change the label to "Hello World"

I already have java on my computer, and I guess there is a chance one might need to get java?

If this works on linux, I am very tempted to take the Catalina IDE and move it over to jabaco.

Thoughts and feedback would be most appreciated.

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2011-02-20 17:05
    Dr_Acula,

    I've been playing around with a Spin to bytecode compiler for a few days. My approach is to generate an intermediate SPASM (SPin bytecode assembly) program, and then run a Spin assembler on it to produce the bytecodes. A similar approach could be taken to convert Spin to any language. That is, the front end would parse Spin code and generate an intermediate output. The final step would be done by converters that would translate the intermediate code into C, Basic, PASM or Spin bytecode. A special converter would be needed for each target language.

    I'm writing my compiler in C because I am more proficient in it than other languages. I hope to post some code in a few days, but I may wait until it's a bit further along.

    Dave
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-02-20 17:19
    That sounds very interesting. The *hard* bits are things like parsing priority of lines with multiple mathematical functions - are you doing that in your code?

    Can you give an example of what your intermediate code looks like? I can imagine that intermediate code might be a lot easier to parse than raw Spin.

    The language you write this in may not matter. In the BCX converter, I do multiple passes (9 at present) and each pass takes an input file off the disk and produces an output file. So you can mix and match any language you like for doing the passes. So an IDE ends up running multiple console line programs - eg it does a 9 pass conversion, then runs BCX, then runs Homespun, then runs Catalina, then runs Payload.

    Your approach makes a lot of sense. Do you have a bytecode listing by any chance?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-02-20 19:55
    I can parse simple expressions, but I have added operator precedence yet. I'm using a technique where I parse a line into tokens, and each token has a function pointer associated with it. I call the function associated with a token and it generates the code for that token. I hope to have operator precedence working in a day or so.

    The intermediate code is Spin assembly, which is not the best choice for a generic intermediate language. PropBasic would actually make a better intermediate language converting to other languages. Once I get the Spin compiler working it should be fairly easy to change the generated output to something else.

    The Spin Hello World program is attached below along with the compiler/assembler listing.

    Dave
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-24 12:05
    How do you do a PEEK/POKE in SPIN? This is actually related to the TV video driver, though I could not find a better thread to ask on.
    I need to be able to read and write to arbitrary locations in hub mem.

    As some know I use Prop Asm a lot more than SPIN, so in SPIN I have some difficulties.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-03-24 12:09
    Sorry: I just found the usage of BYTEMOVE, WORDMOVE, LONGMOVE, BYTEFILL, WORDFILL, LONGFILL in the Propeller manual. The keywords are not intuitive to me sometimes.
  • AribaAriba Posts: 2,690
    edited 2011-03-24 12:23
    There is also a equivalent to peek/poke in Spin:
    val = peek(addr):
     val := byte[hubaddr] ( or word[hubaddr] or long[hubaddr] )
     poke addr,val:
     byte[hubaddr] := val
    
    Andy
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-03-24 13:53
    I had forgotten about this thread until David Saunders peeked and poked it :) I did spend a couple of more weeks on the Spin to Spasm compiler. I added a recursive technique to handle operator precedence. It actually works quite well, and it can take a very complicated expression and convert it to the stack model that the Spin interpreter uses. I stopped working on it three weeks ago when I started looking at the CASE statement. The standard Spin compilers generate some unusual code to handle this.

    Another thing I looked at was Gimple. This is the intermediate language generated by the GNU gcc compiler. In theory, we could convert any standard C program into Spin, Basic, PASM, etc. by writing a converter from Gimple to that language.

    Dave
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-03-25 05:42
    I like the idea of some sort of intermediate language that uses a stack model. Take
    a = (b * (c+d))

    and expand it out to a series of stack instructions.

    Like you say, they ought to be rather similar for lots of different languages.

    I would have thought intuitively that "Case" ought to be fairly easy in comparison. Just a series of "if" statements?

    Is the spin compiler obfuscating this?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-03-25 06:14
    An if statement will use a jump-on-zero to skip over the body of the if statement if the condition is false. A case operator is essentially a jump-on-nonzero, where it jumps to the code to be executed. In a case statement all of the tests are arranged together in memory so they execute one after another without jumping. I think this is done to make it more efficient and to handle situations where there is more than one value to test. This requires 2 passes through the body of a case block, and I wasn't prepared to tackle it at that time.

    Gimple is a nice language for the intermediate stage. It does use temporary values instead of stack to hold results as they are computed. Normally Gimple is converted to a register transfer language (RTL) at the next step. I think it would be fairly easy to convert Gimple to PropBasic. It's not that hard to convert to a stack-based model either. Of course, the tricky part is to produce optimized code.
Sign In or Register to comment.