macro_rules! ty {
(Int) => {
Type::Int
};
(Bool) => {
Type::Bool
};
(String) => {
Type::String
};
(Float) => {
Type::Float
};
(Symbol) => {
Type::Symbol
};
(Channel) => {
Type::Channel
};
(T) => {
Type::Var("T".to_string())
};
(U) => {
Type::Var("U".to_string())
};
(V) => {
Type::Var("V".to_string())
};
(W) => {
Type::Var("W".to_string())
};
(K) => {
Type::Var("K".to_string())
};
(M) => {
Type::Var("M".to_string())
};
(Q) => {
Type::Var("Q".to_string())
};
(T1) => {
Type::Var("T1".to_string())
};
(T2) => {
Type::Var("T2".to_string())
};
(T3) => {
Type::Var("T3".to_string())
};
(T4) => {
Type::Var("T4".to_string())
};
(V2) => {
Type::Var("V2".to_string())
};
(M2) => {
Type::Var("M2".to_string())
};
(Acc) => {
Type::Var("Acc".to_string())
};
}
macro_rules! stack {
(a) => {
StackType::RowVar("a".to_string())
};
(a $t1:tt) => {
StackType::RowVar("a".to_string()).push(ty!($t1))
};
(a $t1:tt $t2:tt) => {
StackType::RowVar("a".to_string())
.push(ty!($t1))
.push(ty!($t2))
};
(a $t1:tt $t2:tt $t3:tt) => {
StackType::RowVar("a".to_string())
.push(ty!($t1))
.push(ty!($t2))
.push(ty!($t3))
};
(a $t1:tt $t2:tt $t3:tt $t4:tt) => {
StackType::RowVar("a".to_string())
.push(ty!($t1))
.push(ty!($t2))
.push(ty!($t3))
.push(ty!($t4))
};
(a $t1:tt $t2:tt $t3:tt $t4:tt $t5:tt) => {
StackType::RowVar("a".to_string())
.push(ty!($t1))
.push(ty!($t2))
.push(ty!($t3))
.push(ty!($t4))
.push(ty!($t5))
};
(b) => {
StackType::RowVar("b".to_string())
};
(b $t1:tt) => {
StackType::RowVar("b".to_string()).push(ty!($t1))
};
(b $t1:tt $t2:tt) => {
StackType::RowVar("b".to_string())
.push(ty!($t1))
.push(ty!($t2))
};
}
macro_rules! builtin {
($sigs:ident, $name:expr, (a -- a)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a), stack!(a)));
};
($sigs:ident, $name:expr, (a -- a $o1:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a), stack!(a $o1)));
};
($sigs:ident, $name:expr, (a -- a $o1:tt $o2:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a), stack!(a $o1 $o2)));
};
($sigs:ident, $name:expr, (a $i1:tt -- a)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1), stack!(a)));
};
($sigs:ident, $name:expr, (a $i1:tt -- a $o1:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1), stack!(a $o1)));
};
($sigs:ident, $name:expr, (a $i1:tt -- a $o1:tt $o2:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1), stack!(a $o1 $o2)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt -- a)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2), stack!(a)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt -- a $o1:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2), stack!(a $o1)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt -- a $o1:tt $o2:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2), stack!(a $o1 $o2)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt -- a $o1:tt $o2:tt $o3:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2), stack!(a $o1 $o2 $o3)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt -- a $o1:tt $o2:tt $o3:tt $o4:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2), stack!(a $o1 $o2 $o3 $o4)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt $i3:tt -- a)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2 $i3), stack!(a)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt $i3:tt -- a $o1:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2 $i3), stack!(a $o1)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt $i3:tt -- a $o1:tt $o2:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2 $i3), stack!(a $o1 $o2)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt $i3:tt -- a $o1:tt $o2:tt $o3:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2 $i3), stack!(a $o1 $o2 $o3)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt $i3:tt $i4:tt -- a $o1:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2 $i3 $i4), stack!(a $o1)));
};
($sigs:ident, $name:expr, (a $i1:tt $i2:tt $i3:tt $i4:tt $i5:tt -- a $o1:tt)) => {
$sigs.insert($name.to_string(), Effect::new(stack!(a $i1 $i2 $i3 $i4 $i5), stack!(a $o1)));
};
}
macro_rules! builtins_int_int_to_int {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a Int Int -- a Int));
)+
};
}
macro_rules! builtins_int_int_to_bool {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a Int Int -- a Bool));
)+
};
}
macro_rules! builtins_bool_bool_to_bool {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a Bool Bool -- a Bool));
)+
};
}
macro_rules! builtins_int_to_int {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a Int -- a Int));
)+
};
}
macro_rules! builtins_string_to_string {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a String -- a String));
)+
};
}
macro_rules! builtins_float_float_to_float {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a Float Float -- a Float));
)+
};
}
macro_rules! builtins_float_float_to_bool {
($sigs:ident, $($name:expr),+ $(,)?) => {
$(
builtin!($sigs, $name, (a Float Float -- a Bool));
)+
};
}
pub(super) use builtin;
pub(super) use builtins_bool_bool_to_bool;
pub(super) use builtins_float_float_to_bool;
pub(super) use builtins_float_float_to_float;
pub(super) use builtins_int_int_to_bool;
pub(super) use builtins_int_int_to_int;
pub(super) use builtins_int_to_int;
pub(super) use builtins_string_to_string;
pub(super) use stack;
pub(super) use ty;