smol lang
Diffstat (limited to 'src/parser/types.rs')
-rw-r--r--src/parser/types.rs96
1 files changed, 85 insertions, 11 deletions
diff --git a/src/parser/types.rs b/src/parser/types.rs
index f06554a..0857e1c 100644
--- a/src/parser/types.rs
+++ b/src/parser/types.rs
@@ -1,15 +1,22 @@
+use std::ops::Deref;
+
use crate::lexer::Token;
use beef::lean::Cow;
-use chumsky::prelude::*;
+use chumsky::{
+ input::{SpannedInput, Stream},
+ prelude::*,
+};
+use match_deref::match_deref;
pub type Span = SimpleSpan<usize>;
pub type Error<'s> = Rich<'s, Token<'s>, Span>;
+pub type Input<'s> = SpannedInput<Token<'s>, SimpleSpan, Stream<crate::lexer::Lexer<'s>>>;
#[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 block: Option<Vec<Token<'s>>>,
pub meta: Vec<Meta<'s>>,
}
@@ -59,7 +66,7 @@ pub enum Associativity {
None,
}
-#[derive(Clone, Debug, Copy)]
+#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Fix {
Pre,
Post,
@@ -68,10 +75,10 @@ pub enum Fix {
#[derive(Clone, Copy)]
pub struct FixMetaData<'s> {
- pub looser_than: Option<&'s str>,
- pub tighter_than: Option<&'s str>,
+ pub looser_than: Option<Spanned<&'s str>>,
+ pub tighter_than: Option<Spanned<&'s str>>,
pub fixness: Fix,
- pub assoc: Option<Associativity>,
+ pub assoc: Option<Spanned<Associativity>>,
}
impl std::fmt::Debug for FixMetaData<'_> {
@@ -92,16 +99,36 @@ impl std::fmt::Debug for FixMetaData<'_> {
#[derive(Clone, Copy)]
pub enum FixMeta<'s> {
- Default(Fix), // function precedence
- Like(Fix, &'s str),
- Data(FixMetaData<'s>),
+ Default(Spanned<Fix>), // function precedence
+ Like(Fix, &'s str, Span),
+ Data(Spanned<FixMetaData<'s>>),
+}
+
+impl<'s> FixMeta<'s> {
+ pub fn span(&self) -> Span {
+ match self {
+ Self::Default(x) => x.span,
+ Self::Like(_, _, x) => x,
+ Self::Data(x) => x.span,
+ }
+ }
+
+ pub fn fix(&self) -> Fix {
+ match_deref! {
+ match self {
+ Self::Default(Deref @ x) => *x,
+ Self::Like(x,..) => *x,
+ Self::Data(Deref @ FixMetaData { fixness, .. }) => *fixness,
+ }
+ }
+ }
}
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::Like(x, y, _) => write!(f, "{x:?} {{ like {y} }}"),
Self::Data(x) => write!(f, "{x:?}"),
}
}
@@ -155,7 +182,54 @@ impl std::fmt::Debug for Expr<'_> {
}
}
-pub type Spanned<T> = (T, Span);
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+pub struct Spanned<T> {
+ pub inner: T,
+ pub span: Span,
+}
+
+impl<T> Deref for Spanned<T> {
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ &self.inner
+ }
+}
+
+impl<T> Spanned<T> {
+ pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Spanned<U> {
+ Spanned {
+ inner: f(self.inner),
+ span: self.span,
+ }
+ }
+
+ pub fn dummy(inner: T) -> Spanned<T> {
+ Spanned {
+ inner,
+ span: SimpleSpan::new(0, 0),
+ }
+ }
+
+ pub fn copys<U>(&self, with: U) -> Spanned<U> {
+ Spanned {
+ inner: with,
+ span: self.span,
+ }
+ }
+}
+
+impl<T> From<(T, Span)> for Spanned<T> {
+ fn from((inner, span): (T, Span)) -> Self {
+ Self { inner, span }
+ }
+}
+
+impl<T: std::fmt::Display> std::fmt::Display for Spanned<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{}", self.inner)
+ }
+}
#[derive(Clone)]
pub enum Type<'s> {