smol lang
Diffstat (limited to 'src/parser/types.rs')
-rw-r--r--src/parser/types.rs183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/parser/types.rs b/src/parser/types.rs
new file mode 100644
index 0000000..f06554a
--- /dev/null
+++ b/src/parser/types.rs
@@ -0,0 +1,183 @@
+use crate::lexer::Token;
+use beef::lean::Cow;
+use chumsky::prelude::*;
+pub type Span = SimpleSpan<usize>;
+pub type Error<'s> = Rich<'s, Token<'s>, Span>;
+
+#[derive(Clone)]
+pub struct FnDef<'s> {
+ pub name: &'s str,
+ pub args: Vec<(Type<'s>, Type<'s>)>,
+ pub ret: Type<'s>,
+ pub block: Option<Expr<'s>>,
+ pub meta: Vec<Meta<'s>>,
+}
+
+impl std::fmt::Debug for FnDef<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{} {:?} -> {:?}", self.name, self.args, self.ret)?;
+ if let Some(b) = &self.block {
+ write!(f, " {b:?}")?;
+ }
+ write!(f, " {:?}", self.meta)
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum Stmt<'s> {
+ Fn(FnDef<'s>),
+}
+
+#[derive(Debug, Clone)]
+pub enum Ast<'s> {
+ Module(Vec<Stmt<'s>>),
+}
+
+#[derive(Clone)]
+pub enum Value<'s> {
+ Float(f64),
+ Int(u64),
+ String(Cow<'s, str>),
+ Unit,
+}
+
+impl std::fmt::Debug for Value<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Float(x) => write!(f, "{x}f"),
+ Self::Int(x) => write!(f, "{x}i"),
+ Self::String(x) => write!(f, "\"{x}\""),
+ Self::Unit => write!(f, "()"),
+ }
+ }
+}
+
+#[derive(Clone, Debug, Copy)]
+pub enum Associativity {
+ Left,
+ Right,
+ None,
+}
+
+#[derive(Clone, Debug, Copy)]
+pub enum Fix {
+ Pre,
+ Post,
+ In,
+}
+
+#[derive(Clone, Copy)]
+pub struct FixMetaData<'s> {
+ pub looser_than: Option<&'s str>,
+ pub tighter_than: Option<&'s str>,
+ pub fixness: Fix,
+ pub assoc: Option<Associativity>,
+}
+
+impl std::fmt::Debug for FixMetaData<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{:?} {{", self.fixness)?;
+ if let Some(x) = self.assoc {
+ write!(f, " assoc {x:?}")?;
+ }
+ if let Some(x) = self.looser_than {
+ write!(f, " looser {x}")?;
+ }
+ if let Some(x) = self.tighter_than {
+ write!(f, " tighter {x}")?;
+ }
+ write!(f, " }}")
+ }
+}
+
+#[derive(Clone, Copy)]
+pub enum FixMeta<'s> {
+ Default(Fix), // function precedence
+ Like(Fix, &'s str),
+ Data(FixMetaData<'s>),
+}
+
+impl std::fmt::Debug for FixMeta<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Default(x) => write!(f, "{x:?}"),
+ Self::Like(x, y) => write!(f, "{x:?} {{ like {y} }}"),
+ Self::Data(x) => write!(f, "{x:?}"),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub enum Meta<'s> {
+ Fix(FixMeta<'s>),
+ Alias(Vec<&'s str>),
+}
+
+impl std::fmt::Debug for Meta<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Fix(fix) => write!(f, "{fix:?}"),
+ Self::Alias(what) => write!(f, "alias {what:?}"),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub enum Expr<'s> {
+ Value(Value<'s>),
+ Ident(&'s str),
+
+ Let {
+ name: &'s str,
+ rhs: Box<Expr<'s>>,
+ },
+ If {
+ cond: Box<Expr<'s>>,
+ when: Box<Expr<'s>>,
+ or: Box<Expr<'s>>,
+ },
+ Semicolon(Box<Expr<'s>>, Box<Expr<'s>>),
+ Call(&'s str, Vec<Expr<'s>>),
+}
+
+impl std::fmt::Debug for Expr<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Value(x) => write!(f, "{x:?}"),
+ Self::Ident(x) => write!(f, "{x}"),
+ Self::Let { name, rhs } => write!(f, "let {name} = {rhs:?}"),
+ Self::If { cond, when, or } => {
+ write!(f, "if {cond:?} {{ {when:?} }} else {{ {or:?} }}")
+ }
+ Self::Semicolon(arg0, arg1) => f.debug_list().entries([arg0, arg1]).finish(),
+ Self::Call(arg, x) => f.debug_tuple("callu").field(arg).field(x).finish(),
+ }
+ }
+}
+
+pub type Spanned<T> = (T, Span);
+
+#[derive(Clone)]
+pub enum Type<'s> {
+ Tuple(Box<[Type<'s>]>),
+ Path(&'s str),
+ Unit,
+}
+
+impl std::fmt::Debug for Type<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::Tuple(x) => write!(
+ f,
+ "{}",
+ std::iter::once("(".to_string())
+ .chain(x.iter().map(|x| format!("{x:?}")).intersperse(", ".into()),)
+ .chain([")".to_string()])
+ .reduce(|acc, x| acc + &x)
+ .unwrap()
+ ),
+ Self::Path(x) => write!(f, "{x}"),
+ Self::Unit => write!(f, "()"),
+ }
+ }
+}