1 subt. model interpreter: introduction abstract syntax parser abstract syntax parser derived...

15
1 model interpreter: Introduction Abstract Syntax Parser Derived Expressio ns Core Test Data Structu res Utils (a racket lib) •Global Env. •Evaluator values •Substitution •Op. semantics •Special forms •ADT per expression •An abstraction barrier, used by all evaluators ponents of the interpreter:

Upload: rose-lang

Post on 06-Jan-2018

215 views

Category:

Documents


1 download

DESCRIPTION

3 applicative -eval apply- procedure (define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp) (let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp))))) (define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp) (let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp))))) (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure))))) (define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure))))) Subt. model interpreter: Core Core main-loop:

TRANSCRIPT

Page 1: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

1

Subt. model interpreter: Introduction

Abstract

Syntax Parser

Derived Expressions

Core

Test

Data Structures

Utils(a racket lib)

• Global Env.• Evaluator values• Substitution

• Op. semantics• Special forms

• ADT per expression• An abstraction barrier,used by all evaluators

Components of the interpreter:

Page 2: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

2

Subt. model interpreter: Tests

Tests package: Should be run with every modification!

The procedure test:• Receives a single expression, e, and an expected value, v.• Returns #t if and only if e evaluates to v.

The procedure run-tests:• Runs multiple number test expressions

(test (derive-eval ‘(* 3 4)) => ‘(value 12))

(run-tests (test (derive-eval ‘(+ 3 4)) => ‘(value 7)) (test (derive-eval ‘(- 3 4)) => ‘(value -1)) (test (derive-eval ‘(/ 4 2)) => ‘(value 2)))

Page 3: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

3

applicative-eval

apply-procedure

(define applicative-eval (lambda (exp) (cond ((atomic? exp) (eval-atomic exp)) ((special-form? exp) (eval-special-form exp)) ((evaluator-value? exp) exp) ((application? exp)

(let ((renamed-exp (rename exp))) (apply-procedure (applicative-eval (operator renamed-

exp)) (list-of-values (operands renamed-exp))))) (else (error 'eval "unknown expression type: ~s" exp)))))

(define apply-procedure (lambda (procedure arguments) (cond ((primitive-procedure? procedure) (apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (let ((parameters (procedure-parameters procedure)) (body (rename (procedure-body procedure)))) (eval-sequence (substitute body parameters arguments)))) (else (error 'apply "Unknown procedure type: ~s" procedure)))))

Subt. model interpreter: Core

Core main-loop:

Page 4: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

4

1.( (lambda(x)2. (lambda(y) (y x)))

3. (lambda(x) (+ x y)) )

Subt. model interpreter: Core

The problem:

(lambda(y) (y (lambda(x) (+ x y))))

• y in line 2 is bound.• y in line 3 is free.

• The free occurrence of y is now bound by the formal parameter.

1.( (lambda(x)2. (lambda(y1) (y1 x)))

3. (lambda(x) (+ x y)) )

(lambda(y1) (y1 (lambda(x) (+ x y))))

The solution: consistently rename bound occurrences and their binding instances:

A reminder: Why do we need renaming?

Page 5: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

5

Subt. model interpreter: Supporting case expressions

5

(define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)))))))

Example of using a case expression:

control

clauses

last clause

What are the components of a case expressions?

What are the components of a case-clause?

ASP

Derived expressions

Core

Data structures

compared

actions

Page 6: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

6

(define eval-special-form (lambda (exp) (cond ((quoted? exp) (make-value exp)) ((lambda? exp) (eval-lambda exp)) ((definition? exp) (eval-definition exp)) ((if? exp) (eval-if exp)) ((begin? exp) (eval-begin exp)) ((case? exp) (eval-case exp)))))

Subt. model interpreter: Core - Special Forms

Supporting case as a special form

Step 1: call the appropriate special evaluation procedure

(define special-form? (lambda (exp) (or (quoted? exp) (lambda? exp) (definition? exp) (if? exp) (begin? exp) (case? exp))))

Step 2: Identify the expression as a special form

ASP

Derived expressions

Core

Data structures

Page 7: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

7

Determining the evaluation rule for a case expression:

1. Evaluate the control.

2. Compare its value to each of the compared

components by order (assume numerical values).

3. Evaluate the actions of the first clause in which

the compared value equals the control value.

4. If no such clause exists, evaluate the actions of

the else-clause by order.

Subt. model interpreter: Core - Special Forms

Supporting case as a special form

(define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…)

Step 3: Write the relevant special evaluation procedure

Page 8: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

8

Subt. model interpreter: Core - Special Forms

Supporting case as a special form

(define fib (lambda (n) (case n (0 0) (1 1) (else (+ (fib (- n 1)) (fib (- n 2)…)

Step 3: Write the relevant special evaluation procedure

(define (eval-case exp) (letrec ((eval-clauses (lambda (control clauses) (cond ((null? clauses) 'unspecified) ((or (case-last-clause? clauses) (= (applicative-eval (case-compared (case-first-clause clauses))) control)) (eval-sequence (case-actions (case-first-clause clauses)))) (else (eval-clauses control (case-rest-clauses clauses))))))) (eval-clauses (applicative-eval (case-control exp)) (case-clauses exp))))

Page 9: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

9

Subt. model interpreter: ASP - Handling lambda expressions

9

; Signature: make-lambda(parameters, body); Type: [LIST(Symbol)*LIST -> LIST]

; Signature: lambda-parameters(exp); Type: [LIST -> LIST(Symbol)]

; Signature: lambda-body(exp); Type: [LIST -> LIST]

; Signature: lambda?(exp); Type: [T -> Boolean]

ADT and implementation :

; Signature: make-lambda(parameters, body); Type: [LIST(Symbol)*LIST -> LIST](define make-lambda (lambda (parameters body) (attach-tag (cons parameters body) 'lambda)))

; Signature: lambda-parameters(exp); Type: [LIST -> LIST(Symbol)](define lambda-parameters (lambda (exp) (car (get-content exp))))

; Signature: lambda-body(exp); Type: [LIST -> LIST](define lambda-body (lambda (exp) (cdr (get-content exp))))

; Signature: lambda?(exp); Type: [T -> Boolean](define lambda? (lambda (exp) (tagged-by? exp 'lambda)))

ASP

Derived expressions

Core

Data structures

Page 10: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

10

Subt. model interpreter: Supporting case expressions

10

ADT for case expressions (including ADT for case-clause):

make-case(control case-clauses)Type: [Symbol*LIST->Case-expression]

Constructor for case

case?(exp)Type: [T -> Boolean]

Predicate

case-clauses(case-exp)Type: [LIST -> LIST]

case-control(case-exp)Type: [LIST -> Symbol]

Selectors

make-case-clause(compared actions)Type: [T*LIST -> LIST]

Constructor for case-clause

case-last-clause?Predicate

case-actions

case-comparedSelectors

case-first-clause

case-rest-clauses

Example of use (client side):(make-case 'n (list (make-case-clause '0 '(0)) (make-case-clause '1 '(1)) (make-case-clause 'else '(+ (fib (- n 1)) (fib (– n 2))))))

Page 11: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

11

(define case? (lambda (exp) (tagged-by? exp 'case)))

(define make-case-clause (lambda (compared actions) (cons compared actions)))

(define make-case (lambda (control case-clauses) (attach-tag (cons control case-clauses) 'case)))

(define case-control (lambda (case-exp) (car (get-content case-exp))))

(define case-clauses (lambda (case-exp) (cdr (get-content case-exp))))

(define case-compared car)

(define case-actions cdr)

(define case-first-clause (lambda (clauses) (car clauses)))

(define case-rest-clauses (lambda (clauses) (cdr clauses)))

(define case-last-clause? (lambda (clauses) (and (null? (cdr clauses)) (eq? (case-compared (case-first-clause clauses)) 'else))))

Adding the implementation in the ASP:

Subt. model interpreter: Supporting case expressions

Constructor

Constructor

SelectorsSelectors

Predicate

Predicate

Page 12: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

12

Subt. model interpreter: Derived expressions

ASP

Derived expressions

Core

Data structures

shallow-derive derive

Recursively applies shallow-derive

derived?

How?

1. Edit derive? to consider the new exp as derived.2. Edit shallow-derive to call the relevant translation procedure.3. Add a shallow translation procedure.

Identifies the derived expression, calls the appropriate shallow translation procedure:

((cond? exp) (cond->if exp)) ⁞ ((let? exp) (let->combination exp))

Why?Smaller, simpler core! (let ((x 1)) x) ((lambda(x) x) 1)

Page 13: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

13

(define derive (lambda (exp) (if (atomic? exp) exp (let ((derived-exp (let ((mapped-derive-exp (map derive exp))) (if (not (derived? exp)) mapped-derive-exp (shallow-derive mapped-derive-exp))))) (if (equal? exp derived-exp) exp (derive derived-exp))))))

Subt. model interpreter: Derived expressions

(define derived? (lambda (exp) (or (cond? exp) (function-definition? exp) (let? exp) (letrec? exp))))

(define shallow-derive (lambda (exp) (cond ((cond? exp) (cond->if exp)) ((function-definition? exp) (function-define->define exp)) ((let? exp) (let->combination exp)) ((letrec? exp) (letrec->let exp)) (else "Unhandled derivision" exp))))

ASP

Derived expressions

Core

Data structures

Page 14: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

14

Subt. model interpreter: Derived expressions

ASP

Derived expressions

Core

Data structures

1. Edit derive? to consider the new exp as derived.2. Edit shallow-derive to call the relevant translation procedure.3. Add a shallow translation procedure.

Page 15: 1 Subt. model interpreter: Introduction Abstract Syntax Parser Abstract Syntax Parser Derived Expressions Core Test Data Structures Utils (a racket lib)

15

Subt. model interpreter: Data Structures

ASP

Derived expressions

Core

Data structures

The Global Environment:

(define make-the-global-environment (lambda () (let* ((primitive-procedures (list (list 'car car) (list 'cdr cdr)

(list 'cons cons) (list 'null? null?) (list '+ +) (list '* *) (list '/ /) (list '> >) (list '< <) (list '- -) (list '= =) (list 'list list) (list 'append append) ))

(prim-variables (map car primitive-procedures)) (prim-values (map (lambda (x)

(make-primitive-procedure (cadr x))) primitive-procedures)) )

(make-sub prim-variables prim-values))))