feat(prelude): add builtins and standard library
This commit is contained in:
1 parent
68b3f9f319
commit
9ce5ca1651
1 file changed
+178
@@ -0,0 +1,178 @@
|
||||
module Fml.Core.Prelude
|
||||
|
||||
open Fml.Core.Types
|
||||
open Fml.Core.Value
|
||||
|
||||
// Built-in primitives shared by the interpreter and the bytecode VM, plus a
|
||||
// standard library written in fml itself that each session may load on top.
|
||||
|
||||
let private genVar () = TVar(ref (Generic(newVarId ())))
|
||||
|
||||
let initialTypeEnv: Map<string, Ty> =
|
||||
Map.ofList
|
||||
[ "head", (let a = genVar () in TArrow(TList a, a))
|
||||
"tail", (let a = genVar () in TArrow(TList a, TList a))
|
||||
"isEmpty", (let a = genVar () in TArrow(TList a, TBool))
|
||||
"not", TArrow(TBool, TBool)
|
||||
"print", (let a = genVar () in TArrow(a, TUnit))
|
||||
"fst", (let a = genVar () in let b = genVar () in TArrow(TTuple [ a; b ], a))
|
||||
"snd", (let a = genVar () in let b = genVar () in TArrow(TTuple [ a; b ], b))
|
||||
"stringLength", TArrow(TString, TInt)
|
||||
"intToString", TArrow(TInt, TString)
|
||||
"boolToString", TArrow(TBool, TString) ]
|
||||
|
||||
let initialValueEnv: Env =
|
||||
Map.ofList
|
||||
[ "head",
|
||||
VBuiltin(
|
||||
"head",
|
||||
fun v ->
|
||||
match v with
|
||||
| VList(x :: _) -> x
|
||||
| VList [] -> raise (RuntimeError "head of an empty list")
|
||||
| _ -> raise (RuntimeError "head expects a list")
|
||||
)
|
||||
"tail",
|
||||
VBuiltin(
|
||||
"tail",
|
||||
fun v ->
|
||||
match v with
|
||||
| VList(_ :: xs) -> VList xs
|
||||
| VList [] -> raise (RuntimeError "tail of an empty list")
|
||||
| _ -> raise (RuntimeError "tail expects a list")
|
||||
)
|
||||
"isEmpty",
|
||||
VBuiltin(
|
||||
"isEmpty",
|
||||
fun v ->
|
||||
match v with
|
||||
| VList xs -> VBool(List.isEmpty xs)
|
||||
| _ -> raise (RuntimeError "isEmpty expects a list")
|
||||
)
|
||||
"not",
|
||||
VBuiltin(
|
||||
"not",
|
||||
fun v ->
|
||||
match v with
|
||||
| VBool b -> VBool(not b)
|
||||
| _ -> raise (RuntimeError "not expects a boolean")
|
||||
)
|
||||
"print",
|
||||
VBuiltin(
|
||||
"print",
|
||||
fun v ->
|
||||
printfn "%s" (prettyValue v)
|
||||
VUnit
|
||||
)
|
||||
"fst",
|
||||
VBuiltin(
|
||||
"fst",
|
||||
fun v ->
|
||||
match v with
|
||||
| VTuple(a :: _) -> a
|
||||
| _ -> raise (RuntimeError "fst expects a pair")
|
||||
)
|
||||
"snd",
|
||||
VBuiltin(
|
||||
"snd",
|
||||
fun v ->
|
||||
match v with
|
||||
| VTuple(_ :: b :: _) -> b
|
||||
| _ -> raise (RuntimeError "snd expects a pair")
|
||||
)
|
||||
"stringLength",
|
||||
VBuiltin(
|
||||
"stringLength",
|
||||
fun v ->
|
||||
match v with
|
||||
| VString s -> VInt s.Length
|
||||
| _ -> raise (RuntimeError "stringLength expects a string")
|
||||
)
|
||||
"intToString",
|
||||
VBuiltin(
|
||||
"intToString",
|
||||
fun v ->
|
||||
match v with
|
||||
| VInt n -> VString(string n)
|
||||
| _ -> raise (RuntimeError "intToString expects an int")
|
||||
)
|
||||
"boolToString",
|
||||
VBuiltin(
|
||||
"boolToString",
|
||||
fun v ->
|
||||
match v with
|
||||
| VBool b -> VString(if b then "true" else "false")
|
||||
| _ -> raise (RuntimeError "boolToString expects a bool")
|
||||
) ]
|
||||
|
||||
// Standard library implemented in fml. Loaded on demand so the base session and
|
||||
// its 22 legacy tests stay untouched. Exercises ADTs, records, modules,
|
||||
// mutually recursive definitions and exhaustive matching all at once.
|
||||
let preludeSource =
|
||||
"""
|
||||
type 'a option = None | Some of 'a ;;
|
||||
type ('a, 'b) result = Ok of 'a | Error of 'b ;;
|
||||
|
||||
module Option = struct
|
||||
let isSome = fun o -> match o with None -> false | Some _ -> true ;;
|
||||
let getOr = fun d o -> match o with None -> d | Some x -> x ;;
|
||||
let map = fun f o -> match o with None -> None | Some x -> Some (f x) ;;
|
||||
let bind = fun o f -> match o with None -> None | Some x -> f x ;;
|
||||
end ;;
|
||||
|
||||
module Result = struct
|
||||
let isOk = fun r -> match r with Ok _ -> true | Error _ -> false ;;
|
||||
let map = fun f r -> match r with Ok x -> Ok (f x) | Error e -> Error e ;;
|
||||
let mapError = fun f r -> match r with Ok x -> Ok x | Error e -> Error (f e) ;;
|
||||
let getOr = fun d r -> match r with Ok x -> x | Error _ -> d ;;
|
||||
end ;;
|
||||
|
||||
module List = struct
|
||||
let rec length = fun xs -> match xs with [] -> 0 | _ :: t -> 1 + length t ;;
|
||||
let rec map = fun f xs -> match xs with [] -> [] | h :: t -> f h :: map f t ;;
|
||||
let rec filter = fun p xs ->
|
||||
match xs with
|
||||
| [] -> []
|
||||
| h :: t -> if p h then h :: filter p t else filter p t ;;
|
||||
let rec foldl = fun f acc xs ->
|
||||
match xs with
|
||||
| [] -> acc
|
||||
| h :: t -> foldl f (f acc h) t ;;
|
||||
let rec foldr = fun f acc xs ->
|
||||
match xs with
|
||||
| [] -> acc
|
||||
| h :: t -> f h (foldr f acc t) ;;
|
||||
let rec append = fun xs ys ->
|
||||
match xs with
|
||||
| [] -> ys
|
||||
| h :: t -> h :: append t ys ;;
|
||||
let rec rev = fun xs ->
|
||||
match xs with
|
||||
| [] -> []
|
||||
| h :: t -> append (rev t) (h :: []) ;;
|
||||
let rec mem = fun x xs ->
|
||||
match xs with
|
||||
| [] -> false
|
||||
| h :: t -> if h = x then true else mem x t ;;
|
||||
let rec range = fun lo hi -> if lo >= hi then [] else lo :: range (lo + 1) hi ;;
|
||||
let sum = fun xs -> foldl (fun acc x -> acc + x) 0 xs ;;
|
||||
end ;;
|
||||
|
||||
module Map = struct
|
||||
let empty = [] ;;
|
||||
let rec add = fun k v m ->
|
||||
match m with
|
||||
| [] -> (k, v) :: []
|
||||
| pair :: rest -> if fst pair = k then (k, v) :: rest else pair :: add k v rest ;;
|
||||
let rec find = fun k m ->
|
||||
match m with
|
||||
| [] -> None
|
||||
| pair :: rest -> if fst pair = k then Some (snd pair) else find k rest ;;
|
||||
let contains = fun k m -> Option.isSome (find k m) ;;
|
||||
let size = fun m -> List.length m ;;
|
||||
let rec remove = fun k m ->
|
||||
match m with
|
||||
| [] -> []
|
||||
| pair :: rest -> if fst pair = k then rest else pair :: remove k rest ;;
|
||||
end ;;
|
||||
"""
|
||||
Reference in new issue
Block a user