mirror of
https://github.com/kanaka/mal.git
synced 2024-11-10 12:47:45 +03:00
51 lines
1.7 KiB
Forth
51 lines
1.7 KiB
Forth
module Core
|
|
|
|
open Types
|
|
|
|
let errArity () = EvalError("arity: wrong number of arguments")
|
|
let errArgMismatch () = EvalError("argument mismatch")
|
|
|
|
let inline toBool b = if b then TRUE else FALSE
|
|
|
|
let inline twoNumberOp (f : int64 -> int64 -> Node) = function
|
|
| [Number(a); Number(b)] -> f a b
|
|
| [_; _] -> raise <| errArgMismatch ()
|
|
| _ -> raise <| errArity ()
|
|
|
|
let inline twoNodeOp (f : Node -> Node -> Node) = function
|
|
| [a; b] -> f a b
|
|
| _ -> raise <| errArity ()
|
|
|
|
let add = twoNumberOp (fun a b -> a + b |> Number)
|
|
let subtract = twoNumberOp (fun a b -> a - b |> Number)
|
|
let multiply = twoNumberOp (fun a b -> a * b |> Number)
|
|
let divide = twoNumberOp (fun a b -> a / b |> Number)
|
|
let lt = twoNodeOp (fun a b -> a < b |> toBool)
|
|
let le = twoNodeOp (fun a b -> a <= b |> toBool)
|
|
let ge = twoNodeOp (fun a b -> a >= b |> toBool)
|
|
let gt = twoNodeOp (fun a b -> a > b |> toBool)
|
|
let eq = twoNodeOp (fun a b -> a = b |> toBool)
|
|
|
|
let list nodes = List(nodes)
|
|
let isList = function
|
|
| [List(_)] -> TRUE
|
|
| [_] -> FALSE
|
|
| _ -> raise <| errArity ()
|
|
|
|
let isEmpty = function
|
|
| [List([])]
|
|
| [Vector([||])] -> TRUE
|
|
| _ -> FALSE
|
|
|
|
let count = function
|
|
| [List(a)] -> a |> List.fold (fun cnt _ -> cnt + 1L) 0L |> Number
|
|
| [Vector(v)] -> v.Length |> int64 |> Number
|
|
| [Nil] -> ZERO
|
|
| [_] -> raise <| errArgMismatch ()
|
|
| _ -> raise <| errArity ()
|
|
|
|
let pr_str nodes = nodes |> Printer.pr_str |> String
|
|
let str nodes = nodes |> Printer.str |> String
|
|
let prn nodes = nodes |> Printer.prn |> printfn "%s"; Nil
|
|
let println nodes = nodes |> Printer.println |> printfn "%s"; Nil
|