Add parse_expression convenience function

This commit is contained in:
Tad Hardesty 2019-12-08 00:29:39 -08:00
parent 034694d540
commit 5709cf031b
3 changed files with 20 additions and 9 deletions

View file

@ -391,11 +391,10 @@ impl fmt::Display for ConstFn {
pub fn evaluate_str(location: Location, input: &[u8]) -> Result<Constant, DMError> {
use super::lexer::{Lexer, from_utf8_or_latin1_borrowed};
use super::parser::Parser;
let mut bytes = input.iter().map(|&x| Ok(x));
let ctx = Context::default();
let expr = Parser::new(&ctx, Lexer::new(&ctx, Default::default(), &mut bytes)).require_expression()?;
let expr = crate::parser::parse_expression(&ctx, location, Lexer::new(&ctx, location.file, &mut bytes))?;
if bytes.next().is_some() {
return Err(DMError::new(location, format!("leftover: {:?} {}", from_utf8_or_latin1_borrowed(&input), bytes.len())));
}

View file

@ -26,6 +26,19 @@ where
Parser::new(context, iter.into_iter()).parse_object_tree()
}
/// Parse a token stream into an expression.
///
/// Fatal errors will be directly returned and miscellaneous diagnostics will
/// be registered with the provided `Context`.
pub fn parse_expression<I>(context: &Context, location: Location, iter: I) -> Result<Expression, DMError>
where
I: IntoIterator<Item=LocatedToken>,
{
let mut parser = Parser::new(context, iter.into_iter());
parser.set_fallback_location(location);
parser.require_expression()
}
type Ident = String;
// ----------------------------------------------------------------------------
@ -399,7 +412,7 @@ where
self.procs = true;
}
pub fn set_fallback_location(&mut self, fallback: Location) {
fn set_fallback_location(&mut self, fallback: Location) {
assert!(self.location == Default::default());
self.location = fallback;
}
@ -1571,7 +1584,7 @@ where
}
/// Parse an expression at the current position.
pub fn require_expression(&mut self) -> Result<Expression, DMError> {
fn require_expression(&mut self) -> Result<Expression, DMError> {
Ok(require!(self.expression()))
}

View file

@ -554,12 +554,11 @@ impl<'ctx> Preprocessor<'ctx> {
return Ok(false);
}
let mut parser = ::parser::Parser::new(
let expr = crate::parser::parse_expression(
self.context,
self.output.drain(..).map(|token| LocatedToken::new(start, token)),
);
parser.set_fallback_location(start);
let expr = parser.require_expression()?;
start,
self.output.drain(..).map(|token| LocatedToken::new(start, token))
)?;
Ok(::constants::preprocessor_evaluate(start, expr, &self.defines)?.to_bool())
}