Skip to content
Snippets Groups Projects
Select Git revision
  • 3c6aef08e4aed4eeaede18a66a45c793c33a07f2
  • master default protected
  • experimental
  • itm_trace
4 results

r

Blame
  • tmp.rs 4.82 KiB
    extern crate nom;
    
    use std::iter::Peekable;
    use std::slice::Iter;
    
    use nom::{
        branch::alt,
        bytes::complete::tag,
        character::complete::char,
        character::complete::{digit1, multispace0},
        combinator::{cut, map},
        error::ParseError,
        multi::many1,
        sequence::{delimited, preceded},
        IResult,
    };
    
    use crust::ast::{Op, Expr};
    
    
    pub fn parse_i32(i: &str) -> IResult<&str, i32> {
        map(digit1, |digit_str: &str| digit_str.parse::<i32>().unwrap())(i)
    }
    
    fn parse_op(i: &str) -> IResult<&str, Op> {
        alt((
            map(tag("=="), |_| Op::Eq),
            map(tag("!="), |_| Op::Neq),
            map(tag("**"), |_| Op::Pow),
            map(tag("&&"), |_| Op::And),
            map(tag("||"), |_| Op::Or),
            map(tag("+"), |_| Op::Add),
            map(tag("-"), |_| Op::Sub),
            map(tag("*"), |_| Op::Mul),
            map(tag("/"), |_| Op::Div),
            map(tag("!"), |_| Op::Not),
        ))(i)
    }
    
    #[derive(Debug, Clone, PartialEq)]
    pub enum Token {
        Num(i32),
        Par(Vec<Token>),
        Op(Op),
    }
    
    fn parse_terminal(i: &str) -> IResult<&str, Token> {
        alt((
            map(parse_i32, |v| Token::Num(v)),
            map(parse_par(parse_tokens), |tokens| Token::Par(tokens)),
        ))(i)
    }
    
    fn parse_token(i: &str) -> IResult<&str, Token> {
        preceded(
            multispace0,
            alt((map(parse_op, |op| Token::Op(op)), parse_terminal)),
        )(i)
    }
    
    fn parse_tokens(i: &str) -> IResult<&str, Vec<Token>> {
        many1(parse_token)(i)
    }
    
    fn compute_atom(t: &mut Peekable<Iter<Token>>) -> Expr {
        match t.next() {
            Some(Token::Num(i)) => Expr::Num(*i),
            Some(Token::Par(v)) => climb(&mut v.iter().peekable(), 0),
            Some(Token::Op(op)) => Expr::UnaryOp(*op, Box::new(climb(t, 4))), // assume highest precedence
            _ => panic!("error in compute atom"),