valkyrie-parser 0.2.5

The hand write parser of valkyrie language
Documentation
use crate::helpers::ProgramState;
use nyar_error::{FileID, NyarError, Result};
use pratt::{Affix, PrattParser, Precedence};
use std::str::FromStr;
use valkyrie_ast::*;
mod call_dot;
mod call_dot_closure;
mod call_dot_match;
mod call_generic;
mod control_flow;
mod operators;

impl crate::ExpressionRootNode {
    pub(crate) fn build(&self, ctx: &mut ProgramState) -> Result<StatementKind> {
        let expr = self.main_expression.build(ctx)?;
        let eos = self.eos.is_some();
        let ex = ExpressionNode { omit: eos, body: expr, span: self.span.clone() };
        Ok(StatementKind::Expression(Box::new(ex)))
    }
}

impl crate::MainExpressionNode {
    pub(crate) fn build(&self, ctx: &mut ProgramState) -> Result<ExpressionKind> {
        let mut stream = vec![];
        let (head, rest) = self.main_term.split_first().expect("at least one term");
        head.push_tokens(&mut stream, ctx)?;
        for (infix, rhs) in self.main_infix.iter().zip(rest.iter()) {
            stream.push(TokenStream::Infix(infix.as_operator()));
            rhs.push_tokens(&mut stream, ctx)?;
        }
        let mut parser = ExpressionResolver;
        let expr = parser.parse(stream.into_iter())?;
        Ok(expr)
    }
}
impl crate::InlineExpressionNode {
    pub(crate) fn build(&self, ctx: &mut ProgramState) -> Result<ExpressionKind> {
        let mut stream = vec![];
        let (head, rest) = self.inline_term.split_first().expect("at least one term");
        head.push_tokens(&mut stream, ctx)?;
        for (infix, rhs) in self.main_infix.iter().zip(rest.iter()) {
            stream.push(TokenStream::Infix(infix.as_operator()));
            rhs.push_tokens(&mut stream, ctx)?;
        }
        let mut parser = ExpressionResolver;
        let expr = parser.parse(stream.into_iter())?;
        Ok(expr)
    }
}
impl crate::TypeExpressionNode {
    pub fn build_external(&self, file: FileID) -> Result<ExpressionKind> {
        let mut stream = ProgramState::new(file);
        self.build(&mut stream)
    }
    pub(crate) fn build(&self, ctx: &mut ProgramState) -> Result<ExpressionKind> {
        let mut stream = vec![];
        let (head, rest) = self.type_term.split_first().expect("at least one term");
        head.push_tokens(&mut stream, ctx)?;
        for (infix, rhs) in self.type_infix.iter().zip(rest.iter()) {
            stream.push(TokenStream::Infix(infix.as_operator()));
            rhs.push_tokens(&mut stream, ctx)?;
        }
        let mut parser = ExpressionResolver;
        let expr = parser.parse(stream.into_iter())?;
        Ok(expr)
    }
}

impl crate::MainTermNode {
    fn push_tokens(&self, stream: &mut Vec<TokenStream>, ctx: &mut ProgramState) -> Result<()> {
        for i in &self.main_prefix {
            stream.push(TokenStream::Prefix(i.as_operator()))
        }
        let main = self.main_factor.build(ctx)?;
        stream.push(TokenStream::Term(main));
        for i in &self.main_suffix_term {
            stream.push(i.as_token(ctx)?)
        }
        Ok(())
    }
}
impl crate::InlineTermNode {
    fn push_tokens(&self, stream: &mut Vec<TokenStream>, ctx: &mut ProgramState) -> Result<()> {
        for i in &self.main_prefix {
            stream.push(TokenStream::Prefix(i.as_operator()))
        }
        let main = self.main_factor.build(ctx)?;
        stream.push(TokenStream::Term(main));
        for i in &self.inline_suffix_term {
            stream.push(i.as_token(ctx)?)
        }
        Ok(())
    }
}
impl crate::TypeTermNode {
    fn push_tokens(&self, stream: &mut Vec<TokenStream>, ctx: &mut ProgramState) -> Result<()> {
        for i in &self.type_prefix {
            stream.push(TokenStream::Prefix(i.as_operator()))
        }
        let main = self.main_factor.build(ctx)?;
        stream.push(TokenStream::Term(main));
        for i in &self.type_suffix_term {
            stream.push(i.as_token(ctx)?)
        }
        Ok(())
    }
}

struct ExpressionResolver;

#[derive(Debug)]
enum TokenStream {
    Prefix(OperatorNode),
    Infix(OperatorNode),
    Term(ExpressionKind),
    Postfix(OperatorNode),
    Subscript(SubscriptCallNode),
    Generic(GenericCallNode),
    Apply(ApplyCallNode),
    Dot(DotCallNode),
    DotMatch(MatchCallNode),
    DotClosure(ClosureCallNode),
}

impl<I> PrattParser<I> for ExpressionResolver
where
    I: Iterator<Item = TokenStream>,
{
    type Error = NyarError;
    type Input = TokenStream;
    type Output = ExpressionKind;

    fn query(&mut self, input: &Self::Input) -> Result<Affix> {
        let affix = match input {
            TokenStream::Prefix(v) => Affix::Prefix(v.kind.precedence()),
            TokenStream::Infix(v) => Affix::Infix(v.kind.precedence(), v.kind.associativity()),
            TokenStream::Term(_) => Affix::Nilfix,
            TokenStream::Postfix(v) => Affix::Postfix(v.kind.precedence()),
            _ => Affix::Postfix(Precedence(10000)),
        };
        Ok(affix)
    }

    fn primary(&mut self, input: Self::Input) -> Result<Self::Output> {
        match input {
            TokenStream::Term(v) => Ok(v),
            _ => unreachable!(),
        }
    }

    fn infix(&mut self, lhs: Self::Output, op: Self::Input, rhs: Self::Output) -> Result<Self::Output> {
        match op {
            TokenStream::Infix(v) => Ok(BinaryNode { infix: v, lhs, rhs }.into()),
            _ => unreachable!(),
        }
    }

    fn prefix(&mut self, op: Self::Input, rhs: Self::Output) -> Result<Self::Output> {
        match op {
            TokenStream::Prefix(v) => Ok(UnaryNode { operator: v, base: rhs }.into()),
            _ => unreachable!(),
        }
    }

    fn postfix(&mut self, lhs: Self::Output, op: Self::Input) -> Result<Self::Output> {
        match op {
            TokenStream::Postfix(v) => Ok(UnaryNode { operator: v, base: lhs }.into()),
            TokenStream::Subscript(call) => Ok(call.with_base(lhs).into()),
            TokenStream::Apply(call) => Ok(call.with_base(lhs).into()),
            TokenStream::Dot(call) => Ok(call.with_base(lhs).into()),
            TokenStream::Generic(call) => Ok(call.with_base(lhs).into()),
            TokenStream::DotMatch(call) => Ok(call.with_base(lhs).into()),
            TokenStream::DotClosure(call) => Ok(call.with_base(lhs).into()),
            _ => unreachable!(),
        }
    }
}

impl crate::MainFactorNode {
    pub(crate) fn build(&self, ctx: &mut ProgramState) -> Result<ExpressionKind> {
        match self {
            Self::Leading(v) => v.build(ctx),
            Self::GroupFactor(v) => v.main_expression.build(ctx),
            Self::NewStatement(v) => v.build(ctx).map(Into::into),
            Self::ObjectStatement(v) => v.build(ctx).map(Into::into),
            Self::DefineLambda(v) => v.build(ctx).map(Into::into),
            Self::TryStatement(v) => v.build(ctx).map(Into::into),
            Self::MatchExpression(v) => v.build(ctx).map(Into::into),
            Self::SwitchStatement(v) => v.build(ctx).map(Into::into),
        }
    }
}
impl crate::TypeFactorNode {
    pub(crate) fn build(&self, ctx: &mut ProgramState) -> Result<ExpressionKind> {
        match self {
            Self::Leading(v) => v.build(ctx),
            Self::TypeExpression(v) => v.build(ctx),
        }
    }
}

impl crate::MainSuffixTermNode {
    fn as_token(&self, ctx: &mut ProgramState) -> Result<TokenStream> {
        let token = match self {
            Self::InlineSuffixTerm(v) => v.as_token(ctx)?,
            Self::DotMatchCall(v) => TokenStream::DotMatch(v.build(ctx)?),
            Self::DotClosureCall(v) => TokenStream::DotClosure(v.build(ctx)?),
            Self::TupleCall(v) => TokenStream::Apply(v.build(ctx)?),
        };
        Ok(token)
    }
}

impl crate::InlineSuffixTermNode {
    fn as_token(&self, ctx: &mut ProgramState) -> Result<TokenStream> {
        let token = match self {
            Self::MainSuffix(v) => TokenStream::Postfix(v.as_operator()),
            Self::RangeCall(v) => TokenStream::Subscript(v.build(ctx)?),
            Self::InlineTupleCall(v) => TokenStream::Apply(v.build(ctx)?),
            Self::DotCall(v) => TokenStream::Dot(v.build(ctx)?),
            Self::GenericCall(v) => TokenStream::Generic(v.build(ctx)?),
        };
        Ok(token)
    }
}

impl crate::TypeSuffixTermNode {
    fn as_token(&self, ctx: &mut ProgramState) -> Result<TokenStream> {
        let token = match self {
            Self::GenericHide(v) => TokenStream::Generic(v.build_call(ctx)?),
            Self::TypeSuffix(v) => TokenStream::Postfix(v.as_operator()),
        };
        Ok(token)
    }
}