|
|
<プログラム> | ::= | … | let <識別子> = <式> ;; |
<式> | ::= | … |
| | let <識別子> = <式1> in <式2> |
syntax.ml:
type exp = ... | LetExp of id * exp * exp type program = Exp of exp | Decl of id * exp
parser.mly:
%token LET IN EQ toplevel : Expr SEMISEMI { Exp $1 } | LET ID EQ Expr SEMISEMI { Decl ($2, $4) } Expr : IfExpr { $1 } | LetExpr { $1 } | LTExpr { $1 } LetExpr : LET ID EQ Expr IN Expr { LetExp ($2, $4, $6) }
lexer.mll:
let reservedWords = [ ... ("in", Parser.IN); ("let", Parser.LET); ] ... | "<" Parser.LT | "=" Parser.EQ
eval.ml:
let rec eval_exp env = function ... | LetExp (id, exp1, exp2) -> let value = eval_exp env exp1 in eval_exp (Environment.extend id value env) exp2 let eval_decl env = function Exp e -> let v = eval_exp env e in ("-", env, v) | Decl (id, e) -> let v = eval_exp env e in (id, Environment.extend id v env, v)
Figure 7: 局所定義
# let x = 1 let y = x + 1;; val x = 1 val y = 2
let x = 100 and y = x in x+yの実行結果は 200 ではなく,(xが大域環境で 10に束縛され ているので) 110 である.