ref: b2beb0311ec840da0eafa95888d816af0353436e
dir: /core.ml/
module T = Types.Types
let base = Env.make None
let number_compare t f =
Types.proc (function
| [T.Number a; T.Number b] -> t (f a.value b.value)
| _ -> raise (Invalid_argument "not a number") )
let simple_compare t f =
Types.proc (function [T.Number a; T.Number b] -> t (f a b) | _ -> raise (Invalid_argument "incomparable"))
let mk_num x = Types.number x
let mk_bool x = T.Bool x
let seq = function T.List {T.value= xs; meta= _} -> xs | T.Vector {T.value= xs; meta= _} -> xs | _ -> []
(* this is 'assoc' from mal, but it's not what assoc is in scheme *)
let rec link = function
| c :: k :: v :: (_ :: _ as xs) -> link (link [c; k; v] :: xs)
| [T.Nil; k; v] -> Types.map (Types.M9map.add k v Types.M9map.empty)
| [T.Map {T.value= m; T.meta}; k; v] -> T.Map {T.value= Types.M9map.add k v m; T.meta}
| _ -> T.Nil
let init env =
Env.set env (Types.symbol "raise") (Types.proc (function [ast] -> raise (Types.M9exn ast) | _ -> T.Nil)) ;
Env.set env (Types.symbol "*arguments*")
(Types.list
( if Array.length Sys.argv > 1 then List.map (fun x -> T.String x) (List.tl (List.tl (Array.to_list Sys.argv)))
else [] ) ) ;
Env.set env (Types.symbol "+") (number_compare mk_num ( +. )) ;
Env.set env (Types.symbol "-") (number_compare mk_num ( -. )) ;
Env.set env (Types.symbol "*") (number_compare mk_num ( *. )) ;
Env.set env (Types.symbol "/") (number_compare mk_num ( /. )) ;
Env.set env (Types.symbol "<") (simple_compare mk_bool ( < )) ;
Env.set env (Types.symbol "<=") (simple_compare mk_bool ( <= )) ;
Env.set env (Types.symbol ">") (simple_compare mk_bool ( > )) ;
Env.set env (Types.symbol ">=") (simple_compare mk_bool ( >= )) ;
(* Env.set
* env
* (Types.symbol "proc?")
* (Types.proc (function
* | [ T.Proc { T.meta = T.Map { T.value = meta } } ] ->
* mk_bool
* (not
* (Types.M9map.mem kw_macro meta
* && Types.to_bool (Types.M9map.find kw_macro meta)))
* | [ T.Proc _ ] -> T.Bool true
* | _ -> T.Bool false)); *)
Env.set env (Types.symbol "number?") (Types.proc (function [T.Number _] -> T.Bool true | _ -> T.Bool false)) ;
Env.set env (Types.symbol "list") (Types.proc (function xs -> Types.list xs)) ;
Env.set env (Types.symbol "list?") (Types.proc (function [T.List _] -> T.Bool true | _ -> T.Bool false)) ;
Env.set env (Types.symbol "vector") (Types.proc (function xs -> Types.vector xs)) ;
Env.set env (Types.symbol "vector?") (Types.proc (function [T.Vector _] -> T.Bool true | _ -> T.Bool false)) ;
Env.set env (Types.symbol "empty?")
(Types.proc (function
| [T.List {T.value= []; meta= _}] -> T.Bool true
| [T.Vector {T.value= []; meta= _}] -> T.Bool true
| _ -> T.Bool false ) ) ;
Env.set env (Types.symbol "count")
(Types.proc (function
| [T.List {T.value= xs; meta= _}] | [T.Vector {T.value= xs; meta= _}] ->
Types.number (float_of_int (List.length xs))
| _ -> Types.number 0. ) ) ;
Env.set env (Types.symbol "display")
(Types.proc (function xs ->
print_string (Printer.stringify xs false) ;
T.Unspecified ) ) ;
Env.set env (Types.symbol "string")
(Types.proc (function xs -> T.String (String.concat "" (List.map (fun s -> Printer.print s false) xs)))) ;
Env.set env (Types.symbol "read-string") (Types.proc (function [T.String x] -> Reader.read x | _ -> T.Nil)) ;
Env.set env (Types.symbol "slurp") (Types.proc (function [T.String x] -> T.String (Reader.slurp x) | _ -> T.Nil)) ;
Env.set env (Types.symbol "cons") (Types.proc (function [x; xs] -> Types.list [x; xs] | _ -> T.Nil)) ;
Env.set env (Types.symbol "concat")
(Types.proc
(let rec concat = function
| x :: y :: more -> concat (Types.list (seq x @ seq y) :: more)
| [(T.List _ as x)] -> x
| [x] -> Types.list (seq x)
| [] -> Types.list [] in
concat ) )