use std::rc::Rc;
use std::fmt;
use std::fmt::{Debug,Formatter};
use std::hash::{Hash,Hasher};
use eval;
use normal;
pub type Var = String;
pub type Ident = String;
#[derive(Clone,Debug,Eq,PartialEq,Hash,PartialOrd,Ord)]
pub enum Name {
Bin(NameRec, NameRec),
Leaf,
Sym(String),
Num(usize),
NoParse(String),
}
pub type NameRec = Rc<Name>;
#[derive(Clone,Debug,Eq,PartialEq,Hash,PartialOrd,Ord)]
pub enum NameTm {
Var(Var),
ValVar(Var),
Name(Name),
Bin(NameTmRec, NameTmRec),
Lam(Var, Sort, NameTmRec),
App(NameTmRec, NameTmRec),
WriteScope,
NoParse(String),
}
pub type NameTmRec = Rc<NameTm>;
#[derive(Clone,Debug,Eq,PartialEq,Hash,PartialOrd,Ord)]
pub enum IdxTm {
Var(Var),
Ident(Ident),
Sing(NameTm),
Empty,
Apart(IdxTmRec, IdxTmRec),
Union(IdxTmRec, IdxTmRec),
Unit,
Bin(IdxTmRec, IdxTmRec),
Pair(IdxTmRec, IdxTmRec),
Proj1(IdxTmRec),
Proj2(IdxTmRec),
WriteScope,
NmSet(normal::NmSet),
Lam(Var, Sort, IdxTmRec),
App(IdxTmRec, IdxTmRec),
Map(NameTmRec, IdxTmRec),
MapStar(NameTmRec, IdxTmRec),
FlatMap(IdxTmRec, IdxTmRec),
FlatMapStar(IdxTmRec, IdxTmRec),
NoParse(String),
}
pub type IdxTmRec = Rc<IdxTm>;
#[derive(Clone,Debug,Eq,PartialEq,Hash,PartialOrd,Ord)]
pub enum Sort {
Nm,
NmSet,
NmArrow(SortRec,SortRec),
IdxArrow(SortRec,SortRec),
Unit,
Prod(SortRec,SortRec),
NoParse(String),
}
pub type SortRec = Rc<Sort>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Kind {
Type,
TypeParam(KindRec),
IdxParam(Sort, KindRec),
NoParse(String),
}
pub type KindRec = Rc<Kind>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Prop {
Tt,
Equiv(IdxTm, IdxTm, Sort),
Apart(IdxTm, IdxTm, Sort),
Conj(PropRec, PropRec),
NoParse(String),
}
pub type PropRec = Rc<Prop>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Effect {
WR(IdxTm, IdxTm),
NoParse(String),
}
pub type EffectRec = Rc<Effect>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Type {
Var(Var),
Ident(Ident),
Sum(TypeRec, TypeRec),
Prod(TypeRec, TypeRec),
Unit,
Ref(IdxTm, TypeRec),
Thk(IdxTm, CEffectRec),
IdxApp(TypeRec, IdxTm),
TypeApp(TypeRec, TypeRec),
Nm(IdxTm),
NmFn(NameTm),
TypeFn(Var, Kind, TypeRec),
IdxFn(Var, Sort, TypeRec),
Rec(Var, TypeRec),
Exists(Var, SortRec, Prop, TypeRec),
NoParse(String),
}
pub type TypeRec = Rc<Type>;
pub fn ident_nat() -> Ident { "Nat".to_string() }
pub fn ident_bool() -> Ident { "Bool".to_string() }
pub fn ident_string() -> Ident { "String".to_string() }
pub fn type_string() -> Type { Type::Ident(ident_string()) }
pub fn type_nat() -> Type { Type::Ident(ident_nat()) }
pub fn type_bool() -> Type { Type::Ident(ident_bool()) }
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum CType {
Lift(Type),
Arrow(Type,CEffectRec),
NoParse(String),
}
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum CEffect {
Cons(CType,Effect),
ForallType(Var,Kind,CEffectRec),
ForallIdx(Var,Sort,Prop,CEffectRec),
NoParse(String),
}
pub type CEffectRec = Rc<CEffect>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Val {
Var(Var),
Unit,
Pair(ValRec, ValRec),
Inj1(ValRec),
Inj2(ValRec),
Roll(ValRec),
Name(Name),
NameFn(NameTm),
Anno(ValRec,Type),
Pack(IdxTm, ValRec),
ThunkAnon(ExpRec),
Bool(bool),
Nat(usize),
Str(String),
NoParse(String),
}
pub type ValRec = Rc<Val>;
#[derive(Clone)]
pub struct HostEvalFn {
pub path:String,
pub arity:usize,
pub eval:Rc<Fn(Vec<eval::ast_dynamic::RtVal>) -> eval::ast_dynamic::ExpTerm>
}
impl Hash for HostEvalFn {
fn hash<H:Hasher>(&self, _hasher: &mut H) {
panic!("XXX")
}
}
impl Debug for HostEvalFn {
fn fmt(&self, f:&mut Formatter) -> fmt::Result {
write!(f, "HostEvalFn({:?})", self.path)
}
}
impl PartialEq for HostEvalFn {
fn eq(&self, _other:&Self) -> bool {
panic!("XXX")
}
}
impl Eq for HostEvalFn { }
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum PrimApp {
NameBin(Val,Val),
RefThunk(Val),
NatEq(Val,Val),
NatLt(Val,Val),
NatLte(Val,Val),
NatPlus(Val,Val),
}
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Exp {
UseAll(UseAllModule, ExpRec),
Decls(DeclsRec, ExpRec),
AnnoE(ExpRec,CEffect),
AnnoC(ExpRec,CType),
Force(Val),
Thunk(Val,ExpRec),
Unroll(Val,Var,ExpRec),
Unpack(Var,Var,Val,ExpRec),
Fix(Var,ExpRec),
Ret(Val),
DefType(Var,Type,ExpRec),
Let(Var,ExpRec,ExpRec),
Lam(Var, ExpRec),
HostFn(HostEvalFn),
App(ExpRec, Val),
IdxApp(ExpRec, IdxTm),
Split(Val, Var, Var, ExpRec),
Case(Val, Var, ExpRec, Var, ExpRec),
IfThenElse(Val, ExpRec, ExpRec),
Ref(Val,Val),
Get(Val),
WriteScope(Val,ExpRec),
NameFnApp(Val,Val),
PrimApp(PrimApp),
Unimp,
DebugLabel(Option<Name>,Option<String>,ExpRec),
NoParse(String),
}
pub type ExpRec = Rc<Exp>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub struct Module {
pub path: String,
pub body: String,
pub decls: Decls,
}
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub enum Decls {
UseAll(UseAllModule, DeclsRec),
Doc( String, DeclsRec),
NmTm( String,NameTm, DeclsRec),
IdxTm(String,IdxTm, DeclsRec),
Type( String,Type, DeclsRec),
Val( String,Option<Type>, Val, DeclsRec),
Fn( String,Type,Exp, DeclsRec),
End,
NoParse(String),
}
pub type DeclsRec = Rc<Decls>;
#[derive(Clone,Debug,Eq,PartialEq,Hash)]
pub struct UseAllModule {
pub path: String,
pub module: Rc<Module>
}