parameter passing

Download Parameter passing

If you can't read please download the document

Upload: georgiana-t

Post on 29-Jul-2015

118 views

Category:

Science


2 download

TRANSCRIPT

1. Assignment #7 CSCE 550 Parameter passing convention Georgiana Tache gxt6286 2. 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 3. 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) 4. 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) 5. 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. 6. 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 I use mode in call-exp, var-exp and apply-procedure 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)) )) 7. Semantics of the changed expressions 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 call-exp, the argument of the function is evaluated with value-of only if we have call by value. In case of call by reference and call by need, the expression is evaluated with value-of- operand: 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))))))) 8. 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))))))) 9. 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. 10. 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))))))) 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 data-structures.scm (define value-of-thunk (lambda (th) (cases thunk th (a-thunk (exp1 saved-env) (value-of exp1 saved-env))))) The procedure's argument stays as a thunk until it's needed in the body and will be evaluated as a var-exp. 11. 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) 12. Examples of test cases 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 > (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 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 13. Questions?