I want to write an interpreter for a scripting language in javascript. Something that could run this script:
set myVariable to "Hello World"
repeat 5 times with x
begin
set myVariable to myVariable plus " " plus x
end
popup "myVariable is: " plus myVariable
The equivalent javascript of the above would be:
var myVariable = "Hello World";
for (var x=1; x<=5; x++) {
myVariable += " " + x;
}
alert("myVariable is: " + myVariable);
I don't want to translate from one to the other, I want to write a javascript program to interprete and execute the script directly. How can this be done?
Update:
I'm looking for a tutorial (preferably in javascript but C would do) that will walk me through this. I guess I'm looking for one that does not use any external tools as the tools seem to be my issue. I don't want to use something that calls libraries and a bunch of pre-built code. I want to see the whole thing, done from scratch.
OK, I'll actually try to tackle this question somewhat... although there is no way I could possibly distill everything you need to know into a few sentences or even paragraphs.
First, you should gain an understanding / familiarity with what's involved in building a compiler. You say you want to "interpret" the code - but, I think what you really want is to compile the code to Javascript (and in Javascript as well).
Wikipedia has a great page on the topic: http://en.wikipedia.org/wiki/Compiler
The gist of the thing is:
1.) Convert the text (source code) into some sort of in-memory data structure (abstract syntax tree - AST) that actually lets you reason about the structure of the program you've been given.
2.) Given that structure, produce your output (Javascript, in this case).
To break down step 1 a bit further - Define your grammar e.g.; what is valid syntax in this new language of yours, and what is not? Typically, it's best to reason about this sort of thing with BNF on paper (or whatever syntax the tools you use prefer - although (E)BNF is the standard). The challenging part about this step is not only doing the grunt work of parsing the source code - but also making sure you've come up with a grammar that is unambiguous and readily parsable. Those two requirements are actually somewhat more difficult to nail down than you might think.
I've built an LALR parser generator in C# - and, I can tell you, unless you've built one before, it's not a trivial task. Beyond that, there are so many good ones, that, unless you are really wanting to know how it works for the fun of it or because you're into that kind of thing, it makes a whole lot more sense to use a parser-generator someone else wrote. The great thing about a parser generator is that it will take that syntax definition you've come up with convert it into a program that will spit out an AST the other end. That's a HUGE amount of work that was just done for you. And, in fact, there are a few for Javascript:
http://www.google.com/search?q=javascript+parser+generator
PEG.js – Parser Generator for JavaScript
JS/CC Parser Generator Project Homepage
On to step 2. This step can be very basic for something like infix expressions - or it can get very complex. But, the idea is, given the AST, "convert" it into your output format (Javascript). Typically you need to check for things that aren't checked for by the "simple" syntax checking that occurs in the parser. For example, even in your sample code there is a whole number of things that could possibly go wrong. In the part where you say plus x
what would happen if the developer never defined x
? Should this be an error? Should x
default to some value? This is where your language really comes to life. And, to back-track for a minute - your time needs to be spent on this step - not on the parser. Use a tool for that - seriously. You're talking about starting a large and challenging project - don't make it even harder for yourself. To add to all this - there is often a need to make multiple "passes" through the AST. For example, the first pass may look for and setup "module" definitions, the second pass may look for and setup "namespaces", another pass may setup classes, etc. These further refinements of the structure of the final application are used in later steps to determine if a reference to a particular class/variable/module/etc is valid (it actually exists or can be referenced).
There are a few really great books on compilers. The infamous "dragon book" is one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With