rugs 0.0.1

A WIP Haskell implementation
Documentation
use super::declaration::DeclKind;
use super::helpers::error;
use super::lexing::{Token, TokenValue};
use super::ParserState;
use crate::{ast::*, location::Location};

impl<'a> ParserState<'a> {
    pub(super) fn parse_expression(&mut self) -> anyhow::Result<Expression> {
        let exp = self.parse_infix_expression()?;
        if self.is_next(TokenValue::DoubleColon)? {
            let context = self
                .try_parse(&mut |this| this.parse_context(false))?
                .unwrap_or(self.new_context());
            let ty = self.parse_type()?;
            Ok(self.typed(exp, context, ty))
        } else {
            Ok(exp)
        }
    }

    fn parse_infix_expression(&mut self) -> anyhow::Result<Expression> {
        if self.is_next(Token::varsym("-").value)? {
            let exp = self.parse_expression()?;
            let negate = self.var(varid("-"));
            return Ok(self.app(negate, exp)); // TODO: This will need to take part in precedence later
        }
        let exp = self.parse_lexp()?;
        if let Some(op) = self.try_parse(&mut Self::parse_qop)? {
            let exp_right = self.parse_infix_expression()?;
            Ok(self.infix(op, exp, exp_right))
        } else {
            Ok(exp)
        }
    }

    fn parse_lexp(&mut self) -> anyhow::Result<Expression> {
        let tok = self.peek_next_token()?;
        match tok.value {
            TokenValue::Backslash => self.parse_lambda_expression(),
            TokenValue::Let => self.parse_let_expression(),
            TokenValue::If => self.parse_if_expression(),
            TokenValue::Case => self.parse_case_expression(),
            TokenValue::Do => self.parse_do_expression(),
            _ => self.parse_fexp(),
        }
    }

    fn parse_fexp(&mut self) -> anyhow::Result<Expression> {
        let mut exp = self.parse_aexp()?;
        let aexps = self.parse_some(&mut Self::parse_aexp)?;
        for arg in aexps {
            exp = self.app(exp, arg);
        }
        Ok(exp)
    }

    fn parse_aexp(&mut self) -> anyhow::Result<Expression> {
        let tok = self.get_next_token()?;
        let tok2 = tok.clone();
        let expr = match tok.value {
            TokenValue::LeftParen => self.parse_parens_exp()?,
            TokenValue::LeftBracket => self.parse_bracket_exp()?,
            TokenValue::QConId(_, _)
            | TokenValue::QVarId(_, _)
            | TokenValue::ConId(_)
            | TokenValue::VarId(_) => self.var(Identifier::try_from(tok)?),
            TokenValue::Char(ch) => self.char_const(&ch),
            TokenValue::Float(d) => self.float(&d),
            TokenValue::Integer(bn) => self.integer(bn),
            TokenValue::String(s) => self.string_const(&s),
            t => return error(&format!("unexpected token {:?} in aexp", t), tok.location),
        };
        if self.peek_next(TokenValue::LeftBrace)? {
            let rec_expr = self.parse_record_expression()?;
            match tok2.value {
                TokenValue::QConId(_, _) | TokenValue::ConId(_) => Ok(self.record_constr(Token::try_into(tok2)?, rec_expr)),
                _ => {
                    if rec_expr.is_empty() {
                        Err(self.error("Empty record update"))
                    } else {
                        Ok(self.record_update(expr, rec_expr))
                    }
                }
            }

        } else {
            Ok(expr)
        }
    }

    fn parse_parens_exp(&mut self) -> anyhow::Result<Expression> {
        let tok = self.peek_next_token()?;
        let exp = match tok.value {
            TokenValue::RightParen => {
                self.get_next_token()?;
                return Ok(self.var(conid("()")));
            }
            TokenValue::Comma => {
                let mut con = "(".to_string();
                while self.is_next(TokenValue::Comma)? {
                    con.push(',');
                }
                self.expect(TokenValue::RightParen)?;
                con.push(')');
                return Ok(self.var(conid(&con)));
            }
            _ => self.parse_expression()?,
        };
        let tok = self.get_next_token()?;
        match tok.value {
            TokenValue::RightParen => Ok(self.wrapped(exp)),
            TokenValue::Comma => {
                let mut tuple = vec![exp];
                loop {
                    let e = self.parse_expression()?;
                    tuple.push(e);
                    let tok = self.get_next_token()?;
                    match tok.value {
                        TokenValue::Comma => {}
                        TokenValue::RightParen => break,
                        _ => {
                            return error(
                                &format!("Unexpected token {:?} in tuple expression", tok),
                                tok.location,
                            )
                        }
                    }
                }
                Ok(self.tuple(tuple))
            }
            _ => {
                return error(
                    &format!("Expected right paren or comma, got {:?}", tok),
                    tok.location,
                )
            }
        }
    }

    fn parse_if_expression(&mut self) -> anyhow::Result<Expression> {
        self.expect(TokenValue::If)?;
        let predicate = self.parse_expression()?;
        self.optional_semicolon()?;
        self.expect(TokenValue::Then)?;
        let then_exp = self.parse_expression()?;
        self.optional_semicolon()?;
        self.expect(TokenValue::Else)?;
        let else_exp = self.parse_expression()?;
        Ok(self.if_expression(predicate, then_exp, else_exp))
    }

    fn parse_let_expression(&mut self) -> anyhow::Result<Expression> {
        self.expect(TokenValue::Let)?;
        let decls = self.parse_braced_list(&mut |this, is_virtual| {
            let res = this.parse_declaration(DeclKind::Normal)?;
            Ok(res)
        })?;
        self.expect(TokenValue::In)?;
        let exp = self.parse_expression()?;
        Ok(self.let_expression(decls, exp))
    }

    fn parse_lambda_expression(&mut self) -> anyhow::Result<Expression> {
        self.expect(TokenValue::Backslash)?;
        let mut args = Vec::new();
        loop {
            let pat = self.parse_apattern()?;
            args.push(pat);
            if self.is_next(TokenValue::RightArrow)? {
                break;
            }
        }
        let exp = self.parse_expression()?;
        Ok(self.lambda(args, exp))
    }

    fn parse_case_expression(&mut self) -> anyhow::Result<Expression> {
        self.expect(TokenValue::Case)?;
        let exp = self.parse_expression()?;
        self.expect(TokenValue::Of)?;
        let alts = self.parse_braced_list(&mut ParserState::parse_case_alt)?;
        Ok(self.case_expression(exp, alts))
    }

    fn parse_do_expression(&mut self) -> anyhow::Result<Expression> {
        self.expect(TokenValue::Do)?;
        let stmts = self.parse_braced_list(&mut |this, _| this.parse_seqsyntax(SeqKind::Do))?;
        Ok(self.do_expression(stmts))
    }

    fn parse_bracket_exp(&mut self) -> anyhow::Result<Expression> {
        if let Some((start, step)) = self.try_parse(&mut |this| {
            let first = this.parse_expression()?;
            let step = if this.is_next(TokenValue::Comma)? {
                Some(this.parse_expression()?)
            } else {
                None
            };
            this.expect(TokenValue::DotDot)?;
            Ok((first, step))
        })? {
            let stop = self.try_parse(&mut Self::parse_expression)?;
            self.expect(TokenValue::RightBracket)?;
            match (step, stop) {
                (Some (a), Some(b)) => {
                    let f = self.var(varid("enumFromThenTo"));
                    Ok(self.apps(f, vec![start, a, b]))
                },
                (Some (a), None) => {
                    let f = self.var(varid("enumFromThen"));
                    Ok(self.apps(f, vec![start, a]))
                },
                (None, Some (b)) => {
                    let f = self.var(varid("enumFromTo"));
                    Ok(self.apps(f, vec![start, b]))
                },
                (None, None) => {
                    let f = self.var(varid("enumFrom"));
                    Ok(self.app(f, start))
                }
            }
        } else if let Some(exp) = self.try_parse(&mut |this| {
            let first = this.parse_expression()?;
            this.expect(TokenValue::Bar)?;
            Ok(first)
        })? {
            let quals = self.parse_separated_by(&mut |this| this.parse_seqsyntax(SeqKind::Comprehension), TokenValue::Comma)?;
            Ok(self.comprehension(exp, quals))
        } else {
            let exps = self.parse_separated_by(&mut Self::parse_expression, TokenValue::Comma)?;
            self.expect(TokenValue::RightBracket)?;
            Ok(self.list(exps))
        }
    }

    fn parse_case_alt(&mut self, is_virtual: bool) -> anyhow::Result<CaseAlt> {
        let pat = self.parse_pattern()?;
        if self.is_next(TokenValue::RightArrow)? {
            let exp = self.parse_expression()?;
            Ok(CaseAlt::Simple(pat, exp))
        } else {
            let guardexps = self.parse_some1(&mut Self::parse_case_guarded)?;
            Ok(CaseAlt::Guarded(pat, guardexps))
        }  
    }

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

    pub (super) fn parse_seqsyntax(&mut self, kind: SeqKind) -> anyhow::Result<SeqSyntax> {
        let expfn = if kind == SeqKind::Guard {
            |this:&mut ParserState| this.parse_infix_expression()
        } else {
            |this:&mut ParserState| this.parse_expression()
        };
        if self.is_next(TokenValue::Let)? {
            let decls = self.parse_braced_list(&mut |this,_| this.parse_declaration(DeclKind::Normal))?;
            Ok(SeqSyntax::Decls(decls))
        } else if let Some(pat) = self.try_parse(&mut |this|{
            let pat = this.parse_pattern()?;
            this.expect(TokenValue::LeftArrow)?;
            Ok(pat)
        })? {
            let exp = expfn(self)?;
            Ok(SeqSyntax::Pattern(pat, exp))
        } else if kind == SeqKind::Do && self.is_next(TokenValue::Semicolon)? {
                Ok(SeqSyntax::Empty)
        } else {
            let exp = expfn(self)?;
            Ok(SeqSyntax::Expr(exp))
        }
    }

    pub (super) fn parse_record_expression(&mut self) -> anyhow::Result< Vec<(Identifier, Expression)>> {
        self.parse_separated_by(&mut Self::parse_record_field, TokenValue::Comma)
    }

    pub (super) fn parse_record_field(&mut self) -> anyhow::Result<(Identifier, Expression)> {
        let var = self.parse_qvar()?;
        self.expect(TokenValue::Equals)?;
        let exp = self.parse_expression()?;
        Ok((var, exp))
    }
}