Parameter passing

Page 1

Assignment #7 CSCE 550

“Parameter passing convention” Georgiana Tache gxt6286


Statement of the problem ●

A new language AF (Annot-Formal) which extends Mutable Pairs (chapter 4) AF supports: –

Call-by-value Call-by-reference

Call-by-need

The type of calling is established at the point of procedure declaration New test cases are added to support the differences between the types of calling


Convention ●

The type of calling is distinguished using the following annotations in front of the procedure argument: –

value

ref

lenes - for lazy evaluation

There is no implicit annotation

All proc declarations are required to specify the convention let p = proc (value x) x in (p 10)


Changes in the lexical spec & grammar â—?

Lexical spec supports 3 annotations: (annot ("lenes") symbol) (annot ("value") symbol) (annot ("ref") symbol)

â—?

The grammar for proc is changed to require the type of parameter passing in the procedure declaration (expression ("proc" "(" annot identifier ")" expression) proc-exp)


Abstract Data Types ●

ExpVal = Num + Bool + Proc + Reference + Mutpair + Thunk

Thunk = (Expression, Environment)

Thunk is used to store the information for evaluating an expression within an environment. Its evaluation is delayed until the last moment.


Semantics of the changed expressions ●

I keep in the store a global variable mode, which will save the annotation I update its value once the procedure is declared interp.scm (define mode "") (define value-of-program (lambda (pgm) (initialize-store!) (set! mode (newref 'unspecified)) (…... ))))))

interp.scm (proc-exp (annot var body) (begin (setref! mode annot) (proc-val (procedure var body env)) ))

I use mode in call-exp, var-exp and apply-procedure


Semantics of the changed expressions In call-exp, the argument of the function is evaluated with value-of only if we have call by value.

interp.scm (call-exp (rator rand) (let ((proc (expval->proc (value-of rator env))) (arg (if (equal? (deref mode) 'value) (value-of rand env) (value-of-operand rand env)))) (apply-procedure proc arg)))

In case of call by reference and call by need, the expression is evaluated with value-ofoperand: If the operand is a variable then get its value from the environment. If it's an expression not bound to a variable, evaluate it only if we don't have call by need, and also create a new reference for it.

(define value-of-operand (lambda (exp env) (cases expression exp (var-exp (var) (apply-env env var)) (else (newref (if (equal? (deref mode) 'lenes) (a-thunk exp env) (value-of exp env)))))))


Semantics of the changed expressions ● ●

A change in apply-procedure If call by value – create a new reference, otherwise use the same reference (which is either bound before in value-of-operand or bound at the creation of the variable) (define apply-procedure (lambda (proc1 arg) (cases proc proc1 (procedure (var body saved-env) (let ((r (if (equal? (deref mode) 'value) (newref arg) arg))) (let ((new-env (extend-env var r saved-env))) (value-of body new-env)))))))


Semantics of the changed expressions Call by need implementation

â—?

A lazy reference evaluation

(define value-of-operand (lambda (exp env) (cases expression exp (var-exp (var) (apply-env env var)) (else (newref (if (equal? (deref mode) 'lenes) (a-thunk exp env) (value-of exp env)))))))

(define-datatype thunk thunk? (a-thunk (exp1 expression?) (env environment?))) A thunk has an (unevaluated) expression and an environment attached.


Semantics of the changed expressions Call by need implementation ●

Modification in var-exp:

interp.scm (var-exp (var) (if (not (equal? (deref mode) 'lenes)) (deref (apply-env env var)) ; else, lazy evaluation: (let ((ref1 (apply-env env var))) (let ((w (deref ref1))) (if (expval? w) w (let ((v1 (value-of-thunk w))) (begin (setref! ref1 v1) v1)))))))

data-structures.scm (define value-of-thunk (lambda (th) (cases thunk th (a-thunk (exp1 saved-env) (value-of exp1 saved-env))))) If non-lazy evaluation or lazy evaluation of an expval → get the value of the variable from the environment If lazy evaluation of a thunk → evaluate it using value-of-thunk

The procedure's argument stays as a thunk until it's needed in the body and will be evaluated as a var-exp.


Examples of test cases test1.scm "newpair (let p = proc(value x) set x = 4 in let a = 3 in begin (p a); a end, 3)" test2.scm "newpair (let p = proc(ref x) set x = 4 in let a = 3 in begin (p a); a end, 4)"

test4.scm "newpair (let swap = proc (ref x) proc (value y) let temp = x in begin set x = y; set y = temp end in let a = 33 in let b = 44 in begin ((swap a) b); -(a,b) end , 0)" Each test file has a tuple: “newpair (AF-lang-code, expected value)�


Examples of test cases > (run-all) Runs all previous test cases from tests.scm, where I have modified the syntax of proc > (run-all-files) Runs all additional tests defined in new files, folder tests > (run-everything) Runs both of the above

test6.scm "newpair (let p = proc(value f) proc(value x) -(((f f) -(x,1)), -(0,x)) in let newp = proc(lenes n) 25 in (newp ((p p) 5)) , 25)"

Using value or ref instead of lenes → the program doesn't terminate

In top.scm – 2 new functions: run-file: reading and interpreting one test file run-all-files: comparing the expected output with the actual output, for all test files


Questions?


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.