Advertisement

Simple BASIC compiler.

Started by November 17, 2004 02:59 AM
17 comments, last by Nice Coder 19 years, 9 months ago
1. Building nice little vm, with main memory and two stacks. 2. Would like to know how to build a very simple BASIC compiler, to compile into simple little vm. 3. Would like to know any information relevent to above points. From, Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
One resource of use is The Angelcode Reference DB, it has several links on the creation of a VM and/or compiler. There's also a useful section on GameDev with useful articles. It's also worth buying Game Scripting Mastery as this book will teach you everything from ground up in a simple way. It's more geared towards writing a C-like language, but I'm sure that basic would be easier.
Advertisement
Thanks evolutional!

I've tried building a basic compiler (or parts thereov), but things like loops and if statetements awere things i couldn't get.

i;='m looking at an ebook on compiler building [grin].

From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Loops and if statements are done with conditional branching. Your VM will probably have:
- JMP (Jump to instruction)
- JE (Jump if condition = true)
- JNE (Jump if not true)
- JL/JG (Jump if less/greater)
- JLE, JGE (Jump less or equal / greater or equal)

But you probably know that already. So, you need to know where to jump to. You could do this by storing named labels in your VM, via relative offsets (eg: Jump 5 instructions back) or via fixed offsets (Jump to instruction # 10). This is all calculated in the compilation stage.

I think this article does a decent job of explaining it (look about 2/3 down).

0: if a = b then1..:  // Do statement99: end if


If the statement above fails its test (a != b) then the code should jump to source line #99 or if you throw an else in there it should jump there instead and the original. When building your object code it'd be easy to keep a list of references for things like this (the reference refers to an instruction) which is then resolved into a fixed (or relative) offset at bytecode compile time.

if a = b then               // Ref: If_cond_00001 begin // Do statementend if                      // Ref: If_cond_00001 end


... would eventually resolve the labels (If_cond_00001 begin/end) into instruction offsets; the begin may point to instruction #10 and the end may point to instruction #250 - so your bytecode should look something like:

cmp a, bjne 250         // jump to fixed instruction offset 250 if not true........            // Do statement code in here....// Instruction offset 250, contine running


I probably didn't do a good job at explaining that - but hopefully you'll see what I mean.
Ok, i've been doing a bit of thinking, and of reading.

For something like

if x = y then   if z = k then   end ifend if


How would that be handled?

I was also thinking about multi-pass compiling, how exectly can you compile with a single pass, and what is the difference between passes?

Could you keep a sort of flag array, in which on pass 1, you flag statements as "external", or "If statement", or "Else", ect.

Is this used/is it good to use?

Sorry for all the questions, i'm just interested.
From,
Nice coder
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
An if statement becomes a compare and a conditional branch. Generally what you get is a branch if he condition is untrue to the associated end-if. To know where the relevant end-if is, you'll obviously have to have read through the script once, or be willing to do a lot of back-and-forward scanning through it. You will need to have a way of representing code blocks that are contained in other blocks. A tree is a good representation for that sort of thing.

Performing more than one pass makes some things easier. You can go through once and find the location of end-ifs and whatever so that on the next pass you can use that location in your conditional branch. Basically it's just for any sort of compilation requirement that requires you to be able to look forward in the file as well as backwards, really.

I'm not sure what you're getting at with the flag array, as I don't see any benefit in what you're suggesting. The multipass mechanism (in systems I am familiar with) is really just to simplify forward and backwards referencing.
Advertisement
ok, thanks for that.

Also, how wuold i compile things like:
if (1 + 2 = a) and (2^2 = (b ^3)) xor (C(53) != D(15)) then

??

Also, how would i calculate the line for the end-if, if i haven't compiled the code between me and it yet?

From,
Nice Coder

[Edited by - Nice Coder on November 17, 2004 11:05:26 PM]
Click here to patch the mozilla IDN exploit, or click Here then type in Network.enableidn and set its value to false. Restart the browser for the patches to work.
Pick up the C book "C, How to Program". Spread as an exercise in the book is the overview on how to write this exact thing. If you are a competent programmer (and you better be if you want to write a compiler) you should be able to put this info into an implementation, no problem. I did it... Now it's your turn!
---Ninja : Art of Winning
better yet, pick up "Game Scripting Mastery", and read the second half...but I highly recommend you read the first half first.
There is some good compiler tutorials and an example BASIC compiler with full comments written in C++ at http://www.briancbecker.com

I used it to write my own BASIC compiler at http://blackfrog.pagemac.com

- Sean

This topic is closed to new replies.

Advertisement