cs 598 scripting languages design and implementation 10. interpreters part i: lisp

82
CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

Upload: claud-ford

Post on 18-Jan-2018

217 views

Category:

Documents


0 download

DESCRIPTION

Lisp Again from the wikipedia: Lisp (historically, LISP) is a family of computer programming languages with a long history and a distinctive, fully parenthesized Polish prefix notation.[1] Originally specified in 1958, Lisp is the second-oldest high-level programming language in widespread use today; only Fortran is older (by one year). Like Fortran, Lisp has changed a great deal since its early days, and a number of dialects have existed over its history. Today, the most widely known general-purpose Lisp dialects are Common Lisp and Scheme. Lisp was invented by John McCarthy in 1958 while he was at the Massachusetts Institute of Technology (MIT). McCarthy published its design in a paper in Communications of the ACM in 1960, entitled Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I (Part II was never published). He showed that with a few simple operators and a notation for functions, one can build a Turing-complete language for algorithms. 3

TRANSCRIPT

Page 1: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

CS 598 Scripting Languages Design and Implementation

10. InterpretersPart I: Lisp

Page 2: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

2

Interpreters• Typically, the simplest way to implement a dynamic

language.• The resulting implementation could be slow, but it is often

adequate as testified by the numerous interpreted laguages that are widely used.

• An interpreter is a practical tool, but also its specification can be used to formally specify the semantics of a language.

• However, formal definitions are seldom used by practitioners.

Page 3: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

3

Lisp• Again from the wikipedia: Lisp (historically, LISP) is a family of computer

programming languages with a long history and a distinctive, fully parenthesized Polish prefix notation.[1] Originally specified in 1958, Lisp is the second-oldest high-level programming language in widespread use today; only Fortran is older (by one year). Like Fortran, Lisp has changed a great deal since its early days, and a number of dialects have existed over its history. Today, the most widely known general-purpose Lisp dialects are Common Lisp and Scheme.

• Lisp was invented by John McCarthy in 1958 while he was at the Massachusetts Institute of Technology (MIT). McCarthy published its design in a paper in Communications of the ACM in 1960, entitled Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I (Part II was never published). He showed that with a few simple operators and a notation for functions, one can build a Turing-complete language for algorithms.

Page 4: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

4

Scheme• Scheme and Common Lisp are the two principal dialects of the

computer programming language Lisp. Unlike Common Lisp, however, Scheme follows a minimalist design philosophy that specifies a small standard core accompanied by powerful tools for language extension.

• Scheme was created during the 1970s at the MIT AI Lab and released by its developers, Guy L. Steele and Gerald Jay Sussman, via a series of memos now known as the Lambda Papers. It was the first dialect of Lisp to choose lexical scope and the first to require implementations to perform tail-call optimization, giving stronger support for functional programming and associated techniques such as recursive algorithms.

Page 5: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

5

Simple scheme tutorial

• https://classes.soe.ucsc.edu/cmps112/Spring03/languages/scheme/SchemeTutorialB.html

Page 6: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

6

Lisp metacircular evaluator• You can read Lisp by reading a reference manual or by

studying eval• The fact that the definition of eval is available in Lisp

means that the programming environment is part of the language.

• Even today, the fact that eval can be defined in Lisp means that it’s easy to experiment with new models of implementation and debugging.

• … it must give up the possiblity of many optimizations. In other words, using eval is not without consequences

Page 7: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

7

Types of procedures

• Predicates and• Selectors

• Approach introduced by McCarthy• Both types found in VDL

Page 8: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

8

Metacircular evaluatorBasic procedures

• (apply-primmitive-procedure < procedure > < args > )• (primitive-procedure? < procedure > )

– returns whether the procedure is a primitive procedure.

• (lookup-variable-value < variable > <env>) – returns the value of < variable > in the environment < env >.

• (extend-environment < variables > < values > < base-env >) – adds a frame to < base-env > with < variables > bound to < values >.

• (define-variable! < variable > < value > < env >)– adds < variable > with value < value > to the environment’s top frame.

• (set-variable-value! < variable > < value > < env >)

Page 9: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

9

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 10: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

10

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 11: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

11

apply

(define (apply procedure arguments) (cond ((primitive-procedure? procedure)

(apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence

(procedure-body procedure)(extend-environment (parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type\APPLY"

procedure))))

Page 12: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

12

apply

(define (apply procedure arguments) (cond ((primitive-procedure? procedure)

(apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence

(procedure-body procedure)(extend-environment (parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type\APPLY"

procedure))))

Page 13: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

13

eval-sequence

(define (eval-sequence exps env) (cond ((last-exp? exps) (eval (first-exp exps)env)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps)env))))

Page 14: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

14

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 15: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

15

list-of-values

(define (list-of-values exps env) (cond ((no-operands? exps) '()) (else (cons (eval (first-operand exps) env) (list-of-values (rest-operands exps) env)))))

Page 16: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

16

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 17: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

17

eval-cond

(define (eval-cond clist env) (cond ((no-clauses? clist) nil) ((else-clause? (first-clause clist)) (eval-sequence (actions (first-clause clist)) env)

((true? (eval (predicate (first-clause clist))env)) (eval-sequence (actions (first-clause clist)) env))

(else (eval-cond (rest-clauses clist) env))))

Page 18: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

18

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 19: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

19

eval-assignment

(define (eval-assignment exp env) (let ((new-value (eval (assignment-value exp) env))) (set-variable-value! (assignment-variable exp) new-value env) new-value))

Page 20: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

20

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 21: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

21

eval-definition

(define(eval-definition exp env) (define-variable! (definition-variable exp) (eval (definition-value exp) env) env) (definition-variable exp))

Page 22: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

22

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 23: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

23

self-evaluating?quoted?

variable? • The only self-evaluating items are numbers:

(define (self-evaluating? exp) (number? exp))

• Quotations are expressions of the form (quote ( text-of-quotation ) ) :

(define (quoted? exp) (if (atom? exp) nil (eq? (car exp) ‘quote) ) )

(define (text-of-quotation exp) (cadr exp) )

• Variables are represented by symbols:

(define (variable? exp) (symbol? exp) )

Primitive predicates

Page 24: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

24

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 25: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

25

assignment? • Assignments are expressions of the form:

(set! < variable> < value >)

(define (assignment? exp) (if (atom? exp) nil (eq? (car exp) ‘set!)))

Page 26: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

26

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 27: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

27

definition? • Definitions are expressions of the form (define < variable> < value > )• or of the form

(define (<variable> < parameter1 > . . . <parametern > ) < body>)

• The latter form (standard procedure definition) is syntactic sugar for

(define <variable> (lambda (< parameter1 > . . . <parametern > ) ) < body>))

Page 28: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

28

definition? • The corresponding syntax procedures are the following:

(define (definition? exp) (if (atom? exp) nil (eq? (car exp) 'define)))

(define (definition-variable exp) (if (variable? (cadr exp) ) (cadr exp) (caadr exp) ) )

(define (definition-value exp) (if (variable? (cadr exp) ) (caddr exp) (cons ‘lambda (cons (cdadr exp) ;formal parameters (cddr exp ))))))) ;body

Page 29: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

29

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 30: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

30

lambda?

(define (lambda? exp) (if (atom? exp) nil (eq? (car exp) 'lambda) ) )

Page 31: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

31

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 32: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

32

conditional?clauses

(define (conditional? exp) (if (atom? exp) nil (eq? (car exp) 'cond) ) ) (define (clauses exp) (cdr exp) )

Page 33: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

33

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 34: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

34

conditional? clauses

(define (conditional? exp) (if (atom? exp) nil (eq? (car exp) 'cond) ) ) (define (clauses exp) (cdr exp) )

Page 35: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

35

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 36: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

36

eval-cond

(define (eval-cond clist env) (cond ((no-clauses? clist) nil) ((else-clause? (first-clause clist)) (eval-sequence (actions (first-clause clist)) env)

((true? (eval (predicate (first-clause clist))env)) (eval-sequence (actions (first-clause clist)) env))

(else (eval-cond (rest-clauses clist) env))))

Page 37: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

37

no-clauses?/first-clause/ rest-clauses/predicate/actions/ true?/else-

clause? (define (no-clauses? clauses)

(null? clauses) )

(define (first-clause clauses) (car clauses)) (define (rest-clauses clauses) (cdr clauses) ) (define (predicate clause) (car clause) )

(define (actions clause) (cdr clause) ) (define (true? x) (not (null? x) ) )

(define (else-clause? clause) (eq? (predicate clause) 'else) )

Page 38: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

38

apply

(define (apply procedure arguments) (cond ((primitive-procedure? procedure)

(apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence

(procedure-body procedure)(extend-environment (parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type\APPLY"

procedure))))

Page 39: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

39

eval-sequence

(define (eval-sequence exps env) (cond ((last-exp? exps) (eval (first-exp exps)env)) (else (eval (first-exp exps) env) (eval-sequence (rest-exps exps)env))))

Page 40: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

40

last-exp?/first-exp/rest-exps

(define (last-exp? seq) (null? (cdr seq) ) ) (define (first-exp seq) (car seq) )(define (rest-exps seq) (cdr seq) )

Page 41: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

41

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 42: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

42

application?operator operands

;application if it is non atom and is none of the above (define (application? exp) (not (atom? exp) ) )

(define (operator app) (car app) )

(define (operands app) (cdr app) )

Page 43: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

43

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 44: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

44

list-of-values

(define (list-of-values exps env) (cond ((no-operands? exps) '()) (else (cons (eval (first-operand exps)env) (list-of-values (rest-operands exps) env)))))

Page 45: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

45

no-operands? first-operand

rest-operands

(define (no-operands? args) (null? args) ) (define (first-operand args) (car args) ) (define (rest-operands args) (cdr args) )

Page 46: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

46

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 47: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

47

make-procedure (define (make-procedure lambda-exp env) (list 'procedure lambda-exp env)) Since a lambda expression has the syntax (lambda <parameters> <exp1> . . . <expn>) the result of make-procedure is(procedure (lambda <parameters> <exp1> . . . <expn> ) < env>)

Page 48: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

48

eval

(define (eval exp env) (cond ((self-evaluating? exp) exp)

((quoted? exp) (text-of -quotation exp))((variable? exp) (lookup-variable-value exp env)) ((definition? exp) (eval-definition exp env))((assignment? exp) (eval-assignment exp env)) ((lambda? exp)(make-procedure exp env) )((conditional? exp) (eval-cond (clauses exp) env) ) ((application? exp) (apply (eval (operator exp) env) (list-of-values (operands exp) env))

(else(error "Unknown expression type/EVAL” exp))))

Page 49: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

49

apply

(define (apply procedure arguments) (cond ((primitive-procedure? procedure)

(apply-primitive-procedure procedure arguments)) ((compound-procedure? procedure) (eval-sequence

(procedure-body procedure)(extend-environment (parameters procedure) arguments (procedure-environment procedure)))) (else (error "Unknown procedure type\APPLY"

procedure))))

Page 50: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

50

compound-procedure?parameters

procedure-bodyprocedure-environment

(procedure (lambda <parameters> <exp1> . . . <expn> ) < env>)

(define (compound-procedure? proc) (if (atom? proc) nil (eq? (car proc) 'procedure) ) )

(define (parameters proc) (cadr (cadr proc) ) )(define (procedure-body proc) (cddr (cadr proc) ) )(define (procedure-environment proc) (caddr proc) )

Page 51: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

51

Metacircular evaluatorBasic procedures

• (apply-primmitive-procedure < procedure > < args > )• (primitive-procedure? < procedure > )

– returns whether the procedure is a primitive procedure.

• (lookup-variable-value < variable > <env>) – returns the value of < variable > in the environment < env >.

• (extend-environment < variables > < values > < base-env >) – adds a frame to < base-env > with < variables > bound to < values >.

• (define-variable! < variable > < value > < env >)– adds < variable > with value < value > to the environment’s top frame.

• (set-variable-value! < variable > < value > < env >)

Page 52: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

52

lookup-variable-value (define (lookup-variable-value var env) (let ((b (binding-in-env var env))) (if (found-binding? b) (binding-value b) (error "Unbound variable" var))))

(define (binding-in-env var env) (if (no-more-frames? env) no-binding (let ((b (binding-in-frame var (first-frame env)))) (if (found-binding? b) b (binding-in-env var (rest-frames env))))))

Page 53: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

53

Metacircular evaluatorBasic procedures

• (apply-primmitive-procedure < procedure > < args > )• (primitive-procedure? < procedure > )

– returns whether the procedure is a primitive procedure.

• (lookup-variable-value < variable > <env>) – returns the value of < variable > in the environment < env >.

• (extend-environment < variables > < values > < base-env >) – adds a frame to < base-env > with < variables > bound to < values >.

• (define-variable! < variable > < value > < env >)– adds < variable > with value < value > to the environment’s top frame.

• (set-variable-value! < variable > < value > < env >)

Page 54: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

54

extend-environmentset-variable-value!define-variable!

define (extend-environment variables values base-env) (adjoin-frame (make-frame variables values) base-env ))

(define (set-variable-value! var val env) (let ((b (binding-in-env var env))) (if (found-binding? b) (set-binding-value! b val) (error "Unbound variable" var))))

(define (define-variable! var val env) (let ((b (binding-in-frame var (first-frame env)))) (if (found-binding? b) (set-binding-value! b val) (set-first-frame! env (adjoin-binding (make-binding var val) (first-frame env))))))

Page 55: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

55

Representing environments(define (first-frame env) (car env))

(define (rest-frames env) (cdr env))

(define (no-more-frames? env) (null? env))

(define (adjoin-frame frame env) (cons frame env))

(define (set-first-frame! env new-frame) (set-car! env new-frame))

Page 56: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

56

Frames(define (make-frame variables values) (cond ((and (null? variables) (null? values) ) ‘() ) ((null? variables) (error "Too many values supplied" values) ) ((null? values) (error "Too few values supplied" variables) ) (else (cons (make-binding (car variables) (car values) ) (make-frame (cdr variables) (cdr values))))))

(define (adjoin-binding binding frame) (cons binding frame) )

Page 57: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

57

(define (assq key bindings)(cond ((null? bindings) no-binding) ((eq? key (binding-variable (car bindings))(car bindings)) (else (assq key (cdr bindings))))) (define (binding-in-frame var frame)(assq var frame)) (define (found-binding? b)(not (eq? b no-binding) ) ) (define no-binding nil)

Page 58: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

58

Representing bindings(define (make-binding variable value) (cons variable value) ) (define (binding-variable binding) (car binding) ) (define (binding-value binding) (cdr binding) ) (define (set-binding-value! binding value) (set-cdr! binding value) )

Page 59: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

59

(define primitive-procedure-names‘(car cdr cons ( <names of more primitives> ) ) )

 (define primitive-procedure-objects(<list of objects representing primitives> ) )

Page 60: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

60

(define (setup-environment) (let ((initial-env (extend-environment primitive-procedure-name primitive-procedure-objects ‘() ) ) )

(define-variable! 'nil nil initial-env)

(define-variable! 't (not nil) initial-env) initial-env) ) (define the-global-environment (setup-environment) )

Page 61: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

61

(define (primitive-procedure? proc) (if (atom? proc) nil (eq? (car proc) 'primitive) ) )

(define (primitive-id proc) (cadr proc) ) (define primitive-procedure-objects ‘( (primitive car)(primitive cdr) (primitive cons) (<more primitives> ) ) )

Page 62: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

62

(define (apply-primitive-procedure proc args) (let ( (p (primitive-id proc) ) ) (cond ( (eq? p ‘car) (car (car args) ) ) ( (eq? p ‘cdr) (cdr (car args) ) ) ( (eq? p ‘cons) (cons (car args)(cadr args))) (<more primitives> ) (else (error "Unknown primitive procedure” proc))))

Page 63: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

63

A Lisp interpreter of micro algol

• From “A FORMAL DESCRIPTION OF A SUBSET OF ALGOL” By John McCarhty, 1964.

• “Microalgol is a language for programming about, not for programming in”.

• Two statement:– Assignments– if <p> then goto <label>

Page 64: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

64

Example of microalgol program

root :=1;a: root := 0.5 * (root + x/root);

error := root * root – x;perror := if error > 0.0 then error else 0.0 –

error;If perror > 0.0001 then goto a;

Page 65: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

65

Representation

• It will be an abstract syntax tree, in the form of a Lisp object as follows:

• A program is (<stmt> <stmt> …<stmt>)

• A statement is either– (‘assignment <variable> <expression>) or– (‘ifstatement <expression> <label>)

Page 66: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

66

Selecting a statement by position

(define (statement prog pc) (cond ((null? prog) nil) ((= pc 1) (car prog)) (else (statement (cdr prog) (- pc 1)))))

Page 67: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

67

Representation

• An expression is just represented in prefix notation.

• For example:z*(x+2.0)*(2.0+y) → (‘prod (‘prod ‘z (‘sum ‘x 2.0)) (‘sum 2.0 ‘y))

• andx := t + if error > 0.0 then e else 0.0 - e →(‘assignment ‘x (‘add ‘t (‘ifexpression (‘less 0.0 ‘e) ‘e (‘diff 0.0 ‘e)))

Page 68: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

68

Predicates and their selectorsvariable?number?sum? addend augenddiff? subtraend minuendprod? multiplier multiplicandquotient? numerator denominatorifexpression? proposition antecedent(then) consequent(else)equal? lefteq righteqless? leftlt rightltassignment? left rightifstatement? proposition destination

The form of these predicates is the obvious one. variable? and number? are as above. The others have the following form:

(define (prod? exp) (if (atom? exp) nil (eq? (car exp) ’prod) ) )

Page 69: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

69

Selectors

(define (addend exp ) (cadr exp))(define (subtraend exp ) (cadr exp))(define (multiplier exp ) (cadr exp))(define (numerator exp ) (cadr exp))(define (proposition exp ) (cadr exp))(define (lefteq exp ) (cadr exp))(define (leftlt exp ) (cadr exp))(define (left exp ) (cadr exp))(define (proposition exp ) (cadr exp))

Page 70: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

70

Predicates and their selectorsvariable?number?sum? addend augenddiff? subtraend minuendprod? multiplier multiplicandquotient? numerator denominatorifexpression? proposition antecedent(then) consequent(else)equal? lefteq righteqless? leftlt rightltassignment? left rightifstmt? proposition destination

The form of these predicates is the obvious one. variable? and number? are as above. The others have the following form:

(define (prod? exp) (if (atom? exp) nil (eq? (car exp) ’prod) ) )

Page 71: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

71

Selectors

(define (augend exp ) (caddr exp))(define (minuend exp ) (caddr exp))(define (multiplicand exp ) (caddr exp))(define (denominator exp ) (caddr exp))(define (antecedent exp ) (caddr exp))(define (consequent exp ) (cadddr exp))(define (righteq exp ) (caddr exp))(define (rightlt exp ) (caddr exp))(define (right exp ) (caddr exp))(define (destination exp ) (caddr exp))

Page 72: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

72

Interpreter(define (eval prog pc env)(let ((s (statement prog pc))) (cond ((null? s) env) ((assignment? s) (eval prog (+ pc 1) (define-variable! (left s) (op (right s) env) env) env)) ((ifstatement? s) (eval prog (cond ((true? (op (proposition s) env) ) (lookup-variable-value (destination s) env) ((else (+ pc 1))) env)) (else error “Unknown statement type – EVAL”))))

Page 73: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

73

op(define (opexpr env) (cond ((variable? expr) (lookup-variable-value expr eval)) ((number? expr) expr) ((sum? expr) (+ (op (addend expr) env) (op (augend expr) env) ((diff? expr) (- (op (subtraend expr) env) (op (minuend expr) env)) ((prod? expr) (* (op (multiplier expr) env) (op (multiplicand expr) env)) ((quotient? expr) (/ (op (numerator expr) env) (op (denomintor expr) env)) ((ifexpression? expr) (cond (true? (op (proposition expr) env) (op (antecedent expr) env)) (else (op (consequent expr) env))) ((equal? expr) (= (op (lefteq expr) env) (op (righteq expr) env)) ((less? expr) (< (op (leftlt expr) env) (op (rightlt expr) env)) (else error “Unknown operator – EVAL-EXPR”)))

Page 74: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

74

Processing the program as a sequence of characters

(define (statement pc prog) ; Get statement number pc (if (= pc 1) (delim “;” prog) (statement (- pc 1) (strip “;” prog)))

(define (first prog) ; Get first character of program (if (equal? prog “”) “” (substring prog 0 1) )

(define (rest prog) ; Get the whole program but the first character (if (equal? prog “”) “” (substring prog 1 (string-length prog) )

Page 75: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

75

(define (delim char prog) ; Get the sequence of characters (if (equal? (first prog) char); before the first “;” “” (string-append (first prog) (delim char (rest prog)))))

(define (strip char prog) ; Remove all occurences of char (if (equal? (first prog) char) ; from prog (rest prog) (strip char (rest prog))))

Page 76: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

76

(define (sum? exp) (operator exp 0 “+”)) ; Sum operation

(define (operator exp lev op) (cond ((equal? exp “”) nil) ((equal? (first exp “(“)) (operator (rest exp) (+ lev 1) op)) ((equal? (first exp “)“)) (operator (rest exp) (- lev 1) op)) ((> lev 0) (operator (rest exp) lev op)) ((equal? (first exp op)) #t) (else (operator (rest exp) pos op))))

Page 77: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

77

(define (augend exp) (delimexp “+” 0 exp)

(define (delimexp op lev exp) (cond ((equal? (first exp “(“)) (string-append (first exp) (delimexp op (+ lev 1) (rest exp))) ((equal? (first exp “)“)) (string-append (first exp) (delimexp op (- lev 1) (rest exp))) ((> lev 0)) (string-append (first exp) (delimexp op lev (rest exp))) ((equal? (first exp) op) “”) (else (string-append (first exp) (delimexp op lev (rest exp))))

Page 78: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

78

The program as a sequence of tokens

• Has the advantage that we don’t need to do the lexical scanning as part of the intepretation process.

• Each token has a symbol assosciated with it, except that variables and numbers are pairs.

Page 79: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

79

root :=1;a: root := 0.5 * (root + x/root);

error := root * root – x;perror := if error > 0.0 then error else 0.0 –

error;If perror > 0.0001 then goto a;

(list (‘var . ‘root) ‘assign (‘number . 1) ‘semicolon (‘label ‘a) ‘colon (‘variable . root) ‘assign (‘number 0.5) ‘mpy ‘leftpar (‘variable .‘root) ‘sum (‘variable . ‘x) ‘div (‘variable . ‘root) ‘rightpar ‘semicolon … (‘variable ‘perror) ‘assign ‘if (‘variable . ‘error) ‘gt (‘number . 0.0) ‘then (‘variabl ‘error) ‘else ...

Page 80: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

80

Example evaluator(number, ‘sum, ‘mpy)

(define (eval-exp exp) (cond ((= (length exp) 1) (cdar exp)) ( (operator exp 0 ’sum ) (+ (eval-exp (left-operand exp 0 ’sum)) (eval-exp (right-operand exp 0 ’sum )))) ((operator exp 0 'mpy ) (* (eval-exp (left-operand exp 0 'mpy)) (eval-exp (right-operand exp 0 'mpy)))) (else (eval-exp (depar exp)))))

(define (operator exp lev op) (cond ((equal? exp '()) #f) ((equal? (car exp) 'leftpar) (operator (cdr exp) (+ lev 1) op)) ((equal? (car exp) 'rightpar) (operator (cdr exp) (- lev 1) op)) ((> lev 0) (operator (cdr exp) lev op)) ((eq? (car exp) op) #t) (else (operator (cdr exp) lev op))))

Page 81: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

81

(define (left-operand exp lev op) (cond ((equal? exp '()) '()) ((equal? (car exp) 'lp) (cons (car exp) (left-operand (cdr exp) (+ lev 1) op))) ((equal? (car exp) 'rp) (cons (car exp) (left-operand (cdr exp) (- lev 1) op))) ((> lev 0) (cons (car exp) (left-operand (cdr exp) lev op))) ((equal? (car exp) op) '()) (else (cons (car exp ) (left-operand (cdr exp) lev op)))))

(define (right-operand exp lev op) (cond ((equal? exp '()) '()) ((equal? (car exp) 'lp) (right-operand (cdr exp) (+ lev 1) op)) ((equal? (car exp) 'rp) (right-operand (cdr exp) (- lev 1) op)) ((> lev 0) (right-operand (cdr exp) lev op)) ((eq? (car exp) op) (cdr exp) ) (else (right-operand (cdr exp) lev op))))

Page 82: CS 598 Scripting Languages Design and Implementation 10. Interpreters Part I: Lisp

82

(define (depar exp) (if (equal? (car exp) 'leftpar ) (dep1 (cdr exp)) exp))

(define (dep1 exp) (if (equal? (cdr exp) '()) '() (cons (car exp) (dep1 (cdr exp)))))