【CMPSC 461 求解】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:
- 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. - 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. - 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))).
推荐阅读
- java|网络编程懒人入门(一)(快速理解网络通信协议(上篇))
- java|编程必备基础 计算机组成原理+操作系统+计算机网络
- SWEN221 软件开发
- COSC 1285 算法求解
- IRDM 2020 任务定义
- CSC 3002 分析
- Java|社招和校招有什么不同(阿里美团等大厂 JAVA 社招面经分享)
- Webapp和后端交互检查测试
- 数据库开发|通过栗子来学习MySQL高级知识点(学习,复习,面试都可)