parent
							
								
									0dc2f7be84
								
							
						
					
					
						commit
						9f69cfd65b
					
				| @ -0,0 +1,518 @@ | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| use crate::{ | ||||
|     Builtin, DeBrujinAst, | ||||
|     exec::builtins::DeBrujinBuiltInAst, | ||||
|     parse::Constant, | ||||
|     types::{PrimitiveType, TaggedType, Type, TypeTag}, | ||||
| }; | ||||
| 
 | ||||
| pub struct LtOp; | ||||
| struct LtOpNat(usize); | ||||
| struct LtOpFloat(f64); | ||||
| 
 | ||||
| impl Builtin for LtOp { | ||||
|     fn name(&self) -> String { | ||||
|         "lt".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Num, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", PrimitiveType::Bool), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(LtOpNat(n)))) | ||||
|             } | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(LtOpFloat(n)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for LtOpNat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("lt{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("lt".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Nat(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Nat, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 < n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for LtOpFloat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("lt{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("lt".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Float(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Float, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 < n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct LeOp; | ||||
| struct LeOpNat(usize); | ||||
| struct LeOpFloat(f64); | ||||
| 
 | ||||
| impl Builtin for LeOp { | ||||
|     fn name(&self) -> String { | ||||
|         "le".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Num, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", PrimitiveType::Bool), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(LeOpNat(n)))) | ||||
|             } | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(LeOpFloat(n)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for LeOpNat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("le{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("le".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Nat(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Nat, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 <= n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for LeOpFloat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("le{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("le".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Float(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Float, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 <= n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct GtOp; | ||||
| struct GtOpNat(usize); | ||||
| struct GtOpFloat(f64); | ||||
| 
 | ||||
| impl Builtin for GtOp { | ||||
|     fn name(&self) -> String { | ||||
|         "gt".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Num, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", PrimitiveType::Bool), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(GtOpNat(n)))) | ||||
|             } | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(GtOpFloat(n)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for GtOpNat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("gt{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("gt".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Nat(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Nat, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 > n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for GtOpFloat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("gt{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("gt".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Float(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Float, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 > n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct GeOp; | ||||
| struct GeOpNat(usize); | ||||
| struct GeOpFloat(f64); | ||||
| 
 | ||||
| impl Builtin for GeOp { | ||||
|     fn name(&self) -> String { | ||||
|         "ge".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Num, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", PrimitiveType::Bool), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(GeOpNat(n)))) | ||||
|             } | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(GeOpFloat(n)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for GeOpNat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("ge{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("ge".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Nat(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Nat, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 >= n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for GeOpFloat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("ge{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("ge".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Float(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Float, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 >= n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct EqOp; | ||||
| struct EqOpNat(usize); | ||||
| struct EqOpFloat(f64); | ||||
| 
 | ||||
| impl Builtin for EqOp { | ||||
|     fn name(&self) -> String { | ||||
|         "eq".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Num, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", PrimitiveType::Bool), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(EqOpNat(n)))) | ||||
|             } | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(EqOpFloat(n)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for EqOpNat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("eq{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("eq".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Nat(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Nat, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 == n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for EqOpFloat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("eq{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("eq".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Float(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Float, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 == n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct NeOp; | ||||
| struct NeOpNat(usize); | ||||
| struct NeOpFloat(f64); | ||||
| 
 | ||||
| impl Builtin for NeOp { | ||||
|     fn name(&self) -> String { | ||||
|         "ne".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Num, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", PrimitiveType::Bool), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(NeOpNat(n)))) | ||||
|             } | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(NeOpFloat(n)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for NeOpNat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("ne{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("ne".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Nat(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Nat, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Nat(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 != n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for NeOpFloat { | ||||
|     fn name(&self) -> String { | ||||
|         format!("ne{}", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("ne".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Float(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         Type::arrow(PrimitiveType::Float, PrimitiveType::Bool).into() | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Float(n)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Constant(Constant::Bool(self.0 != n))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,94 @@ | ||||
| use std::rc::Rc; | ||||
| 
 | ||||
| use crate::{ | ||||
|     Builtin, DeBrujinAst, | ||||
|     exec::builtins::DeBrujinBuiltInAst, | ||||
|     parse::Constant, | ||||
|     types::{PrimitiveType, TaggedType, Type, TypeTag}, | ||||
| }; | ||||
| 
 | ||||
| pub struct OpCond; | ||||
| struct OpCond1(bool); | ||||
| struct OpCond2(bool, DeBrujinBuiltInAst); | ||||
| 
 | ||||
| impl Builtin for OpCond { | ||||
|     fn name(&self) -> String { | ||||
|         "if".to_string() | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Any, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 PrimitiveType::Bool, | ||||
|                 Type::arrow("a", Type::arrow("a", "a")), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         match rhs { | ||||
|             DeBrujinBuiltInAst::Constant(Constant::Bool(b)) => { | ||||
|                 Some(DeBrujinBuiltInAst::Builtin(Rc::new(OpCond1(b)))) | ||||
|             } | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for OpCond1 { | ||||
|     fn name(&self) -> String { | ||||
|         format!("if{}1", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Any, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow( | ||||
|                 "a", | ||||
|                 Type::arrow("a", "a"), | ||||
|             ))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::FreeVariable("if".to_string())), | ||||
|             Box::new(DeBrujinAst::Constant(Constant::Bool(self.0))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         Some(DeBrujinBuiltInAst::Builtin(Rc::new(OpCond2(self.0, rhs)))) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Builtin for OpCond2 { | ||||
|     fn name(&self) -> String { | ||||
|         format!("if{}2", self.0) | ||||
|     } | ||||
| 
 | ||||
|     fn r#type(&self) -> TaggedType { | ||||
|         TaggedType::Tagged( | ||||
|             TypeTag::Any, | ||||
|             "a".to_string(), | ||||
|             Box::new(TaggedType::Concrete(Type::arrow("a", "a"))), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn to_ast(&self) -> DeBrujinAst { | ||||
|         DeBrujinAst::Application( | ||||
|             Box::new(DeBrujinAst::Application( | ||||
|                 Box::new(DeBrujinAst::FreeVariable("if".to_string())), | ||||
|                 Box::new(DeBrujinAst::Constant(Constant::Bool(self.0))), | ||||
|             )), | ||||
|             Box::new(self.1.clone().into()), | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     fn apply(&self, rhs: DeBrujinBuiltInAst) -> Option<DeBrujinBuiltInAst> { | ||||
|         Some(if self.0 { self.1.clone() } else { rhs }) | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| mod arith; | ||||
| mod cmp; | ||||
| mod conditional; | ||||
| 
 | ||||
| use std::{collections::HashMap, rc::Rc}; | ||||
| 
 | ||||
| pub use arith::{AddOp, MulOp, SubOp}; | ||||
| pub use cmp::{EqOp, GeOp, GtOp, LeOp, LtOp, NeOp}; | ||||
| pub use conditional::OpCond; | ||||
| 
 | ||||
| use super::Builtin; | ||||
| 
 | ||||
| pub fn all_builtins() -> HashMap<String, Rc<dyn Builtin>> { | ||||
|     let mut builtins: HashMap<String, Rc<dyn Builtin>> = HashMap::new(); | ||||
|     builtins.insert("add".to_string(), Rc::new(AddOp)); | ||||
|     builtins.insert("sub".to_string(), Rc::new(SubOp)); | ||||
|     builtins.insert("mul".to_string(), Rc::new(MulOp)); | ||||
|     builtins.insert("if".to_string(), Rc::new(OpCond)); | ||||
|     builtins.insert("ge".to_string(), Rc::new(GeOp)); | ||||
|     builtins.insert("gt".to_string(), Rc::new(GtOp)); | ||||
|     builtins.insert("le".to_string(), Rc::new(LeOp)); | ||||
|     builtins.insert("lt".to_string(), Rc::new(LtOp)); | ||||
|     builtins.insert("eq".to_string(), Rc::new(EqOp)); | ||||
|     builtins.insert("ne".to_string(), Rc::new(NeOp)); | ||||
|     builtins | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue