#![warn(missing_docs)]
extern crate idata;
extern crate im;
use std::result;
#[macro_use]
pub(crate) mod macros;
pub(crate) mod ast;
pub(crate) mod gcode;
pub(crate) mod ir;
pub(crate) mod parser;
pub(crate) mod rules_for_peg;
pub struct Peg<'a>(&'a str);
#[derive(Debug)]
pub enum Error {
ParserErr(crate::parser::Error),
ReplaceErr(String),
IRErr(crate::ir::Error),
}
impl<'a> Peg<'a> {
pub fn new(txt: &'a str) -> Self {
Self(txt)
}
pub fn gen_rules(&self) -> result::Result<crate::parser::expression::SetOfRules, Error> {
use crate::ir::IR;
let irtxt = crate::rules_for_peg::rules().parse(self.0)?.replace(None)?;
let ir = IR::new(&irtxt.str());
Ok(ir.get_rules().unwrap())
}
}
impl crate::parser::expression::SetOfRules {
pub fn parse(&self, text: &str) -> Result<ast::Node, Error> {
crate::parse(text, self).map_err(|e| Error::ParserErr(e))
}
pub fn parse_debug(&self, text: &str) -> Result<ast::Node, Error> {
crate::parse_debug(text, self).map_err(|e| Error::ParserErr(e))
}
}
pub fn print_rules2parse_peg2() {
use crate::ir::IR;
let irtxt = crate::rules_for_peg::rules()
.parse(gcode::peg2code::text_peg2code())
.unwrap()
.replace(None)
.unwrap();
let ir = IR::new(&irtxt.str());
let rules = ir.get_rules().unwrap();
let r = crate::gcode::rust_from_rules(&rules);
let r = r;
println!("{}", r);
}
pub struct FnCallBack(pub fn(&str) -> Option<String>);
impl ast::Node {
pub fn replace(
&self,
fcallback: Option<&FnCallBack>,
) -> Result<crate::ast::replace::Replaced, Error> {
ast::replace::replace(&self, fcallback).map_err(|e| Error::ReplaceErr(e))
}
}
fn parse(s: &str, rules: &parser::expression::SetOfRules) -> Result<ast::Node, parser::Error> {
parse_with_debug(s, rules, false)
}
fn parse_debug(
s: &str,
rules: &parser::expression::SetOfRules,
) -> Result<ast::Node, parser::Error> {
parse_with_debug(s, rules, true)
}
fn parse_with_debug(
s: &str,
rules: &parser::expression::SetOfRules,
debug: bool,
) -> Result<ast::Node, parser::Error> {
let (st, ast) = if debug {
parser::expression::parse(parser::Status::init_debug(s, &rules, debug))?
} else {
parser::expression::parse(parser::Status::init(s, &rules))?
};
match (st.pos.n == s.len(), st.potential_error.clone()) {
(true, _) => Ok(ast),
(false, Some(e)) => Err(e),
(false, None) => Err(parser::Error::from_status_normal(
&st,
"not consumed full input",
)),
}
}