rugs 0.0.1

A WIP Haskell implementation
Documentation
use super::{
    helpers::error,
    lexing::{Token, TokenValue},
    ParserState,
};
use crate::ast::*;
 
#[derive(Debug, Clone, PartialEq)]
pub enum DeclKind {
    Instance,
    Class,
    Normal,
}

impl<'a> ParserState<'a> {
    pub(super) fn parse_top_declarations(&mut self) -> anyhow::Result<Vec<TopDeclaration>> {
        let mut decls = Vec::new();
        let tok = self.peek_next_token()?;
        match tok.value {
            TokenValue::RightBrace | TokenValue::VirtualRightBrace => return Ok(decls),
            t => {},
        }
        loop {
            let decl = self.parse_top_declaration()?;
            decls.push(decl);
            let tok = self.peek_next_token()?;
            match tok.value {
                TokenValue::Semicolon => {
                    self.get_next_token()?;
                }
                TokenValue::RightBrace | TokenValue::VirtualRightBrace => break,
                t => return error(&format!("expected semicolon or right brace, got {:?}", t), tok.location),
            }
        }
        Ok(decls)
    }

    pub(super) fn parse_top_declaration(&mut self) -> anyhow::Result<TopDeclaration> {
        let tok = self.peek_next_token()?;
        match tok.value {
            TokenValue::Type => Ok(TopDeclaration::Type(self.parse_type_decl()?)),
            TokenValue::Data => Ok(TopDeclaration::Data(self.parse_data()?)),
            TokenValue::Newtype => Ok(TopDeclaration::Newtype(self.parse_newtype()?)),
            TokenValue::Class => Ok(TopDeclaration::Class(self.parse_class()?)),
            TokenValue::Instance => Ok(TopDeclaration::Instance(self.parse_instance()?)),
            TokenValue::Default => Ok(TopDeclaration::Default(self.parse_default_declaration()?)),
            TokenValue::Foreign => Ok(TopDeclaration::Foreign(self.parse_foreign_declaration()?)),
            _ => Ok(TopDeclaration::Declaration(
                self.parse_declaration(DeclKind::Normal)?,
            )),
        }
    }

    pub(super) fn parse_declaration(&mut self, decl_kind: DeclKind) -> anyhow::Result<Declaration> {
        if decl_kind != DeclKind::Instance {
            if let Some(decl) = self.try_parse(&mut Self::parse_type_signature)? {
                return Ok(decl);
            } 
            if let Some(decl) = self.try_parse(&mut Self::parse_fixity_declaration)? {
                return Ok(decl);
            }
        }
        if let Some(fun) = self.try_parse(&mut Self::parse_function_lhs)? {
            let bind = self.parse_function_rhs()?;
            Ok(self.new_declaration(DeclarationValue::FunBind(fun, bind)))
        } else {
            if decl_kind == DeclKind::Normal {
                let pat = self.parse_pattern()?;
                let bind = self.parse_function_rhs()?;
                Ok(self.new_declaration(DeclarationValue::PatBind(pat, bind)))
            } else {
                let var = self.parse_var()?;
                let bind = self.parse_function_rhs()?;
                Ok(self.new_declaration(DeclarationValue::VarBind(var, bind)))
            }
        }
    }

    pub (super) fn parse_function_lhs(&mut self) -> anyhow::Result<FunBind> {
        if let Some(fun) = self.try_parse(&mut Self::parse_function_prefix)? {
            Ok(fun)
        } else if let Some(fun) = self.try_parse(&mut Self::parse_function_infix)? {
            Ok(fun)
        } else if let Some(fun) = self.try_parse(&mut Self::parse_function_wrapped)? {
            Ok(fun)
        } else {
            Err(self.error("Bad function definition lhs"))
        }
    }

    pub (super) fn parse_function_prefix(&mut self) -> anyhow::Result<FunBind> {
        let var = self.parse_var()?;
        let pats = self.parse_some1(&mut Self::parse_apattern)?;
        Ok(FunBind::Plain(var, pats))
    }

    pub (super) fn parse_function_infix(&mut self) -> anyhow::Result<FunBind> {
        let lhs = self.parse_pattern()?;
        let op = self.parse_varop()?;
        let rhs = self.parse_pattern()?;
        Ok(FunBind::Op(op, lhs, rhs))
    }

    pub (super) fn parse_function_wrapped(&mut self) -> anyhow::Result<FunBind> {
        self.expect(TokenValue::LeftParen)?;
        let fun = self.parse_function_lhs()?;
        self.expect(TokenValue::RightParen)?;
        let pats = self.parse_some1(&mut Self::parse_apattern)?;
        Ok(FunBind::Wrapped(Box::new(fun), pats))
    }

    pub (super) fn parse_function_rhs(&mut self) -> anyhow::Result<Binding> {
        if self.is_next(TokenValue::Equals)? {
            let exp = self.parse_expression()?;
            let where_decls = self.parse_optional_where()?;
            Ok(Binding::Plain(exp, where_decls))
        } else {
            let rhs = self.parse_some1(&mut Self::parse_function_rhs_guarded)?;
            let where_decls = self.parse_optional_where()?;
            Ok(Binding::Guarded(rhs, where_decls))
        }
    }

    pub (super) fn parse_optional_where(&mut self) -> anyhow::Result<Vec<Declaration>> {
        if self.is_next(TokenValue::Where)? {
            self.parse_some1(&mut |this| this.parse_declaration(DeclKind::Normal))
        } else {
            Ok(Vec::new())
        }
    }

    pub (super) fn parse_function_rhs_guarded(&mut self) -> anyhow::Result<GuardedExpression> {
        let guards = self.parse_guards()?;
        self.expect(TokenValue::Equals)?;
        let exp = self.parse_expression()?;
        Ok(GuardedExpression { guards: guards, body: exp })
    }

    pub (super) fn parse_guards(&mut self) -> anyhow::Result<Vec<SeqSyntax>> {
        self.expect(TokenValue::Bar)?;
        self.parse_separated_by(&mut |this| this.parse_seqsyntax(SeqKind::Guard), TokenValue::Comma)
    }

    pub (super) fn parse_default_declaration(&mut self) -> anyhow::Result<Vec<Type>> {
        self.expect(TokenValue::Default)?;
        self.parse_paren_list(&mut Self::parse_type)
    }

    pub (super) fn parse_type_signature(&mut self) -> anyhow::Result<Declaration> {
        let vars = self.parse_separated_by(&mut Self::parse_var, TokenValue::Comma)?;
        self.expect(TokenValue::DoubleColon)?;
        let context = self.try_parse(&mut |this| this.parse_context(false))?;
        let ty = self.parse_type()?;
        Ok(self.new_declaration(DeclarationValue::TypeSignature(vars, context, ty)))
    }

    pub(super) fn parse_fixity_declaration(&mut self) -> anyhow::Result<Declaration> {
        let assoc = match self.get_next_token()?.value {
            TokenValue::Infix => Association::NonAssociative,
            TokenValue::Infixl => Association::Left,
            TokenValue::Infixr => Association::Right,
            _ => return Err(self.error("Expected infix declaration")),
        };
        let prec = match self.peek_next_token()?.value {
            TokenValue::Integer(bn) => {
                let n: u32 = bn.try_into().unwrap_or(1000);
                if n > 9 {
                    return Err(self.error("precedence must be betweem 0 and 9"));
                }
                n
            }
            _ => 9,
        };
        let ops = self.parse_separated_by(&mut Self::parse_op, TokenValue::Comma)?;
        Ok(self.new_declaration(DeclarationValue::Fixity(ops, assoc, prec)))
    }
}