# zero, one or several function definitions at the beginning of the file def fibaux(a, b, k): if k == 0: return a else: return fibaux(b, a+b, k-1) def fib(n): return fibaux(0, 1, n) # then one or several statements at the end of the file print("a few values of the Fibonacci sequence:") for n in [0, 1, 11, 42]: print(fib(n))More generally, a mini-Python file is composed of an optional list of function definitions, followed by a list of statements. Caveat: the last statement must be followed by a newline.
Statements are: assignment, conditional, loop (for), output with print, returning a value with return, and evaluation an expression. Expressions are: a constant (Boolean, integer, or string), access to a variable, building a list (with syntax [e1, e2, ..., en]), access to a list element (with syntax notation e[i]), function call, or one of the operations +, -, *, //, ==, <>, <, <=, >, >=, and, or and not.
We also consider three built-in functions: list(range(n)) builds the list [0, 1, 2, ..., n-1] and len(l) returns the length of list l. (We only use list and range jointly in this way.)
Download this archive: mini-python-java.tar.gz
Once uncompressed (with tar zxvf mini-python.tar.gz), you get a directory mini-python-java/. (If you use Eclipse, you can run it in the directory where mini-python-java/ is, with the command eclipse -data ., then create a project mini-python-java and disable option Use default location.) This project contains a package mini_python with the following files:
Syntax.java | abstract syntax of mini-Python (complete) |
Lexer.java, MyLexer.java | lexical analysis (complete) |
parser.java, sym.java | parsing (complete) |
Interp.java | interpreter (to be completed) |
Main.java | main file (complete) |
Makefile | to automate the build, if you don't use an IDE (complete) |
The executable takes a mini-Python file on the command line, with suffix .py. When it is absent, file test.py is used.
print(1 + 2*3) print((3*3 + 4*4) // 5) print(10-3-4)whose output must be
7 5 3Division and modulus operations must signal a division by zero, by raising exception Error.
To test, simply edit file test.py and run Main.
Then complete the interpreter with Boolean constants, arithmetic comparison and operations and, or and not. In Python, comparison is structural. You can use the method compareTo that is provided in class Value.
Finally, complete the interpreter to handle the conditional (construction Sif).
Test on the following file
print(not True and 1//0==0) print(1<2) if False or True: print("ok") else: print("oups")whose output must be
False True ok
Complete the interpreter so that we can access variables (case Eident). Accessing a variable that is not in the map must raise an error.
Similarly, complete the interpreter so that we can assign a value to a variable (method visit(Sassign s)). This time, the variable may or may not be in the table. In the former case, its value is modified. In the latter case, it is added.
Finally, complete the interpreter so that we can concatenate two strings with operation +.
Test on the following file
x = 41 x = x+1 print(x) b = True and False print(b) s = "hello" + " world!" print(s)whose output must be
42 False hello world!
Then complete the interpreter to handle function calls. For a call f(e1,...,en) to a function f defined as def f(x1,...,xn): s, we have to build a new environment that maps each formal parameter xi to the value of ei. This means building a new object of type Interp. Then we interpret the statement s (the body of the function) in this new environment. The statement return is interpreted using the Java exception Return (already defined). If the execution terminates without an explicit return, the value None must be returned.
Test on the following file
def fact(n): if n <= 1: return 1 return n * fact(n-1) print(fact(10))whose output must be
3628800
Complete function stmt to interpret the assignment of a list element (class Sset).
Finally, complete function stmt to interpret the for loop. The statement for x in e: s successively assigns to the variable x the values of the list e, and executes the statement s for each of them. The expression e must be evaluated only once.
Test using the program at the beginning of this page. The output must be:
0 1 89 267914296