caseとlet*
case syntaxとlet* syntaxに対応した。
パーサにparseLetstarとparseCaseを追加した。
対話環境でテストしてみる。
# let e1 = parse "(case (* 2 3) ((2 3 5 7) 'prime) ((1 4 6 8 9) 'composit))";; val e1 : Parser.exp = IfExp (ApplyExp (VarExp "memv", [ApplyExp (VarExp "*", [SelfEvalExp (Int 2); SelfEvalExp (Int 3)]); QuoteExp (List [Int 2; Int 3; Int 5; Int 7])]), QuoteExp (Id "prime"), IfExp (ApplyExp (VarExp "memv", [ApplyExp (VarExp "*", [SelfEvalExp (Int 2); SelfEvalExp (Int 3)]); QuoteExp (List [Int 1; Int 4; Int 6; Int 8; Int 9])]), QuoteExp (Id "composit"), UnspecifiedExp)) # evalExp env e1;; - : Parser.exp Valtype.valtype = SymbolV "composit" # let e2 = parse "(let* ((x 7) (z (+ x 3))) (* z x))";; val e2 : Parser.exp = ApplyExp (LambdaExp (["x"], Fixed, ApplyExp (LambdaExp (["z"], Fixed, ApplyExp (LambdaExp ([], Fixed, ApplyExp (VarExp "*", [VarExp "z"; VarExp "x"])), [])), [ApplyExp (VarExp "+", [VarExp "x"; SelfEvalExp (Int 3)])])), [SelfEvalExp (Int 7)]) # evalExp env e2;; - : Parser.exp Valtype.valtype = IntV 70
展開していて結果もそれなりであるが、caseでは (* 2 3) が何回も評価されている。r7rsの else => にも未対応。
伝統的なマクロが動くのでschemeで書いてもいいのだが、外部ファイルを読み込むデザインは保留しているので、当面はパーサにOCamlでハードコードする。