Here i like to explain about
small "interpreter of lisp using python" . first lets go to language interpreter . its a process to convert a language into execution state
using syntax and semantics rules simply say compiler .
a compiler have many parts but we focus on
parsing and
execution
Parsing means convert a program into sequence of characters based on syntax rules and
execution means
internal representation then processed based on semantic rules .
Representation of an interpreter
This is done in python and JavaScript to see the code :
click here
Before explaining this we have to look at the working of the program for this
1: >> program = "(begin (define r 3) (* 3.141592653 (* r r)))"
2: >>> parse(program)
3: ['begin', ['define', 'r', 3], ['*', 3.141592653, ['*', 'r', 'r']]]
4: >>> eval(parse(program))
5: 28.274333877
just look parse section convert the lisp program into list of number and strings in python and evaluation gives the final output
execution :
Mainly have two parts evaluation and Environment .
Evaluation means there are nine cases in lisp that is evaluated using function eval taking two argument that expression x,environment env.
1: def eval(x, env=global_env):
2: "Evaluate an expression in an environment."
3: if isa(x, Symbol): # variable reference
4: return env.find(x)[x]
5: elif not isa(x, list): # constant literal
6: return x
7: elif x[0] == 'quote': # (quote exp)
8: (_, exp) = x
9: return exp
10: elif x[0] == 'if': # (if test conseq alt)
11: (_, test, conseq, alt) = x
12: return eval((conseq if eval(test, env) else alt), env)
13: elif x[0] == 'set!': # (set! var exp)
14: (_, var, exp) = x
15: env.find(var)[var] = eval(exp, env)
16: elif x[0] == 'define': # (define var exp)
17: (_, var, exp) = x
18: env[var] = eval(exp, env)
19: elif x[0] == 'lambda': # (lambda (var*) exp)
20: (_, vars, exp) = x
21: return lambda *args: eval(exp, Env(vars, args, env))
22: elif x[0] == 'begin': # (begin exp*)
23: for exp in x[1:]:
24: val = eval(exp, env)
25: return val
26: else: # (proc exp*)
27: exps = [eval(exp, env) for exp in x]
28: proc = exps.pop(0)
29: return proc(*exps)
30: isa = isinstance
31: Symbol = str
Environment
Environments are mappings of variable names (symbols) to the values
(data objects) held by them
for a function definition there two section first definition second procedure call
when define a function we have the output
1: >> program = "(define area (lambda (r) (* 3.141592653 (* r r)))"
2: >>> parse(program)
3: ['define', 'area', ['lambda', ['r'], ['*', 3.141592653, ['*', 'r', 'r']]]]
4: >>> eval(parse(program))
5: None
In this evaluation
we take the branch
if x[0] == 'define', under which Python
sets
var to
'area' and
exp to
['lambda', ['r'], ['*', 3.141592653, ['*', 'r', 'r']]].
Python then modifies the
env (which at this point is the global environment),
adding a new variable,
'area', and setting it to the result of evaluating
exp. To evaluate
exp, we follow the
elif x[0] == 'lambda' in
eval, branch, assigning the three
variables
(_, vars, exp) to the corresponding elements of the
list
x (and signalling an error if
x is not of
length 3). We then create a new procedure that, when called, will evaluate
the expression
['*', 3.141592653 ['*', 'r', 'r']], in the environment
formed by binding the formal parameters of the procedure (in this case there
is just one parameter,
r) to the arguments supplied in the procedure call,
and in addition using the current environment for any variables not in the parameter list (for example, the variable
*). The value of this
newly-minted procedure is then assigned as the value of
area
in
global_env.
Now what happens when we evaluate
(area 3)? Since
area is not one of the special form symbols, this must be a
procedure call (the last
else: of
eval), and the
whole list of expressions is evaluated, one at a time. Evaluating
area yields the procedure we just created; evaluating
3 yields
3. We then (according to the last line of
eval) call the newly-created procedure with the argument list
[3]. this means evaluating
exp, which is
['*', 3.141592653 ['*', 'r', 'r']], in the environment where
r is
3
and the outer environment is the global environment, and therefore
* is the multiplication procedure.
We have an Env class which gives appropriate value for variables
This process of looking first in inner environments and then in
outer ones is called
.
finds the right environment according to
lexical scoping rules.