ntha-0.1.0: src/Prologue.hs
module Prologue where
import Ast
import Type
import Value
import State
import TypeScope
import Debug.Trace
import qualified Data.Map as M
mkTCon :: TypeConstructor -> Expr -> Type
mkTCon (TypeConstructor name types) (EDataDecl _ t _ _) = TCon name types t
mkTCon _ _ = error "not support"
assumptions :: Infer TypeScope
assumptions = do
tvarA <- makeVariable
tvarB <- makeVariable
let name = "List"
let vars = [tvarA]
let dataType = TOper name vars
let consConstructor = TypeConstructor "Cons" [tvarA, TOper "List" [tvarA]]
let nilConstructor = TypeConstructor "Nil" []
let listData = EDataDecl "List" dataType vars [consConstructor, nilConstructor]
return $ TypeScope Nothing $ M.fromList [("+", functionT [intT, intT] intT),
("-", functionT [intT, intT] intT),
("*", functionT [intT, intT] intT),
("/", functionT [intT, intT] intT),
("%", functionT [intT, intT] intT),
("=", functionT [tvarB, tvarB] boolT),
("≠", functionT [tvarB, tvarB] boolT),
("<", functionT [intT, intT] boolT),
(">", functionT [intT, intT] boolT),
("≤", functionT [intT, intT] boolT),
("≥", functionT [intT, intT] boolT),
("∧", functionT [boolT, boolT] boolT),
("∨", functionT [boolT, boolT] boolT),
("¬", functionT [boolT] boolT),
("int2str", functionT [intT] strT),
("bool2str", functionT [boolT] strT),
("asserteq", functionT [tvarB, tvarB] unitT),
("print", functionT [strT] unitT),
("error", functionT [strT] tvarB),
("reverse", functionT [listT tvarB] (listT tvarB)),
("list?", functionT [tvarB] boolT),
("string?", functionT [tvarB] boolT),
("Cons", mkTCon consConstructor listData),
("Nil", mkTCon nilConstructor listData),
("inc", functionT [intT] intT),
("dec", functionT [intT] intT)]
builtins :: ValueScope
builtins = ValueScope Nothing $ M.fromList [("+", binFn (\(VNum a) (VNum b) -> (VNum $ a + b))),
("-", binFn (\(VNum a) (VNum b) -> (VNum $ a - b))),
("*", binFn (\(VNum a) (VNum b) -> (VNum $ a * b))),
("/", binFn (\(VNum a) (VNum b) -> (VNum $ a `div` b))),
("%", binFn (\(VNum a) (VNum b) -> (VNum $ a `mod` b))),
("=", binFn (\a b -> VBool $ a == b)),
("≠", binFn (\a b -> VBool $ a /= b)),
("<", binFn (\a b -> VBool $ a < b)),
(">", binFn (\a b -> VBool $ a > b)),
("≤", binFn (\a b -> VBool $ a <= b)),
("≥", binFn (\a b -> VBool $ a >= b)),
("∧", binFn (\(VBool a) (VBool b) -> VBool $ a && b)),
("∨", binFn (\(VBool a) (VBool b) -> VBool $ a || b)),
("¬", Fn (\(VBool b) _ -> VBool $ not b)),
("int2str", Fn (\(VNum n) _ -> strV $ show n)),
("bool2str", Fn (\(VBool b) _ -> strV $ show b)),
("asserteq", binFn (\a b -> if a == b
then VUnit
else error $ show a ++ " and " ++ show b ++ " not equal.")),
("print", Fn (\v _ -> trace (desugerStrV v) VUnit)),
("error", Fn (\v _ -> error $ desugerStrV v)),
("reverse", Fn (\v _ -> reverseList v)),
("list?", Fn (\v _ -> case v of
Adt "Cons" _ -> VBool True
_ -> VBool False)),
("string?", Fn (\v _ -> VBool $ isString v)),
("Cons", binFn (\a b -> cons a b)),
("Nil", nil),
("inc", Fn (\(VNum n) _ -> VNum $ n + 1)),
("dec", Fn (\(VNum n) _ -> VNum $ n - 1))]