CMPSC 461, HW11 MUL461 Part A

Due: April 22rd, 11:59PM

Set-up: For this assignment, edit a copy of mula.rkt, which is on the course website. In particular,

replace occurrences of "CHANGE" to complete the problems. Do not use any mutation (set!, set-mcar!,

etc.) anywhere in the assignment.

Overview: This project has to do with mul461 (a Made Up Language for CMPSC 461). mul461 programs

are written directly in Racket by using the constructors defined by the structs defined at the beginning of

mula.rkt. This is the definition of mul461’s syntax for Part A:

? If s is a Racket string, then (mul461-var s) is a mul461 expression (a variable use).

? If n is a Racket integer, then (mul461-int n) is a mul461 expression (an integer constant).

? If e1 and e2 are mul461 expressions, then (mul461-+ e1 e2) is a mul461 expression (an addition).

? If e1 and e2 are mul461 expressions, then (mul461-- e1 e2) is a mul461 expression (a subtraction).

? If e1 and e2 are mul461 expressions, then (mul461-* e1 e2) is a mul461 expression (a multiplication).

? If b is a Racket boolean, then (mul461-bool b) is a mul461 expression (a boolean constant).

? If e1 and e2 are mul461 expressions, then (mul461-and e1 e2) is a mul461 expression. e1 and e2

should both evaluate to mul461-bool values.

? If e1 and e2 are mul461 expressions, then (mul461-or e1 e2) is a mul461 expression. e1 and e2

should both evaluate to mul461-bool values.

? If e is a mul461 expression that evaluates to a mul461-bool value, then (mul461-not e) is a mul461

expression.

? If e1 and e2 are mul461 expressions, then (mul461-< e1 e2) is a mul461 expression that evaluates

to a mul461-bool value if e1 and e2 evaluate to mul461-int values.

? If e1 and e2 are mul461 expressions, then (mul461-= e1 e2) is a mul461 expression that evaluates

to a mul461-bool value if e1 and e2 evaluate to mul461-int values.

? If e1, e2, and e3 are mul461 expressions, then (mul461-if e1 e2 e3) is a mul461 expression. It is a

condition where the result is e2 if e1 is a boolean constant of true else the result is e3. Only one of e2

and e3 is evaluated.

? If s is a Racket string and e1 and e2 are mul461 expressions, then (mul461-let s e1 e2) is a mul461

expression (a let expression where the value resulting from evaluating e1 is bound to s in the evaluation

of e2).

In Part A, A mul461 value is a mul461 integer constant, a or a mul461 boolean constant.

You should assume mul461 programs are syntactically correct (e.g., do not worry about wrong things like

(mul461-int "hi") or (mul461-int (mul461-int 37)). But do not assume mul461 programs are free of

type errors like (mul461-+ (mul461-bool #t) (mul461-int 7)) or (mul461-not (mul461-int 3)).

Warning: What makes this assignment challenging is that you have to understand mul461 well and

debugging an interpreter is an acquired skill.

Turn-in Instructions: Turn in your modified mula.rkt to gradescope.

1

Problems:

1. Implementing the mul461 Language: Write a mul461 interpreter, i.e., a Racket function eval-exp

that takes a mul461 expression e and either returns the mul461 value that e evaluates to under the

empty environment or calls Racket’s error if evaluation encounters a run-time mul461 type error or

unbound mul461 variable.

A mul461 expression is evaluated under an environment (for evaluating variables, as usual). In your

interpreter, use a Racket list of Racket pairs to represent this environment (which is initially empty)

so that you can use without modification the provided envlookup function. Here is a description of

the semantics of mul461 expressions:

? All values evaluate to themselves. For example, (eval-exp (mul461-int 17)) would return

(mul461-int 17), not 17.

? A variable evaluates to the value associated with it in the environment.(This case for var is done

for you.)

? An addition/subtraction/multiplication evaluates its subexpressions and, assuming they both

produce integers, produces the mul461-int n that is their sum/difference/product. (Note the

case for addition is done for you to get you pointed in the right direction.)

? An < or = comparison evaluates its subexpressions and, assuming they both produce integers,

produces the mul461-bool b that is the result of comparing the two integer values.

? An and/or evaluates its subexpressions and, assuming they both produce booleans, produces the

mul461-bool b that is their and/or boolean operation result.

? A not evaluates its subexpression and, assuming it produces a boolean, produces the mul461-bool

b that is the logical negation of its subexpression result.

? An if evaluates its first expression to a value v1. If it is a boolean, then if it is mul461-bool #t,

then if evaluates to its second subexpression, else it evaluates its third subexpression. Only one

of e2 and e3 should be evaluated. Do not evaluate both e2 and e3.

? A let expression evaluates its first expression to a value v. Then it evaluates the second expression

to a value, in an environment extended to map the name in the let expression to v.

2. Expanding the Language: mul461 is a small language, but we can write Racket functions that act

like mul461 macros so that users of these functions feel like mul461 is larger. The Racket functions

produce mul461 expressions that could then be put inside larger mul461 expressions or passed to

eval-exp. In implementing these Racket functions, do not use closure (which is used only internally

in eval-exp). Also do not use eval-exp (we are creating a program, not running it).

(a) Write a Racket function makelet* that takes a Racket list of Racket pairs ’((s1 . e1) . . . (si

. ei)

. . . (sn . en)) and a final mul461 expression en+1. In each pair, assume si

is a Racket string and ei

is a mul461 expression. makelet* returns a mul461 expression whose value is en+1 evaluated in

an environment where each si

is a variable bound to the result of evaluating the corresponding ei

for 1 ≤ i ≤ n. The bindings are done sequentially, so that each ei

is evaluated in an environment

where s1 through si?1 have been previously bound to the values e1 through ei?1.

3. Using the Language: We can write mul461 expressions directly in Racket using the constructors

for the structs and (for convenience) the functions we wrote in the previous problem.

(a) Write a function makefactorial that gives a racket integer n, returns a mul461 expression that

is similar to n ? ((n ? 1) ? (n ? 2)... ? 1) using mul461 constructs. For example (makefactorial

3) should return this value:

(mul461-* (mul461-int 3) (mul461-* (mul461-int 2) (mul461-int 1))).

2

版权所有：留学生编程辅导网 2020 All Rights Reserved 联系方式：QQ:99515681 电子信箱：99515681@qq.com

免责声明：本站部分内容从网络整理而来，只供参考！如有版权问题可联系本站删除。