diff options
Diffstat (limited to 'src/ast.rs')
-rw-r--r-- | src/ast.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/ast.rs b/src/ast.rs new file mode 100644 index 0000000..9202968 --- /dev/null +++ b/src/ast.rs @@ -0,0 +1,55 @@ +// Bidirectional type checking, simple types for effects (or perhaps subtyping?) and typeclasses + +use core::fmt; +use std::collections::HashMap; + +pub type Identifier = String; +pub type Context = HashMap<Identifier, Term>; + +// note: when comes the time, we'll put effects in here (i think) +#[derive(Clone, PartialEq, Eq)] +pub enum Expression { + Annotation{expr: Box<Expression>, kind: Type}, + Constant{term: Term}, + Variable{id: Identifier}, + Abstraction{param: Identifier, func: Box<Expression>}, + Application{func: Box<Expression>, arg: Box<Expression>}, + Conditional{if_cond: Box<Expression>, if_then: Box<Expression>, if_else: Box<Expression>} +} + +// _every_ type in our language is represented as this and interpreted as a type. +// how to store more data than fits... hmm +pub type Value = i8; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum Type { + Empty, + Unit, + Bool, + Natural, + // Float, + // String, + // Enum(Vec<Type>), + // Record(Vec<Type>), + // Function{from: Box<Type>, to: Box<Type>}, +} + +// this means that functions cannot have types? unless we put them as empty values ig +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct Term { + pub val: Value, + pub kind: Type, // currently useless / redundant: will be useful for casting +} + +impl fmt::Debug for Expression { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Expression::Annotation { expr, kind } => write!(f, "{:?}:{:?}", expr, kind), + Expression::Constant { term } => write!(f, "{}", term.val), + Expression::Variable { id } => write!(f, "{}", id), + Expression::Abstraction { param, func } => write!(f, "(λ{}.{:?})", param, func), + Expression::Application { func, arg } => write!(f, "{:?} {:?}", func, arg), + Expression::Conditional { if_cond, if_then, if_else } => write!(f, "if {:?} then {:?} else {:?}", if_cond, if_then, if_else), + } + } +} |