|
⇒ (< 5 4) 0 ⇒ (if (< (+ 3 5) (- 9 18)) v x) 10 ⇒ (+ (= 3 3) 5) 6全体としての文法は,
<プログラム> | ::= | <式> |
<式> | ::= | … |
| | (if <式1> <式2> <式3>) | |
<プリミティブ> | ::= | … | = | < |
|
また,core.ml は,プリミティブを追加したのだから, Syntax.prim 型に関わる部分,つまり,apply_prim を変更すればよい.syntax.ml:
type prim = Plus | Minus | Mul | Add1 | Sub1 | Eq | Lt
parser.mly:
... %token EQ LT ... PrimOp: ... | EQ { Eq } | LT { Lt }
lexer.mll:
let reservedWords = [ ... ("=", Parser.EQ); ("<", Parser.LT); ] rule main = parse ... | ['a'-'z'] ['a'-'z' '_' '0'-'9' '']* | ['+' '-' '*' '=' '<'] ...
core.ml:
let apply_prim p args = match p, args with ... | (Eq, [IntV i; IntV j]) -> if i = j then IntV 1 else IntV 0 | (Eq, _) -> failwith "Arity mismatch: =" | (Lt, [IntV i; IntV j]) -> if i < j then IntV 1 else IntV 0 | (Lt, _) -> failwith "Arity mismatch: <"
Figure 7: 比較プリミティブの追加
|
syntax.ml:
type exp = ... | If of exp * exp * exp
parser.mly:
... %token IF ... Exp : ... | LPAREN IF Exp Exp Exp RPAREN { If ($3, $4, $5) }
lexer.mll:
let reservedWords = [ ... ("if", Parser.IF); ]
core.ml
let rec eval_exp env = function ... | If (e1, e2, e3) -> let IntV test = eval_exp env e1 in if test <> 0 then eval_exp env e2 else eval_exp env e3
Figure 8: if式の追加
Expressed Value | = | 整数 (…, -2, -1, 0, 1, 2, 3, …) + 真偽値 (true, false) |
Denoted Value | = | 整数 + 真偽値 |
type exval = IntV of int | BoolV of boolまた,true, false はキーワードもしくは,大域環境に束縛された変数と して導入する.以下は,実行例である.
⇒ true true ⇒ (> 3 5) false ⇒ (if (> 5 (+ 2 4)) x i) 1(ヒント: この問題は,mini Scheme4までやってから戻るとやりやすい)