Skip to content

Commit

Permalink
feat: built-in and custom call expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
Leslie-Jiang-Hamster committed Jan 22, 2024
1 parent df68f7d commit 5f33bef
Show file tree
Hide file tree
Showing 8 changed files with 216 additions and 57 deletions.
163 changes: 163 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Ok tests
.ok*
7 changes: 5 additions & 2 deletions scheme_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ def __repr__(self):
def define(self, symbol, value):
"""Define Scheme SYMBOL to have VALUE."""
# BEGIN PROBLEM 1
"*** YOUR CODE HERE ***"
self.bindings[symbol] = value
# END PROBLEM 1

def lookup(self, symbol):
"""Return the value bound to SYMBOL. Errors if SYMBOL is not found."""
# BEGIN PROBLEM 1
"*** YOUR CODE HERE ***"
if symbol in self.bindings:
return self.bindings[symbol]
if self.parent != None and not symbol in self.bindings:
return self.parent.lookup(symbol)
# END PROBLEM 1
raise SchemeError('unknown identifier: {0}'.format(symbol))

Expand Down
12 changes: 9 additions & 3 deletions scheme_eval_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from scheme_utils import *
from ucb import main, trace

from util import *

import scheme_forms

##############
Expand Down Expand Up @@ -33,7 +35,9 @@ def scheme_eval(expr, env, _=None): # Optional third argument is ignored
return scheme_forms.SPECIAL_FORMS[first](rest, env)
else:
# BEGIN PROBLEM 3
"*** YOUR CODE HERE ***"
operator = scheme_eval(first, env)
operands = rest.map(lambda x: scheme_eval(x, env))
return scheme_apply(operator, operands, env)
# END PROBLEM 3

def scheme_apply(procedure, args, env):
Expand All @@ -44,11 +48,13 @@ def scheme_apply(procedure, args, env):
assert False, "Not a Frame: {}".format(env)
if isinstance(procedure, BuiltinProcedure):
# BEGIN PROBLEM 2
"*** YOUR CODE HERE ***"
args_py_list = pair_to_list(args)
if procedure.need_env:
args_py_list.append(env)
# END PROBLEM 2
try:
# BEGIN PROBLEM 2
"*** YOUR CODE HERE ***"
return procedure.py_func(*args_py_list)
# END PROBLEM 2
except TypeError as err:
raise SchemeError('incorrect number of arguments: {0}'.format(procedure))
Expand Down
28 changes: 9 additions & 19 deletions tests/01.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,17 @@
>>> global_frame = create_global_frame()
>>> global_frame.define("x", 3)
>>> global_frame.parent is None
b1796eff8a8e977439f97b5c6881a282
# locked
True
>>> global_frame.lookup("x")
3c7e8a3a2176a696c3a66418f78dff6b
# locked
3
>>> global_frame.define("x", 2)
>>> global_frame.lookup("x")
2b7cdec3904f986982cbd24a0bc12887
# locked
2
>>> global_frame.lookup("foo")
ec908af60f03727428c7ee3f22ec3cd8
# locked
# choice: None
# choice: SchemeError
# choice: 3
SchemeError
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
},
{
Expand All @@ -35,18 +28,15 @@
>>> first_frame.define("x", 3)
>>> second_frame = Frame(first_frame)
>>> second_frame.parent == first_frame
b1796eff8a8e977439f97b5c6881a282
# locked
True
>>> second_frame.define("y", False)
>>> second_frame.lookup("x")
3c7e8a3a2176a696c3a66418f78dff6b
# locked
3
>>> second_frame.lookup("y")
96ae38315990d5fb27de4225d8b470ba
# locked
False
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
},
{
Expand Down
15 changes: 6 additions & 9 deletions tests/02.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,21 @@
>>> twos = Pair(2, Pair(2, nil))
>>> plus = BuiltinProcedure(scheme_add) # + procedure
>>> scheme_apply(plus, twos, env) # Type SchemeError if you think this errors
46beb7deeeb5e9af1c8d785b12558317
# locked
4
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
},
{
'code': r"""
>>> env = create_global_frame()
>>> plus = BuiltinProcedure(scheme_add) # + procedure
>>> scheme_apply(plus, nil, env) # Remember what (+) evaluates to in scheme
a384c59daad07475a000a57b0b47b74f
# locked
0
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
},
{
Expand All @@ -35,11 +33,10 @@
>>> twos = Pair(2, Pair(2, nil))
>>> oddp = BuiltinProcedure(scheme_oddp) # odd? procedure
>>> scheme_apply(oddp, twos, env) # Type SchemeError if you think this errors
ec908af60f03727428c7ee3f22ec3cd8
# locked
SchemeError
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
},
{
Expand Down
22 changes: 8 additions & 14 deletions tests/03.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,18 @@
'code': r"""
>>> expr = read_line('(+ 2 2)')
>>> scheme_eval(expr, create_global_frame()) # Type SchemeError if you think this errors
46beb7deeeb5e9af1c8d785b12558317
# locked
4
>>> scheme_eval(Pair('+', Pair(2, Pair(2, nil))), create_global_frame()) # Type SchemeError if you think this errors
46beb7deeeb5e9af1c8d785b12558317
# locked
4
>>> expr = read_line('(+ (+ 2 2) (+ 1 3) (* 1 4))')
>>> scheme_eval(expr, create_global_frame()) # Type SchemeError if you think this errors
4c5d1a42692bacbca88ab48bbcf75c52
# locked
12
>>> expr = read_line('(yolo)')
>>> scheme_eval(expr, create_global_frame()) # Type SchemeError if you think this errors
ec908af60f03727428c7ee3f22ec3cd8
# locked
SchemeError
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
}
],
Expand All @@ -40,14 +36,12 @@
{
'code': r"""
scm> (* (+ 3 2) (+ 1 7)) ; Type SchemeError if you think this errors
a692eb3d6b9f6889d113635424465221
# locked
40
scm> (1 2) ; Type SchemeError if you think this errors
ec908af60f03727428c7ee3f22ec3cd8
# locked
SchemeError
""",
'hidden': False,
'locked': True,
'locked': False,
'multiline': False
},
{
Expand Down
Loading

0 comments on commit 5f33bef

Please sign in to comment.