Language spec: For this last assignment, we'll use the following grammar for a small extension of JOE (from Assignment #5) called JOE+.
<JOE+> ::= <num>
| <id>
| {+ <JOE+> <JOE+>}
| {- <JOE+> <JOE+>}
| {* <JOE+> <JOE+>}
| {/ <JOE+> <JOE+>}
| {- <JOE+>}
| {= <JOE+> <JOE+>} ;; equality test
| {< <JOE+> <JOE+>} ;; less than test
| {with {<id> <JOE+>} <JOE+>} ;; using fun rewrite
| {if <JOE+> <JOE+> <JOE+>}
| {fun {<id>} <JOE+>}
| {refun {<id>} <JOE+>} ;; fun using call-by-refr
| {<JOE+> <JOE+>} ;; function app
| {set <id> <JOE+>} ;; variable assignment
| {seqn <JOE+> <JOE+> ...}
Goal: Do each of the following three tasks:
1. Modify seqn to permit an arbitrary number of sub-expressions
(as shown in the grammar), not
just two. They should be evaluated in left-to-right order.
The value of the seqn expression is the value of
the last sub-expression.
Provide a sample run of at least one program which uses this
expanded feature.
2. Modify the interpreter to evaluate addition from right to left instead of left-to-right. Construct a test case that yields different answers in the two cases and show sample runs of that test case evaluated in the original interpreter (left-to-right) and the modified interpreter (right-to-left).
3. Construct a test case that behaves differently if functions are defined using fun (call-by-value) or if the same function definitions are used with refun (call-by-reference). Supply sample runs of the two cases.