reqlang-expr 0.7.0

A tiny (bytecode compiled, stack VM interpreted) expression language for reqlang's templating engine.
Documentation
//! Parser and associated types

use crate::errors::{ExprErrorS, SyntaxError};
use crate::ast;
use crate::lexer::Token;
use crate::span::Spanned;

grammar<'err>(source: &str, errors: &'err mut Vec<ExprErrorS>);

pub Expr: ast::Expr = {
    ExprIdentifier,
    ExprCall,
    ExprString,
    ExprBool,
    <e:!> => {
        errors.push(SyntaxError::from_parser_error(e.error, source));
        ast::Expr::Error
    }
};

// Boolean Expressions

ExprBool: ast::Expr = {
    "true" => ast::Expr::Bool(ast::ExprBool(true).into()),
    "false" => ast::Expr::Bool(ast::ExprBool(false).into()),
};

// String Expressions

ExprString: ast::Expr = {
    string => ast::Expr::String(ast::ExprString(<>).into())
};

// Call Expressions

CallCallee = ExprS;
CallArgs = Args<ExprS>;
ExprCall: ast::Expr = {
    "(" <callee:CallCallee> <args:CallArgs> ")" => ast::Expr::Call(ast::ExprCall {
        callee,
        args
    }.into())
}

// Identifier Expressions

ExprIdentifier: ast::Expr = <name:identifier> =>
    ast::Expr::Identifier(ast::ExprIdentifier(name).into());

// Utility Types

ExprS = Spanned<Expr>;

Spanned<T>: Spanned<T> = <l:@L> <t:T> <r:@R> =>
    (t, l..r);

#[inline]
Args<E>: Vec<E> = {
    <first:E> <mut args:(<E>)*> => {
        args.insert(0, first);
        args
    },
    () => Vec::new(),
}

extern {
    type Location = usize;
    type Error = ExprErrorS;

    enum Token {
        "(" => Token::LParan,
        ")" => Token::RParan,
        "true" => Token::True,
        "false" => Token::False,
        string => Token::String(<String>),
        identifier => Token::Identifier(<String>),
    }
}