Compare commits
3 commits
3903cbdecd
...
71a8f4e06b
Author | SHA1 | Date | |
---|---|---|---|
71a8f4e06b | |||
91cd1cd7d8 | |||
2d387e6279 |
6 changed files with 164 additions and 137 deletions
|
@ -4,3 +4,8 @@ edition = "2018"
|
|||
name = "laddertypes"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
tiny-ansi = { version = "0.1.0", optional = true }
|
||||
|
||||
[features]
|
||||
pretty = ["dep:tiny-ansi"]
|
||||
|
|
|
@ -65,6 +65,10 @@ impl TypeDict {
|
|||
pub fn get_typeid(&self, tn: &String) -> Option<TypeID> {
|
||||
self.typenames.mλ.get(tn).cloned()
|
||||
}
|
||||
|
||||
pub fn get_varname(&self, var_id: u64) -> Option<String> {
|
||||
self.typenames.my.get(&TypeID::Var(var_id)).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod term;
|
|||
pub mod lexer;
|
||||
pub mod parser;
|
||||
pub mod unparser;
|
||||
pub mod sugar;
|
||||
pub mod curry;
|
||||
pub mod sugar;
|
||||
pub mod lnf;
|
||||
|
@ -14,9 +15,12 @@ pub mod unification;
|
|||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
#[cfg(feature = "pretty")]
|
||||
mod pretty;
|
||||
|
||||
pub use {
|
||||
dict::*,
|
||||
term::*,
|
||||
unification::*
|
||||
sugar::*,
|
||||
unification::*,
|
||||
};
|
||||
|
||||
|
|
148
src/pretty.rs
Normal file
148
src/pretty.rs
Normal file
|
@ -0,0 +1,148 @@
|
|||
use {
|
||||
crate::TypeDict,
|
||||
crate::sugar::SugaredTypeTerm,
|
||||
tiny_ansi::TinyAnsi
|
||||
};
|
||||
|
||||
impl SugaredTypeTerm {
|
||||
pub fn pretty(&self, dict: &TypeDict, indent: u64) -> String {
|
||||
let indent_width = 4;
|
||||
match self {
|
||||
SugaredTypeTerm::TypeID(id) => {
|
||||
format!("{}", dict.get_typename(id).unwrap_or("??".bright_red())).bright_blue()
|
||||
},
|
||||
|
||||
SugaredTypeTerm::Num(n) => {
|
||||
format!("{}", n).bright_cyan()
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Char(c) => {
|
||||
format!("'{}'", c)
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Univ(t) => {
|
||||
format!("{} {} . {}",
|
||||
"∀".yellow().bold(),
|
||||
dict.get_varname(0).unwrap_or("??".into()).bright_blue(),
|
||||
t.pretty(dict,indent)
|
||||
)
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Spec(args) => {
|
||||
let mut s = String::new();
|
||||
s.push_str(&"<".yellow().bold());
|
||||
for i in 0..args.len() {
|
||||
let arg = &args[i];
|
||||
if i > 0 {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str( &arg.pretty(dict,indent+1) );
|
||||
}
|
||||
s.push_str(&">".yellow().bold());
|
||||
s
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Struct(args) => {
|
||||
let mut s = String::new();
|
||||
s.push_str(&"{".yellow().bold());
|
||||
for arg in args {
|
||||
s.push('\n');
|
||||
for x in 0..(indent+1)*indent_width {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str(&arg.pretty(dict, indent + 1));
|
||||
s.push_str(&";\n".bright_yellow());
|
||||
}
|
||||
|
||||
s.push('\n');
|
||||
for x in 0..indent*indent_width {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str(&"}".yellow().bold());
|
||||
s
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Enum(args) => {
|
||||
let mut s = String::new();
|
||||
s.push_str(&"(".yellow().bold());
|
||||
for i in 0..args.len() {
|
||||
let arg = &args[i];
|
||||
s.push('\n');
|
||||
for x in 0..(indent+1)*indent_width {
|
||||
s.push(' ');
|
||||
}
|
||||
if i > 0 {
|
||||
s.push_str(&"| ".yellow().bold());
|
||||
}
|
||||
s.push_str(&arg.pretty(dict, indent + 1));
|
||||
}
|
||||
|
||||
s.push('\n');
|
||||
for x in 0..indent*indent_width {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str(&")".yellow().bold());
|
||||
s
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Seq(args) => {
|
||||
let mut s = String::new();
|
||||
s.push_str(&"[ ".yellow().bold());
|
||||
for i in 0..args.len() {
|
||||
let arg = &args[i];
|
||||
if i > 0 {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str(&arg.pretty(dict, indent+1));
|
||||
}
|
||||
s.push_str(&" ]".yellow().bold());
|
||||
s
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Morph(args) => {
|
||||
let mut s = String::new();
|
||||
for arg in args {
|
||||
s.push_str(&" ~~morph~~> ".bright_yellow());
|
||||
s.push_str(&arg.pretty(dict, indent));
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Func(args) => {
|
||||
let mut s = String::new();
|
||||
for i in 0..args.len() {
|
||||
let arg = &args[i];
|
||||
if i > 0{
|
||||
s.push('\n');
|
||||
for x in 0..(indent*indent_width) {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str(&"--> ".bright_yellow());
|
||||
} else {
|
||||
// s.push_str(" ");
|
||||
}
|
||||
s.push_str(&arg.pretty(dict, indent));
|
||||
}
|
||||
s
|
||||
}
|
||||
|
||||
SugaredTypeTerm::Ladder(rungs) => {
|
||||
let mut s = String::new();
|
||||
for i in 0..rungs.len() {
|
||||
let rung = &rungs[i];
|
||||
if i > 0{
|
||||
s.push('\n');
|
||||
for x in 0..(indent*indent_width) {
|
||||
s.push(' ');
|
||||
}
|
||||
s.push_str(&"~ ".yellow());
|
||||
}
|
||||
s.push_str(&rung.pretty(dict, indent));
|
||||
}
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
134
src/sugar.rs
134
src/sugar.rs
|
@ -1,134 +0,0 @@
|
|||
use crate::{
|
||||
TypeTerm,
|
||||
TypeID
|
||||
};
|
||||
|
||||
pub const SEQ_SUGARID : TypeID = TypeID::Fun(0);
|
||||
pub const ENUM_SUGARID : TypeID = TypeID::Fun(1);
|
||||
pub const STRUCT_SUGARID : TypeID = TypeID::Fun(2);
|
||||
pub const SUGARID_LIMIT : u64 = 3;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum SugaredTypeTerm {
|
||||
/* Atomic Terms */
|
||||
|
||||
// Base types from dictionary
|
||||
TypeID(TypeID),
|
||||
|
||||
// Literals
|
||||
Num(i64),
|
||||
Char(char),
|
||||
|
||||
|
||||
|
||||
/* Complex Terms */
|
||||
|
||||
// Type Parameters
|
||||
// avoid currying to save space & indirection
|
||||
App(Vec< SugaredTypeTerm >),
|
||||
|
||||
// Type Ladders
|
||||
Ladder(Vec< SugaredTypeTerm >),
|
||||
|
||||
|
||||
/* Sugar Terms */
|
||||
Seq( Vec<SugaredTypeTerm> ),
|
||||
Enum( Vec<SugaredTypeTerm> ),
|
||||
Struct( Vec<SugaredTypeTerm> )
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TypeAssignment {
|
||||
id: Option<String>,
|
||||
ty: TypeTerm,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct LayoutSugar {
|
||||
Seq( Vec<TypeAssignment> ),
|
||||
Enum( Vec<TypeAssignment> ),
|
||||
Struct( Vec<TypeAssignment> )
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl SugaredTypeTerm {
|
||||
pub fn desugar(self) -> TypeTerm {
|
||||
match self {
|
||||
SugaredTypeTerm::TypeID(id) => TypeTerm::TypeID(id),
|
||||
SugaredTypeTerm::Num(n) => TypeTerm::Num(n),
|
||||
SugaredTypeTerm::Char(c) => TypeTerm::Char(c),
|
||||
SugaredTypeTerm::App(params) => TypeTerm::App(params.into_iter().map(|p| p.desugar()).collect()),
|
||||
SugaredTypeTerm::Ladder(rungs) => TypeTerm::Ladder(rungs.into_iter().map(|p| p.desugar()).collect()),
|
||||
SugaredTypeTerm::Seq(pattern) => {
|
||||
let mut params : Vec<TypeTerm> = pattern.into_iter().map(|p| p.desugar()).collect();
|
||||
params.insert(0, TypeTerm::TypeID(SEQ_SUGARID));
|
||||
TypeTerm::App(params)
|
||||
}
|
||||
SugaredTypeTerm::Enum(options) => {
|
||||
let mut params : Vec<TypeTerm> = options.into_iter().map(|o| o.desugar()).collect();
|
||||
params.insert(0, TypeTerm::TypeID(ENUM_SUGARID));
|
||||
TypeTerm::App(params)
|
||||
}
|
||||
SugaredTypeTerm::Struct(members) => {
|
||||
let mut params : Vec<TypeTerm> = members.into_iter().map(|m| m.desugar()).collect();
|
||||
params.insert(0, TypeTerm::TypeID(STRUCT_SUGARID));
|
||||
TypeTerm::App(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// normalize any unsugared parts into sugared form
|
||||
pub fn sugar(self) -> SugaredTypeTerm {
|
||||
// todo: optimize
|
||||
self.desugar().sugar()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeTerm {
|
||||
pub fn sugar(self) -> SugaredTypeTerm {
|
||||
match self {
|
||||
TypeTerm::TypeID(id) => SugaredTypeTerm::TypeID(id),
|
||||
TypeTerm::Num(n) => SugaredTypeTerm::Num(n),
|
||||
TypeTerm::Char(c) => SugaredTypeTerm::Char(c),
|
||||
TypeTerm::App(mut params) => {
|
||||
if params.len() > 0 {
|
||||
let prim = params.remove(0);
|
||||
match prim {
|
||||
TypeTerm::TypeID( SEQ_SUGARID ) =>
|
||||
SugaredTypeTerm::Seq(
|
||||
params
|
||||
.into_iter()
|
||||
.map(|p| p.sugar())
|
||||
.collect()
|
||||
),
|
||||
|
||||
TypeTerm::TypeID( ENUM_SUGARID ) =>
|
||||
SugaredTypeTerm::Enum(
|
||||
params
|
||||
.into_iter()
|
||||
.map(|p| p.sugar())
|
||||
.collect()
|
||||
),
|
||||
TypeTerm::TypeID( STRUCT_SUGARID ) =>
|
||||
SugaredTypeTerm::Struct(
|
||||
params
|
||||
.into_iter()
|
||||
.map(|p| p.sugar())
|
||||
.collect()
|
||||
),
|
||||
other => SugaredTypeTerm::App(
|
||||
params.into_iter().map(|p| p.sugar()).collect()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
SugaredTypeTerm::App(vec![])
|
||||
}
|
||||
},
|
||||
TypeTerm::Ladder(rungs) => {
|
||||
SugaredTypeTerm::Ladder(rungs.into_iter().map(|r| r.sugar()).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -57,7 +57,7 @@ impl TypeTerm {
|
|||
pub fn repr_as(&mut self, t: impl Into<TypeTerm>) -> &mut Self {
|
||||
match self {
|
||||
TypeTerm::Ladder(rungs) => {
|
||||
rungs.push(t.into());
|
||||
rungs.push(t.into());
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue