diff options
author | JJ | 2023-07-20 22:46:57 +0000 |
---|---|---|
committer | JJ | 2023-07-20 22:46:57 +0000 |
commit | 77a9e2af0d4118462a0805e6a8994e04a8a86726 (patch) | |
tree | 158e75bdda7c2371ea06a19afb81aa20dac9a140 | |
parent | cd08767dbb2954ba7a93359230c6d75358b5ddf2 (diff) |
-rw-r--r-- | src/ast.rs | 12 | ||||
-rw-r--r-- | src/bidirectional.rs | 18 | ||||
-rw-r--r-- | src/effects.rs | 19 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 2 | ||||
-rw-r--r-- | src/parser.rs | 20 | ||||
-rw-r--r-- | src/util.rs | 37 |
7 files changed, 42 insertions, 70 deletions
@@ -2,7 +2,7 @@ use std::collections::{BTreeMap, HashMap}; pub type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Default)] pub struct Context(HashMap<Identifier, Term>, HashMap<Signature, Expression>); pub type Identifier = String; @@ -173,7 +173,7 @@ impl core::fmt::Display for Type { write!(f, "union[")?; for (i, val) in data.iter().enumerate() { write!(f, "{}", val)?; - if !(i == data.len() - 1) { + if i != data.len() - 1 { write!(f, ", ")?; } } @@ -183,7 +183,7 @@ impl core::fmt::Display for Type { write!(f, "struct[")?; for (i, (key, val)) in data.iter().enumerate() { write!(f, "{}: {}", key, val)?; - if !(i == data.len() - 1) { + if i != data.len() - 1 { write!(f, ", ")?; } } @@ -196,7 +196,7 @@ impl core::fmt::Display for Type { Some(key) => write!(f, "{}: {}", key, val)?, None => write!(f, "{}", val)? } - if !(i == data.len() - 1) { + if i != data.len() - 1 { write!(f, ", ")?; } } @@ -207,7 +207,7 @@ impl core::fmt::Display for Type { write!(f, "interface[")?; for (i, sig) in data.iter().enumerate() { write!(f, "func {}({}): {}", sig.name, sig.from, sig.to)?; - if !(i == data.len() - 1) { + if i != data.len() - 1 { write!(f, ", ")?; } } @@ -222,7 +222,7 @@ impl core::fmt::Display for Type { if let Some(data) = data { for (i, kind) in data.iter().enumerate() { write!(f, "{}", kind)?; - if !(i == data.len() - 1) { + if i != data.len() - 1 { write!(f, ", ")?; } } diff --git a/src/bidirectional.rs b/src/bidirectional.rs index 4e69372..272ccab 100644 --- a/src/bidirectional.rs +++ b/src/bidirectional.rs @@ -7,20 +7,20 @@ impl Context { // fall through to inference mode Expression::Annotation { expr, kind } => { let result = self.infer(Expression::Annotation { expr, kind })?; - return match self.subtype(&result, &target) { + match self.subtype(&result, target) { true => Ok(()), false => Err(format!("inferred type {result} does not match target {target}").into()) } }, // Bt-CheckInfer - Expression::Constant { term } => match self.subtype(&term.convert()?, &target) { + Expression::Constant { term } => match self.subtype(&term.convert()?, target) { true => Ok(()), false => Err(format!("constant is of wrong type, expected {target}").into()) // false => Ok(()) // all our constants are Empty for now }, // Bt-CheckInfer Expression::Variable { id } => match self.get_term(&id) { - Some(term) if self.subtype(&term.convert()?, &target) => Ok(()), + Some(term) if self.subtype(&term.convert()?, target) => Ok(()), Some(_) => Err(format!("variable {id} is of wrong type").into()), None => Err(format!("failed to find variable {id} in context").into()) }, @@ -29,14 +29,14 @@ impl Context { Type::Function(from, to) => { let mut context = self.clone(); context.insert_term(param, from.default()?); - return context.check(*func, &to); + return context.check(*func, to); }, _ => Err(format!("attempting to check an abstraction with a non-function type {target}").into()) }, // fall through to inference mode Expression::Application { func, arg } => { let result = &self.infer(Expression::Application { func, arg })?; - return match self.subtype(result, target) { + match self.subtype(result, target) { true => Ok(()), false => Err(format!("inferred type {result} does not match {target}").into()) } @@ -44,9 +44,9 @@ impl Context { // T-If Expression::Conditional { if_cond, if_then, if_else } => { self.check(*if_cond, &Type::Boolean)?; - self.check(*if_then, &target)?; - self.check(*if_else, &target)?; - return Ok(()); + self.check(*if_then, target)?; + self.check(*if_else, target)?; + Ok(()) } } } @@ -65,7 +65,7 @@ impl Context { }, // Bt-App Expression::Application { func, arg } => match self.infer(*func)? { - Type::Function(from, to) => self.check(*arg, &*from).map(|x| *to), + Type::Function(from, to) => self.check(*arg, &from).map(|x| *to), _ => Err("application abstraction is not a function type".into()) }, // inference from an abstraction is always an error diff --git a/src/effects.rs b/src/effects.rs deleted file mode 100644 index 4c4c110..0000000 --- a/src/effects.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Simple types for effects - -use crate::ast::*; - -// bad and wrong and useless -pub struct Effection { - expr: Expression, - effect: Effect, -} - -// yeah i'm not dealing with this yet -pub enum Effect { - Empty, - Total, - Exn, - Pure, - IO, -} - @@ -1,10 +1,8 @@ -#![allow(unused_variables, non_upper_case_globals)] +#![allow(unused_variables, non_upper_case_globals, clippy::iter_nth_zero)] #![feature(let_chains)] pub mod ast; pub mod bidirectional; -// pub mod classes; -// pub mod effects; pub mod parser; pub mod util; pub mod simple; diff --git a/src/main.rs b/src/main.rs index b93e778..efcefc1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,6 @@ use std::io::{Write, stdout, stdin}; use chrysanthemum::*; use chrysanthemum::ast::*; -use chrysanthemum::bidirectional::*; -use chrysanthemum::simple::*; fn main() { println!("chrysanthemum"); diff --git a/src/parser.rs b/src/parser.rs index 9051bfb..7d3ca65 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -19,8 +19,8 @@ pub fn parse_lambda(input: &str) -> Result<Expression> { rule num() -> Expression = p:"-"? c:['0'..='9']+ { let value = c.iter().collect::<String>().parse::<usize>().unwrap(); Expression::Constant { - term: if let Some(_) = p { - Term::Integer(-1 * isize::try_from(value).unwrap()) + term: if p.is_some() { + Term::Integer(-isize::try_from(value).unwrap()) } else { Term::Natural(value) } @@ -98,14 +98,14 @@ pub fn parse_lambda(input: &str) -> Result<Expression> { } } } - return Ok(lambda::expr(input.trim())?); + Ok(lambda::expr(input.trim())?) } const operators: [char; 17] = ['=', '+', '-', '*', '/', '<', '>', '@', '$', '~', '&', '%', '|', '!', '?', '^', '\\']; const brackets: [char; 6] = ['(', ')', '{', '}', '[', ']']; const special: [char; 7] = ['.', ',', ':', ';', '`', '\'', '"']; -const keywords: [&'static str; 3] = ["if", "else", "func"]; +const keywords: [&str; 3] = ["if", "else", "func"]; pub enum Token { Operator(String), @@ -148,7 +148,7 @@ pub fn lex(input: &str) -> Result<Vec<Token>> { match state { State::Default => match c { ' ' if indent.blank => indent.count += 1, - ' ' if buffer.len() > 0 => { + ' ' if !buffer.is_empty() => { result.push(parse_token(&buffer)?); buffer.clear(); }, @@ -206,7 +206,7 @@ pub fn lex(input: &str) -> Result<Vec<Token>> { buffer.clear(); }, _ if brackets.contains(&c) || special.contains(&c) => { - if buffer.len() > 0 { + if !buffer.is_empty() { result.push(parse_token(&buffer)?); buffer.clear(); } @@ -284,7 +284,7 @@ pub fn lex(input: &str) -> Result<Vec<Token>> { }, } } - return Ok(result); + Ok(result) } fn parse_token(token: &str) -> Result<Token> { @@ -307,7 +307,7 @@ fn is_operator(token: &str) -> bool { return false; } } - return true; + true } fn is_value(token: &str) -> bool { @@ -321,7 +321,7 @@ fn is_value(token: &str) -> bool { return false; } } - return true; + true } fn is_identifier(token: &str) -> bool { @@ -335,5 +335,5 @@ fn is_identifier(token: &str) -> bool { return false; } } - return true; + true } diff --git a/src/util.rs b/src/util.rs index 1962fb4..a575e27 100644 --- a/src/util.rs +++ b/src/util.rs @@ -7,53 +7,48 @@ use crate::ast::*; pub fn unique_ident(count: &mut u8) -> String { *count += 1; if *count == 0 { - panic!("we've overflowed!"); + panic!("we've overflowed!") } else { - return String::from(format!("{:X}", count)); + format!("{:X}", count) } } pub fn Ann(expr: Expression, kind: Type) -> Expression { - return Expression::Annotation { - expr: Box::new(expr), - kind: kind - }; + Expression::Annotation { expr: Box::new(expr), kind } } pub fn Const(term: Term) -> Expression { - return Expression::Constant { term }; + Expression::Constant { term } } pub fn Var(id: &str) -> Expression { - return Expression::Variable { - id: String::from(id) - }; + Expression::Variable { id: String::from(id) } } pub fn Abs(param: &str, func: Expression) -> Expression { - return Expression::Abstraction { + Expression::Abstraction { param: String::from(param), - func: Box::new(func), - }; + func: Box::new(func) + } } pub fn App(func: Expression, arg: Expression) -> Expression { - return Expression::Application { + Expression::Application { func: Box::new(func), arg: Box::new(arg) - }; + } } pub fn Cond(if_cond: Expression, if_then: Expression, if_else: Expression) -> Expression { - return Expression::Conditional { + Expression::Conditional { if_cond: Box::new(if_cond), if_then: Box::new(if_then), if_else: Box::new(if_else) - }; + } } pub fn Func(from: Type, to: Type) -> Type { - return Type::Function(Box::new(from), Box::new(to)) + Type::Function(Box::new(from), Box::new(to)) } pub const Empty: Type = Type::Empty; @@ -64,13 +59,13 @@ pub const Nat: Type = Type::Natural; pub const Int: Type = Type::Integer; pub fn Float(term: f32) -> Term { - return Term::Float(term) + Term::Float(term) } pub fn Str(data: &str) -> Term { - return Term::String(data.into()) + Term::String(data.into()) } pub fn Union(data: Term) -> Term { - return Term::Union(Box::new(data)) + Term::Union(Box::new(data)) } |