5 let errArity () = EvalError("arity: wrong number of arguments")
6 let errArgMismatch () = EvalError("argument mismatch")
8 let inline toBool
b = if b then Node.TRUE else Node.FALSE
10 let inline twoNumberOp
(f
: int64
-> int64
-> Node) = function
11 | [Number(a
); Number(b)] -> f a
b
12 | [_
; _
] -> raise
<| errArgMismatch ()
13 | _ -> raise
<| errArity ()
15 let inline twoNodeOp
(f
: Node -> Node -> Node) = function
17 | _ -> raise
<| errArity ()
19 let add = twoNumberOp
(fun a
b -> a
+ b |> Number)
20 let subtract = twoNumberOp
(fun a
b -> a
- b |> Number)
21 let multiply = twoNumberOp
(fun a
b -> a
* b |> Number)
22 let divide = twoNumberOp
(fun a
b -> a
/ b |> Number)
23 let lt = twoNodeOp
(fun a
b -> a
< b |> toBool
)
24 let le = twoNodeOp
(fun a
b -> a
<= b |> toBool
)
25 let ge = twoNodeOp
(fun a
b -> a
>= b |> toBool
)
26 let gt = twoNodeOp
(fun a
b -> a
> b |> toBool
)
27 let eq = twoNodeOp
(fun a
b -> a
= b |> toBool
)
29 let list nodes
= List(nodes
)
31 | [List(_)] -> Node.TRUE
33 | _ -> raise
<| errArity ()
35 let isEmpty = function
36 | [List([])] -> Node.TRUE
37 | [Vector(seg
)] when seg
.Count <= 0 -> Node.TRUE
41 | [List(lst
)] -> lst
|> List.length
|> int64
|> Number
42 | [Vector(seg
)] -> seg
.Count |> int64
|> Number
44 | [_] -> raise
<| errArgMismatch ()
45 | _ -> raise
<| errArity ()
47 let pr_str nodes
= nodes
|> Printer.pr_str |> String
48 let str nodes
= nodes
|> Printer.str |> String
49 let prn nodes
= nodes
|> Printer.prn |> printfn
"%s"; Nil
50 let println nodes
= nodes
|> Printer.println |> printfn
"%s"; Nil
52 let read_str = function
54 match Reader.read_str s
with
56 | nodes -> List(Symbol("do")::nodes)
57 | [_] -> raise
<| errArgMismatch ()
58 | _ -> raise
<| errArity ()
61 | [String(s
)] -> System.IO.File.ReadAllText s |> String
62 | [_] -> raise
<| errArgMismatch ()
63 | _ -> raise
<| errArity ()
66 | [node
; List(lst
)] -> List(node
::lst
)
67 | [node
; Vector(seg
)] -> List(node
::(List.ofSeq seg
))
68 | [_; _] -> raise
<| errArgMismatch ()
69 | _ -> raise
<| errArity ()
72 let cons st
node = node::st
73 let accumNode acc
= function
74 | List(lst
) -> lst
|> List.fold
cons acc
75 | Vector(seg
) -> seg
|> Seq.fold
cons acc
76 | _ -> raise
<| errArgMismatch ()
79 |> List.fold
accumNode []