Permalink
Browse files

ch4

  • Loading branch information...
nslobodin committed Sep 30, 2012
1 parent 47d8d04 commit a1e7d72cfddbb6794a9ce3a376255925fabb152c
View
@@ -1,4 +1,5 @@
SICP
-----
+====
-SICP challenge.
+This is my solutions of SICP book exercises.
+ch4 also contains simplest Scheme interpreter written in Python.
@@ -1,4 +1,6 @@
+from functools import *
class EnvironmentException(Exception): pass
+class UnboundVariableException(EnvironmentException): pass
class Environment:
@@ -8,7 +10,7 @@ def __init__(self, initialFrame, baseEnv = None):
def define(self, variable, value):
self.frame[variable.raw[0]] = value
- print("Environment after define var:val", self.frame)
+ #print("Environment after define var:val", self.frame)
def set(self, variable, value):
if variable.raw[0] in self.frame.keys():
@@ -18,21 +20,25 @@ def set(self, variable, value):
self.baseEnv.set(variable, value)
else:
raise EnvironmentException
- print("Environment after setting var:val", self.frame)
+ #print("Environment after setting var:val", self.frame)
def lookup(self, variable):
if variable.raw[0] in self.frame.keys():
return self.frame[variable.raw[0]]
else:
if self.baseEnv:
- self.baseEnv.lookup(variable)
+ return self.baseEnv.lookup(variable)
else:
- raise EnvironmentException
+ raise UnboundVariableException
-globalEnvironment = Environment({ "+" : lambda x, y: x + y,
- "-" : lambda x, y: x - y,
- "*" : lambda x, y: x * y,
- "/" : lambda x, y: x / y })
+globalEnvironment = Environment({ "+" : lambda *args: reduce(lambda x, y: x + y, args),
+ "-" : lambda *args: reduce(lambda x, y: x - y, args),
+ "*" : lambda *args: reduce(lambda x, y: x * y, args),
+ "/" : lambda *args: reduce(lambda x, y: x / y, args),
+ ">" : lambda x, y: x > y,
+ "<" : lambda x, y: x < y,
+ ">=" : lambda x, y: x >= y,
+ "<=" : lambda x, y: x <= y })
from Expression import *
@@ -1,34 +1,72 @@
-from Expression import *
-from Environment import *
+import types
-def analyzeExpr(expr):
+# check for self evaluating or single variable
+def checkSelfEvaluating(expr, env):
if len(expr.raw) == 1 and "(" not in expr.raw and ")" not in expr.raw:
- if expr.raw[0].isdigit():
- return NumberExpression(expr.raw)
- else:
- return VariableExpression(expr.raw)
-
- factory = ExpressionsFactory()
- return factory.create(expr)
-
+ try:
+ floatNum = float(expr.raw[0])
+ return NumberExpression([floatNum]).eval(env)
+ except ValueError:
+ return VariableExpression([expr.raw[0]]).eval(env)
+ else:
+ return None
def schemeEval(expr, env):
- exp = analyzeExpr(expr)
- return exp.eval(env)
+ selfEv = checkSelfEvaluating(expr, env)
+ if selfEv:
+ return selfEv
+ else:
+ return expr.eval(env)
def schemeApply(proc, args):
- pass
+ if isinstance(proc, Expression): # compound procedure
+ procParams = proc.cdr().car()
+ if len(procParams.raw) != len(args):
+ return "Invalid number of arguments supplied"
+
+ procBaseEnv = proc.cdr().cdr().cdr().car()
+ frame = {}
+ for i in range(len(procParams.raw)):
+ frame[procParams.raw[i]] = args[i]
+
+ procEnv = Environment(frame, procBaseEnv.raw)
+ procBody = proc.cdr().cdr().car()
+ return schemeEval(Expression.fromPythonList(procBody.raw), procEnv)
+ elif isinstance(proc, types.FunctionType): # built-in proc
+ return proc(*args)
+ else:
+ print("PROC", proc)
+ raise Exception
def Eval(exprString, env):
- ret = schemeEval(Expression.makeExpression(exprString), env)
- if isinstance(ret, Expression):
- ret.apply()
+ expression = Expression.fromSchemeList(exprString)
+ return schemeEval(expression, env)
# debug
if __name__ == "__main__":
- Eval("(define (square x) (* x x))", globalEnvironment)
- #Eval("(define x 2)", globalEnvironment)
- #Eval("(set x 15)", globalEnvironment)
+ out = Eval("(define x 3.55)", globalEnvironment)
+ print(out)
+ out = Eval("(set x 15)", globalEnvironment)
+ print(out)
+ out = Eval("x", globalEnvironment)
+ print(out)
+ out = Eval("(define (square x) (* x x))", globalEnvironment)
+ print(out)
+ out = Eval("(define (fact n) (if (<= n 1) 1 (* n (fact (- n 1)))))", globalEnvironment)
+ print(out)
+ out = Eval("(* 3 4)", globalEnvironment)
+ print(out)
+ out = Eval("(square x)", globalEnvironment)
+ print(out)
+ out = Eval("(+ 2 2 3 (* 6 7 2))", globalEnvironment)
+ print(out)
+ out = Eval("(>= 2 3)", globalEnvironment)
+ print(out)
+ out = Eval("(fact 6)", globalEnvironment)
+ print(out)
+
+from Expression import *
+from Environment import *
Oops, something went wrong.

0 comments on commit a1e7d72

Please sign in to comment.