CS61A Summer 2019
  • CS61A Summer 2019
    • Week 1 - Functions, Env Diagrams
      • Functions
      • Environment Diagrams
      • Lab 1
      • HW 1
    • Week 2 - Recursion, HOF
      • Higher Order Functions
      • Recursion
      • Lab 2 - HOF
      • Lab 3 - Recursion
      • HW 2
    • Project 1 - The game of HOG
      • Phase 1 - Simulator
      • Phase 2 - Commentary
      • Phase 3 - Strategies
    • Week 3 - Sequences, Data Abstraction, Trees
      • Sequences
      • Data Abstraction
      • Trees
      • Lab 4 - Lists practice, Data abstraction
      • Lab 5 - Sequences, Trees
      • HW 3
    • Week 4 - Mutable Functions & Growth, Iterators & Generators
      • Mutable Functions
      • Measuring growth
      • Iterators
      • Generators
      • Lab 6 - Nonlocal, Mutability
      • Lab 7 - Midterm review
    • Project 2 - Typing Test
      • Phase 2 - Basic Functionality
      • Phase 3 - Autocorrect
    • Week 5 - Objects, Inheritance, LL, Interfaces
      • OOP
      • Lab 8 - OOP
      • Lab 9 - More OOP, LLs, Trees
    • Project 3 - Ants
      • Phase 1 - Basic gameplay & Phase 2 - Ants
      • Phase 3 - More Ants!
      • Phase 4 - Water & Might
    • Week 6 - Scheme, Interpreters, Macros
      • Scheme
      • Interpreters
      • Macros
      • Lab 10 - Scheme
      • Lab 11 - Interpreters
      • HW6 - Scheme, Tail Recursion, Macros
    • Week 7 - Streams, Declarative Programming
      • Streams
      • Declarative & Imperative Programming
      • SQL
      • Lab 12 - Macros
      • Lab 13 - SQL
      • HW 7 - Streams, SQL
    • Project 4 - Scheme Interpreter
      • Part 1 - The Reader
      • Part 2 - Evaluation - Core Functionality
      • Part 3 - Evaluation - User-Defined Procedures & Special Forms
      • Part 4 - Write Some Scheme
    • Week 8 - Final Review
      • Lab 14 - Final Review (Optional Lab)
Powered by GitBook
On this page
  1. CS61A Summer 2019

Project 4 - Scheme Interpreter

PreviousHW 7 - Streams, SQLNextPart 1 - The Reader

Last updated 1 year ago

In this project we built an interpreter for a subset of the Scheme language. We weren't really starting from scratch and all the specs were really well defined, so you always knew where and what to implement.

I think it's useful for students new to programming to work on a project like this, because it requires them to navigate a "larger" codebase as opposed to the atomic problems that one deals with in the homeworks and labs.

We also got to write some Scheme in , Problem 19 being the creme de la creme, after finishing that one, I was really happy to be done with this project.

Instructions:

Solution:

Implementation overview

Here is a brief overview of each of the Read-Eval-Print Loop components in our interpreter. Refer to this section as you work through the project as a reminder of how all the small pieces fit together!

  • : This step parses user input (a string of Scheme code) into our interpreter's internal Python representation of Scheme expressions (e.g. Pairs).

    • Lexical analysis has already been implemented for you in the tokenize_lines function in scheme_tokens.py. This function returns a Buffer (from buffer.py) of tokens. You do not need to read or understand the code for this step.

    • Syntactic analysis happens in scheme_reader.py, in the scheme_read and read_tail functions. Together, these mutually recursive functions parse Scheme tokens into our interpreter's internal Python representation of Scheme expressions. You will complete both functions.

  • : This step evaluates Scheme expressions (represented in Python) to obtain values. Code for this step is in the main scheme.py file.

    • Eval happens in the scheme_eval function. If the expression is a call expression, it gets evaluated according to the rules for evaluating call expressions (you will implement this). If the expression being evaluated is a special form, the corresponding do_?_form function is called. You will complete several of the do_?_form functions.

    • Apply happens in the scheme_apply function. If the function is a built-in procedure, scheme_apply calls the apply method of that BuiltInProcedure instance. If the procedure is a user-defined procedure, scheme_apply creates a new call frame and calls eval_all on the body of the procedure, resulting in a mutually recursive eval-apply loop.

  • Print: This step prints the __str__ representation of the obtained value.

  • Loop: The logic for the loop is handled by the read_eval_print_loop function in scheme.py. You do not need to understand the entire implementation.

😄
Part 4
https://inst.eecs.berkeley.edu/~cs61a/su19/proj/scheme/
https://github.com/tomthestrom/cs61a/tree/master/projects/scheme
Read
Eval