Interp-PROC

advertisement
Procedures
EOPL3: Section 3.3 PROC and
App B: SLLGEN
The PROC language
• Expression ::= proc (Identifier) Expression
– AST: proc-exp (var body)
• Expression ::= (Expression Expression)
– AST: call-exp (rator rand)
• PROC includes all of LET language
• Anonymous procedure
• One parameter always
CS784(pm)
2
Semantics of Procedures
• (This slide is for procedures in general.)
• Procedure Definition
– Store formal parameters and body
• Procedure Invocation
– Evaluate body in an environment that binds
formals to actual argument values
• Interpretation of free-variables: Two methods
– Use env at proc definition (lexical/static scoping)
– Use env at proc call (dynamic scoping)
CS784(pm)
3
Scoping and Binding
• references
– (f x y)
– f, x, and y
• declarations
– (lambda (x) (+ x 3))
– (let ((x (+ y 7))) (+ x 3))
• y, and second/right x are refs
• first/left x is a declaration
• lexical scoping rules
CS784(pm)
4
Kinds of Scope
• Static or Lexical scope
– determined by structure of program
– Scheme, C++, Java, and many compiled languages
• Dynamic scope
– determined by path of execution
– Lisp dialects, Perl, and many interpreted languages
• Global Scope
– File scope
• Local Scope
– Block
• Body of a procedure
• Body of a loop
• Scope alters the meaning
CS784(pm)
5
Example-1 of PROC
•
•
•
•
•
•
•
let f = proc (x) --(x,11) in (f (f 77))
Defines an anonymous procedure with one
formal parameter named x.
Body of the procedure: --(x,11)
Binds the name f to this procedure.
Invokes f with actual argument 77.
Invokes f again with the result of above.
(will use two -- just for visibility)
CS784(pm)
6
Example-2 of PROC
• (proc (f) (f (f 77)) proc (x) --(x,11))
• This example is derived from the production
– Expression ::= (Expression Expression)
– so is (f (f 77))
– so is (f 77)
• proc (f) (f (f 77)) is the rator.
– It defines an anonymous procedure with one formal
parameter named f.
• proc (x) --(x,11)) is the rand.
– It also defines an anonymous procedure with one
formal parameter named x.
CS784(pm)
7
Example-3 of PROC
•
let x = 200
in let f =
proc (z) --(z, x)
in let x = 100
in let g =
proc (z) --(z, x)
in --((f 1), (g 1))
CS784(pm)
• Illustrates scope issues
• x and z appear four
times each.
• Lexical scoping
– In --((f 1), (g 1)), the
bodies of f and g must
be evaluated in the env
they were defined.
– In f, x is bound to 200
– In g, x is bound to 100
8
Example Programs of PROC
• Example-1 and -2 produce same result, but
different mechanisms.
• Previous two slides gave semantics
informally
– Watch out: a very seductive approach
– Next few slides: interpreter based
CS784(pm)
9
Example Calc w/ Spec 1
CS784(pm)
10
Example Calc w/ Spec 2
CS784(pm)
11
Example Calc w/ Spec 3
CS784(pm)
12
Example Calc w/ Spec 4
CS784(pm)
13
Recall value-of
• value-of is an operator with two operands
– an AST
– an environment
– (value-of ast env)
• PROC = LET + two more productions
• Bring in all value-of specs from LET
• Additions are shown on next few slides …
CS784(pm)
14
additional value-of specs
• (value-of (proc-exp var body) ρ)
= (proc-val (procedure var body ρ))
• (value-of (call-exp rator rand) ρ)
= (let
( (proc (expval->proc (value-of rator ρ)))
(arg (value-of rand ρ)))
(apply-procedure proc arg))
• To be defined: proc-val, apply-procedure
CS784(pm)
15
Spec of apply-procedure
• (apply-procedure
(procedure var body ρ)
val)
= (value-of body [var=val]ρ )
• apply-procedure takes two arguments:
– an AST of a procedure definition
– an argument for the parameter of the procedure
– yields an expressed value
CS784(pm)
16
Impl of apply-procedure
(define proc?
(lambda (pc)
(procedure? pc)))
• procedure? provided from r5rs
• Names being bound:
(define procedure
(lambda (var body env)
(lambda (val)
(value-of body
(extend-env var val env)))))
•
•
•
•
(define apply-procedure
(lambda (pc val) (pc val)))
CS784(pm)
– proc?
– procedure
– apply-procedure
env is an environment
ASTs: body, pc, val, var
Use of procedure? is too liberal.
procedure is not self-contained;
takes three arguments:
– param name var
– body AST
– environment
17
Alternate impl called Closures
(define-datatype proc proc?
(procedure
(var identifier?)
(body expression?)
(saved-env environment?)))
•
•
Defining a new data type called
“proc”
Has only one variant
–
•
procedure
That has three parts
–
var
•
(define apply-procedure
(lambda (pc val)
(cases proc pc
(procedure
(var body saved-env)
(value-of body
(extend-env
var val saved-env))))))
CS784(pm)
–
body
•
–
an expression
saved-env
•
•
•
which must be an id
an environment
apply-procedure takes pc and val.
“cases proc pc”
–
–
pc is expected to be of type proc
code for each variant of proc
•
only one variant “procedure” here
18
the data type expval is now …
(define-datatype expval expval?
(num-val
(num number?))
(bool-val
(bool boolean?))
(proc-val
(proc proc?)))
CS784(pm)
19
value-of: two new clauses
(proc-exp (var body)
(proc-val (procedure var body env)))
(call-exp (rator rand)
(let ( (proc (expval->proc
(value-of rator env)))
(arg (value-of rand env)))
(apply-procedure proc arg)))
CS784(pm)
20
Curried procedures
• In PROC, procedures with multiple
arguments can be had as in:
– let f = proc (x) proc (y) ...
in ((f 3) 4)
– proc (x) … yields a procedure
• Named after Haskell Brooks Curry (1900 –
1982), a combinatory logician.
CS784(pm)
21
chapter3/proc-lang/
• Two subdirectories
– chapter3/proc-lang/proc-rep: procedural implementation
– chapter3/proc-lang/ds-rep: data type based (i.e., closure)
• Both directories have the following files
–
–
–
–
–
–
–
data-structures.scm
drscheme-init.scm
environments.scm
interp.scm
lang.scm
tests.scm
top.scm
CS784(pm)
22
EOPL3 Appendix B SLLGEN
(define scanner-spec-1 ...)
(define grammar-1 ...)
(sllgen:make-define-datatypes
scanner-spec-1 grammar-1)
(define list-the-datatypes
(lambda ()
(sllgen:list-define-datatypes
scanner-spec-1 grammar-1)))
(define just-scan
(sllgen:make-string-scanner
scanner-spec-1 grammar-1))
(define scan&parse
(sllgen:make-string-parser
scanner-spec-1 grammar-1))
(define read-eval-print
(sllgen:make-rep-loop "--> "
value-of--program
(sllgen:make-stream-parser
scanner-spec-1 grammar-1)))
CS784(pm)
• sllgen:make-definedatatypes: generates a
define-datatype for each
production of the
grammar, for use by
cases.
• sllgen:make-stringscanner takes a scanner
spec and a grammar and
generates a scanning
procedure
• read-eval-print loop
23
Lexical Analysis
(define the-lexical-spec
'((whitespace
(whitespace) skip)
(comment
("%" (arbno
(not #\newline)))
skip)
(identifier
(letter (arbno
(or letter digit
"_" "-" "?")))
symbol)
(number
(digit (arbno digit))
number)
(number
("-" digit (arbno
digit))
number)
))
CS784(pm)
• the-lexical-spec
• from chapter3/
proc-lang/*/lang.scm
• scanners are specified
by reg exp – next slide
• All our languages use
this lexical analysis.
24
SLLGEN Scanner Spec
Scanner-spec ::=
({Regexp-and-action}∗)
Regexp-and-action ::=
(Name ({Regexp}∗)
Action)
Name ::= Symbol
Regexp
::= String | letter
| digit| whitespace|any
::= (not Character)
| (or {Regexp}∗)
::= (arbno Regexp) |
(concat {Regexp}∗)
Action ::=
skip | symbol
| number | string
CS784(pm)
• A scanner
specification in
SLLGEN is a list that
satisfies the grammar
at left
25
The SLLGEN Parsing System
(define the-grammar
'((program (expression) a-program)
(expression (number) const-exp)
(expression
("-" "(" expression "," expression ")")
diff-exp)
(expression
("zero?" "(" expression ")")
zero?-exp)
(expression
("if" expression "then" expression "else" expression)
if-exp)
(expression (identifier) var-exp)
(expression
("let" identifier "=" expression "in" expression)
let-exp)
• the-grammar of PROC
• from chapter3/
proc-lang/*/lang.scm
• Double-quoted items
are terminals/tokens.
(expression
("proc" "(" identifier ")" expression)
proc-exp)
(expression
("(" expression expression ")")
call-exp)
))
CS784(pm)
26
Specifying Grammars
Grammar ::=
({Production}∗)
Production ::=
(Lhs ({Ritem}∗)
Prod-name)
Lhs ::= Symbol
Ritem
::= Symbol | String
::= (arbno {Ritem}∗)
::= (separated-list
{Ritem}∗ String)
Prod-name ::= Symbol
CS784(pm)
• A grammar in
SLLGEN is a list
described by the
grammar at left
27
HW2 Problem
(define closure
(lambda (ids body env)
(let
((freevars
(set-diff
(free-vars body)
ids)))
(let ((saved-env
(extend-env
freevars
(map
(lambda (v)
(apply-env env v))
freevars)
(empty-env))))
(lambda (args)
(eval-expression body
(extend-env ids args
saved-env)))))))
CS784(pm)
•
•
•
•
http://www.cs.wright.edu/~pmateti/Course
s/784/Top/784-HW2.html
In our data-structure representation of
procedures, we have kept the entire
environment in the closure. But of course
all we need are the bindings for the free
variables.
Modify the representation of procedures to
retain only the free variables.
flat closure rep shown left
–
•
•
•
consists of exactly one rib of free variables
and their values.
free-vars: ykwim ;-)
set-diff: difference of two sets
map provided from r5rs
28
Download