![]() |
![]() |
|
Due
30 (Fri.) at start of class
In addition, due
Note that X1 is “add code that is extremely similar to what already exists”, but X2 is not at all rote: it requires a solid understanding of the parse-tree representation and how the functions work.
Over the course of several homeworks, we'll implement a “tower” of languages (X0, X1, …, X6) each language incorporating more features than the previous. X0 is provided for you.
Deliverables:
(15pts) Implement X1 in racket and in Java, both.
X1 is just like X0, but with two additional
types of expressions:
Op ::= … | mod Interpretation: “remainder”; see A.iii for details Expr ::= … | IfPos IfPos ::= if+ Expr thn Expr els Expr ; Interpretation: if 1st Expr evals to a positive |
update
the remainder after dividingIn particular, the result should never be positive if y<0. Notice that this is slightly different behavior than either Java's built-inx byy , where the result is always between 0 (inclusive) and y (exclusive)1
Note that you are already provided sufficient test cases for
update
first evaluate justFor example,Expr0 to get value v0; if v0 is positive, then evaluateExpr1 and return its value; otherwise evaluateExpr2 and return that value.
You must make your own test cases for IfPoss;
include at least two as-simple-as-possible tests, and two tests with more deeply nested
(25pts) Implement X2 in either racket or Java (your choice).
X2 adds identifiers to X1:
Expr ::= … | Id | LetExpr LetExpr ::= let Id <- Expr in Expr2 |
Update your three methods
eval 'ing an identifier simply throws anerror .
You don't need test cases for
<will be read as one token, and
-as second (both racket and Java).
In order to write
- Evaluate
E0 ; let's call the result v0.- Then, substitute v0 for all occurrences of
Id inside the treeE1 ; name the result of the substitution E′.- Evaluate E′, and return that result.
For example:
Observe that when evaluating a (legal) X2 program,
Hint: Substituting a variable with a value in an syntax-tree is essentially the same as replacing every occurrence of one name with another in ananc-tree . (The only difference is that ananc-tree had only twocond -branches, whileExpr has around five, though the code for most of those are very similar.)
(Note: you must do substitution in the parse tree; no credit given for string-substitution 6.)
Hint: Your code will correspond almost word-for-word to the semantics given above.
tl;dr: skip to the code-text below and use either (a) or (b) when writing your Java code for parsing IfPos's.
When parsing the token if+, there is a gotcha in using
However,
In
if (UtilIan.hasNextSplittingBy( s, IfPos.START_TOKEN, PUNCTUATION ) |
\+, and to get a backslash into a string in Java I need
"\\".
ML-like: | let x = 2+3 in x*9 end; |
lisp-like: | (let {[x (+ 2 3)]} (* x 9)) |
lisp-like, simplified: | (let x (+ 2 3) (* x 9)) |
C~-like: | using (var x = 2+3) { return x*9; } |
javascript-like: | var x = 2+3; return x*9; |
Java-like: | { int x = 2+3; return x*9; } |
Haskell-like: | * x 9 \n where x = + 2 3 \n |
Note that you can (and should) test and write a “substitute” function w/o
worrying about the exact syntax of a
eval(parse!("let x <- 5 in ~x sub 3!")) = eval(parse!("~5 sub 3!")) = eval(parse!("2")) |
This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |