5 let inline toBool
b = if b then Node.TRUE else Node.FALSE
7 let inline twoNumberOp
(f
: int64
-> int64
-> Node) = function
8 | [Number(a
); Number(b)] -> f a
b
9 | [_
; _
] -> raise
<| Error.argMismatch
()
10 | _ -> raise
<| Error.wrongArity
()
12 let inline twoNodeOp
(f
: Node -> Node -> Node) = function
14 | _ -> raise
<| Error.wrongArity
()
16 let add = twoNumberOp
(fun a
b -> a
+ b |> Number)
17 let subtract = twoNumberOp
(fun a
b -> a
- b |> Number)
18 let multiply = twoNumberOp
(fun a
b -> a
* b |> Number)
19 let divide = twoNumberOp
(fun a
b -> a
/ b |> Number)
20 let lt = twoNodeOp
(fun a
b -> a
< b |> toBool
)
21 let le = twoNodeOp
(fun a
b -> a
<= b |> toBool
)
22 let ge = twoNodeOp
(fun a
b -> a
>= b |> toBool
)
23 let gt = twoNodeOp
(fun a
b -> a
> b |> toBool
)
24 let eq = twoNodeOp
(fun a
b -> a
= b |> toBool
)
26 let list nodes
= List(nodes
)
28 | [List(_)] -> Node.TRUE
30 | _ -> raise
<| Error.wrongArity
()
32 let isEmpty = function
33 | [List([])] -> Node.TRUE
34 | [Vector(seg
)] when seg
.Count <= 0 -> Node.TRUE
38 | [List(lst
)] -> lst
|> List.length
|> int64
|> Number
39 | [Vector(seg
)] -> seg
.Count |> int64
|> Number
41 | [_] -> raise
<| Error.argMismatch
()
42 | _ -> raise
<| Error.wrongArity
()
44 let pr_str nodes
= nodes
|> Printer.pr_str |> String
45 let str nodes
= nodes
|> Printer.str |> String
46 let prn nodes
= nodes
|> Printer.prn |> printfn
"%s"; Nil
47 let println nodes
= nodes
|> Printer.println |> printfn
"%s"; Nil
49 let read_str = function
51 match Reader.read_str s
with
53 | nodes -> List(Symbol("do")::nodes)
54 | [_] -> raise
<| Error.argMismatch
()
55 | _ -> raise
<| Error.wrongArity
()
58 | [String(s
)] -> System.IO.File.ReadAllText s |> String
59 | [_] -> raise
<| Error.argMismatch
()
60 | _ -> raise
<| Error.wrongArity
()
63 | [node
; List(lst
)] -> List(node
::lst
)
64 | [node
; Vector(seg
)] -> List(node
::(List.ofSeq seg
))
65 | [_; _] -> raise
<| Error.argMismatch
()
66 | _ -> raise
<| Error.wrongArity
()
69 let cons st
node = node::st
70 let accumNode acc
= function
71 | List(lst
) -> lst
|> List.fold
cons acc
72 | Vector(seg
) -> seg
|> Seq.fold
cons acc
73 | _ -> raise
<| Error.argMismatch
()
76 |> List.fold
accumNode []
81 | [List(lst
); Number(n
)] ->
82 let rec nth_list
n = function
83 | [] -> raise
<| Error.indexOutOfBounds
()
84 | h::_ when n = 0L -> h
85 | _::t
-> nth_list
(n - 1L) t
87 | [Vector(seg
); Number(n)] ->
88 if n < 0L || n >= int64
(seg
.Count) then
89 raise
<| Error.indexOutOfBounds
()
92 | [_; _] -> raise
<| Error.argMismatch
()
93 | _ -> raise
<| Error.wrongArity
()
96 | [List([])] -> Node.NIL
98 | [Vector(seg
)] when seg
.Count > 0 -> seg
.Array.[0]
99 | [Vector(_)] -> Node.NIL
101 | [_] -> raise
<| Error.argMismatch
()
102 | _ -> raise
<| Error.wrongArity
()
105 | [List([]) as lst] -> lst
106 | [List(_::t
)] -> List(t
)
107 | [Vector(seg
)] when seg
.Count < 2 -> Node.EmptyLIST
108 | [Vector(seg
)] -> seg
|> Seq.skip
1 |> List.ofSeq
|> List
109 | [_] -> raise
<| Error.argMismatch
()
110 | _ -> raise
<| Error.wrongArity
()
113 | [node] -> raise
<| Error.MalError(node)
114 | _ -> raise
<| Error.wrongArity
()
117 | [BuiltInFunc(_, f
); Node.Seq seq
]
118 | [Func(_, f
, _, _, _); Node.Seq seq
] ->
119 seq
|> Seq.map (fun node -> f
[node]) |> List.ofSeq
|> List
120 | [_; _] -> raise
<| Error.argMismatch
()
121 | _ -> raise
<| Error.wrongArity
()
124 | BuiltInFunc(_, f
)::rest
125 | Func(_, f
, _, _, _)::rest ->
126 let rec getArgsAndCall
acc = function
127 | [] -> raise
<| Error.wrongArity
()
129 seq
|> Seq.fold
(fun acc node -> node::acc) acc |> List.rev
|> f
130 | [_] -> raise
<| Error.argMismatch
()
131 | h::rest -> getArgsAndCall
(h::acc) rest
132 getArgsAndCall
[] rest
133 | _::_ -> raise
<| Error.argMismatch
()
134 | [] -> raise
<| Error.wrongArity
()
136 let isConst cmp
= function
137 | [node] -> if node = cmp
then Node.TRUE else Node.FALSE
138 | _ -> raise
<| Error.wrongArity
()
140 let isSymbol = function
141 | [Symbol(_)] -> Node.TRUE
143 | _ -> raise
<| Error.wrongArity
()