Improved bug implementations
This commit is contained in:
+2
-1
@@ -20,7 +20,8 @@ pub struct AstError<'a, T> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ErrorCode {
|
pub enum ErrorCode {
|
||||||
InvalidStatement = 200,
|
InvalidStatement,
|
||||||
|
AstGenBug,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<pest::error::Error<Rule>> for ParseError<'_, T> {
|
impl<T> From<pest::error::Error<Rule>> for ParseError<'_, T> {
|
||||||
|
|||||||
@@ -32,6 +32,22 @@ pub fn parse<'a>(source: &'a str) -> Result<Vec<TopLevel>, ParseError<'a, Vec<To
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! ast_ensure {
|
||||||
|
($pair:expr, $rule:expr => $body:block) => {
|
||||||
|
if $pair.as_rule() == $rule
|
||||||
|
$body
|
||||||
|
else {
|
||||||
|
Err(AstError {
|
||||||
|
span: $pair.as_span(),
|
||||||
|
error_code: crate::error::ErrorCode::AstGenBug,
|
||||||
|
error_message: format!("Possible bug: expected {:?}, got {}", $rule, $pair),
|
||||||
|
recovered: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! ast_expr {
|
macro_rules! ast_expr {
|
||||||
($($item:ident)::+ { $($k:ident: $v:expr),* $(,)? }) => {{
|
($($item:ident)::+ { $($k:ident: $v:expr),* $(,)? }) => {{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ pub mod types;
|
|||||||
use crate::{
|
use crate::{
|
||||||
Rule,
|
Rule,
|
||||||
ast::*,
|
ast::*,
|
||||||
|
ast_ensure,
|
||||||
error::{AstError, IntoErr, collect_recovered},
|
error::{AstError, IntoErr, collect_recovered},
|
||||||
parser::consume_rule,
|
parser::consume_rule,
|
||||||
};
|
};
|
||||||
@@ -14,7 +15,9 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Identifier {
|
|||||||
type Error = AstError<'a, Self>;
|
type Error = AstError<'a, Self>;
|
||||||
|
|
||||||
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
||||||
|
ast_ensure!(pair, Rule::identifier => {
|
||||||
Ok(Identifier(pair.as_str().to_string()))
|
Ok(Identifier(pair.as_str().to_string()))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Rule,
|
Rule,
|
||||||
ast::*,
|
ast::*,
|
||||||
ast_expr,
|
ast_ensure, ast_expr,
|
||||||
error::{AstError, AstResult, ErrorCode, IntoErr, collect_recovered},
|
error::{AstError, AstResult, ErrorCode, IntoErr, collect_recovered},
|
||||||
parser::listen_rule,
|
parser::listen_rule,
|
||||||
};
|
};
|
||||||
@@ -10,19 +10,25 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
|
|||||||
type Error = AstError<'a, Self>;
|
type Error = AstError<'a, Self>;
|
||||||
|
|
||||||
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
||||||
if pair.as_rule() == Rule::block {
|
ast_ensure!(pair, Rule::block => {
|
||||||
ast_expr!(Block(collect_recovered(pair.into_inner())))
|
ast_expr!(Block(collect_recovered(pair.into_inner())))
|
||||||
} else {
|
|
||||||
Err(AstError {
|
|
||||||
span: pair.as_span(),
|
|
||||||
error_code: ErrorCode::InvalidStatement,
|
|
||||||
error_message: format!(
|
|
||||||
"BUG: AST requires a block, this isn't a block, it's a {:?}",
|
|
||||||
pair.as_rule()
|
|
||||||
),
|
|
||||||
recovered: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
|
||||||
|
type Error = AstError<'a, Self>;
|
||||||
|
|
||||||
|
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
||||||
|
let mut inner = pair.into_inner();
|
||||||
|
|
||||||
|
let condition = inner.next().unwrap().try_into().get()?;
|
||||||
|
let body = inner.next().unwrap().try_into().get()?;
|
||||||
|
|
||||||
|
Ok(StatementBranch {
|
||||||
|
condition,
|
||||||
|
body: Box::new(body),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,19 +120,3 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
|
|
||||||
type Error = AstError<'a, Self>;
|
|
||||||
|
|
||||||
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
|
|
||||||
let mut inner = pair.into_inner();
|
|
||||||
|
|
||||||
let condition = inner.next().unwrap().try_into().get()?;
|
|
||||||
let body = inner.next().unwrap().try_into().get()?;
|
|
||||||
|
|
||||||
Ok(StatementBranch {
|
|
||||||
condition,
|
|
||||||
body: Box::new(body),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user