![]() |
![]() |
|
Note: Download the racket files, and then choose Open… from DrRacket. Do not copy/paste into an empty DrRacket window, since that window is probably using a student-language, and some of the files below use full racket.For fun, you can run the interactive interpreter, H0-repl.rkt.
Java records: Remember: records are just classes where you don't have to declare the constructor, nor override .equals or .hashCode. All fields are immutable and have a public getter, though we won't need those.
<Expr> → <Num> | <Paren> | <BinOp> | <IfZero> <Paren> → shake <Expr> bake Interpretation: a parenthesized expression <BinOp> → add <Expr>1 to <Expr>2 Interpretation: addition <BinOp> → skim <Expr>1 off <Expr>2 Interpretation: subtract <Expr>1 from <Expr>2 (note the order!) <BinOp> → scale <Expr>1 to serve <Expr>2 Interpretation: multiplication <IfZero> → sample <Expr>1; add <Expr>2 to taste or use <Expr>3 instead Interpretation: if <Expr>1 is 0 (within 1e-6), eval to <Expr>2, else <Expr>3.H0:
<BinOp> → chop <Expr>1 into <Expr>2 Interpretation: “remainder”, except works for negative and fractional amounts. See H2.html for details. <Expr> → … | <IfLT+> Interpretation: “if less-than” <IfLT+> → if <Expr>1 not <Expr>2 enough, add <Expr>3 Interpretation: if <Expr>1 is < <Expr>2, result is <Expr>1 + <Expr>3 else <Expr>1.H1: see H2.html for details
<Expr> → … | <Id> | <LetExpr> Interpretation: identifier; let <LetExpr> → substitute <Id> with <Expr>0 in <Expr>1 Interpretation: bind Id to result of <Expr>0 (the right-hand-side); then eval <Expr>1 (the body) w/ that bindingH2: see H2.html for details
<Expr> → … | <FuncExpr> | <FuncApplyExpr> <FuncExpr> → recipe using <Id>: <Expr> Interpretation: a function-value, with parameter <Id> and body-<Expr>. <FuncApplyExpr> → use leftover <Expr>0 in <Expr>1 Interpretation: Apply a function (<Expr>1) to an argument (<Expr>0). Note the order.H4: see H4.html for details
<Num> is any numeric literal
(as written in either Java or Racket, your choice1).
We'll assume that <Id>s are not one of our H0 reserved words
(like skim
— i.e. a terminal in the above grammar);
you don't need to check/enforce that in your code.
Some similar(??) languages: Implementing one's own language (including let-expressions and functions) is a fairly standard exercise. For example, see Brown University's Programming Languages and Interpretation (Shriram Krishnamurthi), and Virginia Tech's OpenDSA Programming Languages textbook. Feel free to skim or read those books, esp. if wanting a different explanation from the notes in this class & its assignments.
Some similar(??) languages:
- emojicode
- Arnold[Schwarzenegger]C
- Genesis, in Old Hebrew
Once we've talked in class about internal-representation (and given examples of the W programs and corresponding internal-data), then we can discuss the provided-implementation, including recursive-descent parsing:
2018 version: The videos below are based on 2018fall's language, T0. So details of the syntax are different than this semester, and some statements might have different semantics, but overall the content is extremely similar to this semester's language.
todo-ibarland: Post the 2021-spring Y0-java/ upload version that uses lambda in BinOp#eval?
Note: Parsing H0 is particularly easy because each expression-type's leading-token lets us know exactly what to expect, removing the need for look-ahead, backtracking, or cleverer algorithms.
Similarly, if using Java, the semantics of H0's arithmetic will be similar to IEEE floating point arithmetic (rather than perfectly-correct arithmetic).
Don't confuse H0's class Num (which extends Expr) with the existing java.lang.Number, which doesn't extend Expr.
↩This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |