:: Enseignements :: Master :: M2 :: 2018-2019 :: Machine Virtuelle (et bazar autour ...) ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Lab 1 - AST walker |
The aim of this first lab is to write an AST interpreter for the language
minijs
which is a small subset of the language
JavaScript.
The AST (abstract syntax tree) is a tree representing a script that can be used
to interpret the script by walking the tree and executing for each kind of expression
a specific code.
To associate a code to execute to a specific kind of expression, we use a visitor
that associate to an expression class a lambda representing the code to execute.
(see
Visitor Pattern for more info)
In order to help you to write the AST interpreter, here is a ZIP archive containing
a get-started code (a lexer, a parser and classes defining the AST)
vm2016-lab1.zip
The archive contains
-
a folder grammar that contains the file (minijs.ebnf) describing the grammar of minijs
and an ANT script (build.xml) that generates a lexer and a parser for this grammar in the folder grammar/gen-src
-
a folder src that contains the Java classes that define the abstract syntax tree and two classes Failure
and JSObject that represent respectively an error in the script and a JavaScript object.
-
a folder samples that contains examples of JavaScript scripts supported by minijs.
-
a folder lab1/src that contains a main class ASTInterpreterMain and two classes ReturnError
that will be detailed below and ASTInterpreter which is the class that must be modified to implement
the interpreter.
The command
ant compile and create a JAR executable
minijs.jar
that can be used to test different sample script (see the folder samples).
Moreover, Java 8 also provide a full-featured JavaScript engine, named Nashorn,
that can be used to compare if the result of your interpreter is correct.
To execute by example hello.js with your interpreter use
java -jar minijs.jar samples/hello.js
and with the Nashorn Javascript engine
jjs samples/hello.js
Exercice 1 - AST interpreter
The aim of this exercise is to just complete the file ASTInterpreter.java and you
should not have to write or modify any other files.
-
Test the executable jar with the script hello.js (in the folder samples)
What is the result ?
What lambdas should be implemented in order to make the script hello.js working ?
To ease our implementation, we suppose that all functions (at least until question 6)
are the print function.
And print can be implemented using System.out.println().
Implement those lambdas !
-
Now, we want to implement this snippet
var message = "hello";
print(message);
What lambdas should be implemented ?
We will use the class JSObject to store the mapping between
a variable name (here message) and its value (here "hello").
Modify the interpreter to support the snippet above.
-
We want to implement the binary operations (numeric.js)
print(1 + 2);
print(1 + 2 * 2);
If we look how the functions +, *, print, ... are implemented,
we can notice that a function have a code (qualified) registered and no receiver.
Implement the corresponding modifications.
-
Verify that the following script works
var a = 3;
var b = 4;
print(a + b);
-
What is the result of the following script if it is run using jjs ?
var me = "Bob";
print("hello", me);
Change your code if minijs doesn't output the same result.
-
What is the expected result of the following script using jjs ?
function fun() { }
print(fun());
And of this code
function fun() { }
print(fun);
Implement the corresponding lambdas !
Note 1: An instance of an environment will be created using JSObject.newEnv.
Note 2: minijs should output the function as an object for the script above
and not the code of the function as jjs does.
-
Verify that the following code works:
function foo() {
print('foo');
bar();
}
function bar() {
print('bar');
}
foo();
-
Implement the instruction return like in
function fun() { return "hello"; }
print(fun());
When 'return' is interpreted you have to stop the interpreter
and go back into the lambda that has called the function, there is a trick to implement
that, you can throw an exception (see ReturnError) when doing the 'return'
and catch it in the lambda that calls the function.
-
Add the support of the instruction 'if' (only the balanced case !)
var a = 3;
//var a = 3;
if (a == 3) {
print("true");
} else {
print("false");
}
Obviously, it means that the interpretation of the function '==' works !
-
JavaScript is known to have weird scope rules, what is the result of
this code if 'a' equals 2 or 3 (see sample if.js).
You can use jjs to test !
var a = 2;
//var a = 3;
if (a == 3) {
print("true");
var b = "hello";
} else {
print("false");
}
print(b);
Modify your code to implement the same rules
-
Now, add the support for the object creation
var o = {
x: 1,
y: 1 + 1
};
You will use the class JSObject too but with the static factory JSObject.newObject.
-
Also implement field access and verify that the code below works
var o = {
x: 1,
y: 1 + 1
};
print(o.x);
print(o.y);
-
And to finish, implement field modification like in the sample object.js.
© Université de Marne-la-Vallée