Skip to content

Commit

Permalink
finished scheme Part II
Browse files Browse the repository at this point in the history
  • Loading branch information
tommyfan34 committed Mar 14, 2021
1 parent abddbf0 commit 400dfca
Show file tree
Hide file tree
Showing 37 changed files with 133 additions and 176 deletions.
Binary file modified scheme/.ok_history
Binary file not shown.
Binary file modified scheme/.ok_storage
Binary file not shown.
Binary file modified scheme/__pycache__/scheme.cpython-38.pyc
Binary file not shown.
Binary file modified scheme/__pycache__/scheme_reader.cpython-38.pyc
Binary file not shown.
54 changes: 52 additions & 2 deletions scheme/scheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ def eval_all(expressions, env):
2
"""
# BEGIN PROBLEM 7
return scheme_eval(expressions.first, env) # replace this with lines of your own code
if expressions is nil:
return None
ret = scheme_eval(expressions.first, env)
if expressions.rest is not nil:
ret = eval_all(expressions.rest, env)
return ret
# END PROBLEM 7

################
Expand Down Expand Up @@ -127,6 +132,14 @@ def make_child_frame(self, formals, vals):
raise SchemeError('Incorrect number of arguments to function call')
# BEGIN PROBLEM 10
"*** YOUR CODE HERE ***"
new_frame = Frame(self)
cur_formal = formals
cur_val = vals
while cur_formal is not nil:
new_frame.bindings[cur_formal.first] = cur_val.first
cur_formal = cur_formal.rest
cur_val = cur_val.rest
return new_frame
# END PROBLEM 10

##############
Expand Down Expand Up @@ -191,11 +204,12 @@ def __init__(self, formals, body, env):
self.body = body
self.env = env

def make_call_frame(self, args, env):
def make_call_frame(self, args, env):
"""Make a frame that binds my formal parameters to ARGS, a Scheme list
of values, for a lexically-scoped call evaluated in environment ENV."""
# BEGIN PROBLEM 11
"*** YOUR CODE HERE ***"
return self.env.make_child_frame(self.formals, args)
# END PROBLEM 11

def __str__(self):
Expand Down Expand Up @@ -263,6 +277,10 @@ def do_define_form(expressions, env):
elif isinstance(target, Pair) and scheme_symbolp(target.first):
# BEGIN PROBLEM 9
"*** YOUR CODE HERE ***"
proc_name = target.first
func = do_lambda_form(Pair(target.rest, expressions.rest), env)
env.bindings[proc_name] = func
return proc_name
# END PROBLEM 9
else:
bad_target = target.first if isinstance(target, Pair) else target
Expand All @@ -278,6 +296,7 @@ def do_quote_form(expressions, env):
validate_form(expressions, 1, 1)
# BEGIN PROBLEM 6
"*** YOUR CODE HERE ***"
return expressions.first
# END PROBLEM 6

def do_begin_form(expressions, env):
Expand All @@ -304,6 +323,7 @@ def do_lambda_form(expressions, env):
validate_formals(formals)
# BEGIN PROBLEM 8
"*** YOUR CODE HERE ***"
return LambdaProcedure(expressions.first, expressions.rest, env)
# END PROBLEM 8

def do_if_form(expressions, env):
Expand Down Expand Up @@ -336,6 +356,15 @@ def do_and_form(expressions, env):
"""
# BEGIN PROBLEM 12
"*** YOUR CODE HERE ***"
if expressions is nil:
return True
val = scheme_eval(expressions.first, env)
if is_true_primitive(val):
if expressions.rest is nil:
return val
return do_and_form(expressions.rest, env)
else:
return False
# END PROBLEM 12

def do_or_form(expressions, env):
Expand All @@ -353,6 +382,13 @@ def do_or_form(expressions, env):
"""
# BEGIN PROBLEM 12
"*** YOUR CODE HERE ***"
if expressions is nil:
return False
val = scheme_eval(expressions.first, env)
if is_false_primitive(val):
return do_or_form(expressions.rest, env)
else:
return val
# END PROBLEM 12

def do_cond_form(expressions, env):
Expand All @@ -373,6 +409,10 @@ def do_cond_form(expressions, env):
if is_true_primitive(test):
# BEGIN PROBLEM 13
"*** YOUR CODE HERE ***"
if clause.rest is nil:
return test
else:
return eval_all(clause.rest, env)
# END PROBLEM 13
expressions = expressions.rest

Expand All @@ -397,6 +437,16 @@ def make_let_frame(bindings, env):
names, values = nil, nil
# BEGIN PROBLEM 14
"*** YOUR CODE HERE ***"
cur = bindings
while cur is not nil:
b = cur.first
validate_form(b, 2, 2)
name = b.first
arg = scheme_eval(b.rest.first, env)
names = Pair(name, names)
values = Pair(arg, values)
cur = cur.rest
validate_formals(names)
# END PROBLEM 14
return env.make_child_frame(names, values)

Expand Down
1 change: 1 addition & 0 deletions scheme/scheme_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ def scheme_read(src):
elif val == "'":
# BEGIN PROBLEM 6
"*** YOUR CODE HERE ***"
return Pair('quote', Pair(scheme_read(src), nil))
# END PROBLEM 6
elif val not in DELIMITERS:
return val
Expand Down
52 changes: 15 additions & 37 deletions scheme/tests/06.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{
'cases': [
{
'answer': 'fd4dd892ccea3adcf9446dc4a9738d47',
'answer': 'Pair(A, nil), where: A is the quoted expression',
'choices': [
r"""
Pair('quote', Pair(A, nil)), where:
Expand All @@ -25,7 +25,7 @@
"""
],
'hidden': False,
'locked': True,
'locked': False,
'question': 'What is the structure of the expressions argument to do_quote_form?'
}
],
Expand All @@ -37,18 +37,15 @@
{
'code': r"""
>>> do_quote_form(Pair(3, nil), global_frame)
3c7e8a3a2176a696c3a66418f78dff6b
# locked
3
>>> do_quote_form(Pair('hi', nil), global_frame)
95448591e64e04a7a7885d5fb9b45583
# locked
'hi'
>>> expr = Pair(Pair('+', Pair('x', Pair(2, nil))), nil)
>>> do_quote_form(expr, global_frame) # Make sure to use Pair notation
2301ee746b57783004f00f39498fdaed
# locked
Pair('+', Pair('x', Pair(2, nil)))
""",
'hidden': False,
'locked': True
'locked': False
}
],
'scored': True,
Expand All @@ -64,27 +61,18 @@
{
'code': r"""
scm> ''hello
f675ad62f5f67e5229145843fd6bbcaa
# locked
# choice: (quote hello)
# choice: hello
# choice: (hello)
# choice: (quote (quote (hello)))
(quote hello)
scm> (quote (1 2))
484e4b42665b2864d685ef07fe666107
# locked
(1 2)
scm> (car '(1 2 3))
eb892a26497f936d1f6cae54aacc5f51
# locked
1
scm> (cdr '(1 2))
750540b47bda75ff036b4a9aa741b087
# locked
(2)
scm> (eval (cons 'car '('(4 2))))
46beb7deeeb5e9af1c8d785b12558317
# locked
4
""",
'hidden': False,
'locked': True
'locked': False
}
],
'scored': True,
Expand All @@ -97,22 +85,12 @@
{
'code': r"""
>>> read_line(" 'x ")
d88f877a51ba10d1c3a834a690bb43e0
# locked
# choice: Pair('x', nil)
# choice: 'x'
# choice: Pair('quote', 'x')
# choice: Pair('quote', Pair('x', nil))
Pair('quote', Pair('x', nil))
>>> read_line(" '(a b) ")
e16dd0e729d41b52ddd5d4d38cbfc7e6
# locked
# choice: Pair('a', Pair('b', nil))
# choice: Pair('quote', Pair(Pair('a', Pair('b', nil)), nil))
# choice: Pair('quote', Pair('a', 'b'))
# choice: Pair('quote', Pair('a', Pair('b', nil)))
Pair('quote', Pair(Pair('a', Pair('b', nil)), nil))
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
Expand Down
51 changes: 15 additions & 36 deletions scheme/tests/07.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,24 @@
{
'code': r"""
>>> eval_all(Pair(2, nil), env)
2b7cdec3904f986982cbd24a0bc12887
# locked
# choice: 2
# choice: SchemeError
2
>>> eval_all(Pair(4, Pair(5, nil)), env)
b33c0f7206201b4aaeae595493888600
# locked
# choice: 4
# choice: 5
# choice: (4 5)
# choice: SchemeError
5
>>> eval_all(nil, env) # return None (meaning undefined)
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
>>> lst = Pair(1, Pair(2, Pair(3, nil)))
>>> eval_all(lst, env)
3c7e8a3a2176a696c3a66418f78dff6b
# locked
3
>>> lst # The list should not be mutated!
4ced98984f008e5161274d6481e4b568
# locked
Pair(1, Pair(2, Pair(3, nil)))
""",
'hidden': False,
'locked': True
'locked': False
}
],
'scored': True,
Expand All @@ -50,39 +40,28 @@
{
'code': r"""
scm> (begin (+ 2 3) (+ 5 6))
20169e9f217f8370ba4f37a3cf0cc2b3
# locked
11
scm> (begin (define x 3) x)
3c7e8a3a2176a696c3a66418f78dff6b
# locked
3
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
scm> (begin 30 '(+ 2 2))
85d97cf58c044cc51a6a7d4315b4ad71
# locked
# choice: (+ 2 2)
# choice: '(+ 2 2)
# choice: 4
# choice: 30
(+ 2 2)
scm> (define x 0)
38ba916dc1f41eb239567ee41a251ecd
# locked
x
scm> (begin (define x (+ x 1)) 42 (define y (+ x 1)))
1a9a3321b8b99a0f9291d89be986e74c
# locked
y
scm> x
eb892a26497f936d1f6cae54aacc5f51
# locked
1
scm> y
2b7cdec3904f986982cbd24a0bc12887
# locked
2
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
Expand Down
16 changes: 6 additions & 10 deletions scheme/tests/08.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
{
'code': r"""
scm> (lambda (x y) (+ x y))
1456de84c3edf333b6f7aee0c0624b20
# locked
(lambda (x y) (+ x y))
scm> (lambda (x)) ; type SchemeError if you think this causes an error
ec908af60f03727428c7ee3f22ec3cd8
# locked
SchemeError
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
Expand Down Expand Up @@ -46,14 +44,12 @@
>>> lambda_line = read_line("(lambda (a b c) (+ a (* b c)))")
>>> lambda_proc = do_lambda_form(lambda_line.rest, env)
>>> lambda_proc.formals
d106bb7be6b014a9d16d74410be4a8a5
# locked
Pair('a', Pair('b', Pair('c', nil)))
>>> lambda_proc.body # Remember that the body is a *list* of expressions!
3fec54ce56372bf73c4e4854aa74fc10
# locked
Pair(Pair('+', Pair('a', Pair(Pair('*', Pair('b', Pair('c', nil))), nil))), nil)
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
Expand Down
12 changes: 3 additions & 9 deletions scheme/tests/09.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@
{
'code': r"""
scm> (define (f x y) (+ x y))
715124391110b4a3beec8c9ba1ec3097
# locked
f
scm> f
1456de84c3edf333b6f7aee0c0624b20
# locked
# choice: (lambda (x y) (+ x y))
# choice: (lambda (f x y) (+ x y))
# choice: (f (x y) (+ x y))
# choice: (define f (lambda (x y) (+ x y)))
(lambda (x y) (+ x y))
""",
'hidden': False,
'locked': True
'locked': False
},
{
'code': r"""
Expand Down
Loading

0 comments on commit 400dfca

Please sign in to comment.