11.3.4 Procedures

To finish the interpreter, we define the evalLoop procedure that sets up the global environment and provides an interactive interface to the interpreter. The evaluation loop reads a string from the user using the Python built-in procedure raw_input. It uses parse to convert that string into a structured list representation. Then, it uses a for loop to iterate through the expressions. It evaluates each expression using meval and the result is printed.

To initialize the global environment, we create an environment with no parent and place variables in it corresponding to the primitives in Charme.

def evalLoop():
    genv = Environment(None)
    genv.add_variable('true', True)
    genv.add_variable('false', False)
    genv.add_variable('+', primitive_plus)
    genv.add_variable('-', primitive_minus)
    genv.add_variable('*', primitive_times)
    genv.add_variable('=', primitive_equals)
    genv.add_variable('<', primitive_lessthan)
    while True:
        inv = raw_input('Charme> ')
        if inv == 'quit': break
        for expr in parse(inv):
            print str(meval(expr, genv))

Here are some sample interactions with our Charme interpreter:

>> evalLoop()
Charme> (+ 2 2)
4
Charme> (define fibo
                        (lambda (n)
                            (if (= n 1) 1
                                (if (= n 2) 1
                                    (+ (fibo (- n 1)) (fibo (- n 2)))))))
None
Charme> (fibo 10)
55