Skip to content

Commit

Permalink
surface more errors
Browse files Browse the repository at this point in the history
  • Loading branch information
codekansas committed Oct 30, 2024
1 parent ccfd2b6 commit 861d2a2
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 135 deletions.
216 changes: 123 additions & 93 deletions klang/src/parser/expressions.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use super::ast::*;
use super::errors::ParseError;
use super::literals::{parse_identifier, parse_literal};
use super::parser::Rule;

pub(crate) fn parse_expression(pair: pest::iterators::Pair<Rule>) -> Expression {
pub(crate) fn parse_expression(
pair: pest::iterators::Pair<Rule>,
) -> Result<Expression, ParseError> {
match pair.as_rule() {
Rule::expression => parse_expression(pair.into_inner().next().unwrap()),
Rule::conditional => parse_conditional(pair),
Expand All @@ -16,115 +19,127 @@ pub(crate) fn parse_expression(pair: pest::iterators::Pair<Rule>) -> Expression
Rule::postfix => parse_postfix(pair),
Rule::primary => parse_primary(pair),
// _ => panic!("Unknown expression type: {:?}", pair.as_rule()),
_ => Expression { expr: None },
_ => Ok(Expression { expr: None }),
}
}

fn parse_conditional(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_conditional(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
3 => {
let condition = parse_expression(parts.next().unwrap());
let if_true = parse_expression(parts.next().unwrap());
let if_false = parse_expression(parts.next().unwrap());
let condition = parse_expression(parts.next().unwrap())?;
let if_true = parse_expression(parts.next().unwrap())?;
let if_false = parse_expression(parts.next().unwrap())?;

Expression {
Ok(Expression {
expr: Some(expression::Expr::Conditional(Box::new(ConditionalExpr {
condition: Some(Box::new(condition)),
then_expr: Some(Box::new(if_true)),
else_expr: Some(Box::new(if_false)),
}))),
}
})
}
_ => panic!(
"Unexpected number of parts in conditional: {:?}",
parts.len()
),
_ => Err(ParseError::from_pair(
format!(
"Unexpected number of parts in conditional: {:?}",
parts.len()
),
pair,
)),
}
}

fn parse_logical_or(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_logical_or(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
2 => {
let left = parse_expression(parts.next().unwrap());
let right = parse_expression(parts.next().unwrap());
let left = parse_expression(parts.next().unwrap())?;
let right = parse_expression(parts.next().unwrap())?;

Expression {
Ok(Expression {
expr: Some(expression::Expr::Binary(Box::new(BinaryExpr {
operator: BinaryOperator::Or.into(),
left: Some(Box::new(left)),
right: Some(Box::new(right)),
}))),
}
})
}
_ => panic!(
"Unexpected number of parts in logical or: {:?}",
parts.len()
),
_ => Err(ParseError::from_pair(
format!(
"Unexpected number of parts in logical or: {:?}",
parts.len()
),
pair,
)),
}
}

fn parse_logical_and(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_logical_and(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
2 => {
let left = parse_expression(parts.next().unwrap());
let right = parse_expression(parts.next().unwrap());
let left = parse_expression(parts.next().unwrap())?;
let right = parse_expression(parts.next().unwrap())?;

Expression {
Ok(Expression {
expr: Some(expression::Expr::Binary(Box::new(BinaryExpr {
operator: BinaryOperator::And.into(),
left: Some(Box::new(left)),
right: Some(Box::new(right)),
}))),
}
})
}
_ => panic!(
"Unexpected number of parts in logical and: {:?}",
parts.len()
),
_ => Err(ParseError::from_pair(
format!(
"Unexpected number of parts in logical and: {:?}",
parts.len()
),
pair,
)),
}
}

fn parse_equality(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_equality(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
3 => {
let left = parse_expression(parts.next().unwrap());
let left = parse_expression(parts.next().unwrap())?;
let operator = parts.next().unwrap();
let right = parse_expression(parts.next().unwrap());
let right = parse_expression(parts.next().unwrap())?;

let operator = match operator.as_str() {
"==" => BinaryOperator::Eq,
"!=" => BinaryOperator::NotEq,
_ => panic!("Unknown equality operator: {:?}", operator),
};

Expression {
Ok(Expression {
expr: Some(expression::Expr::Binary(Box::new(BinaryExpr {
operator: operator.into(),
left: Some(Box::new(left)),
right: Some(Box::new(right)),
}))),
}
})
}
_ => panic!("Unexpected number of parts in equality: {:?}", parts.len()),
_ => Err(ParseError::from_pair(
format!("Unexpected number of parts in equality: {:?}", parts.len()),
pair,
)),
}
}

fn parse_comparison(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_comparison(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
3 => {
let left = parse_expression(parts.next().unwrap());
let left = parse_expression(parts.next().unwrap())?;
let operator = parts.next().unwrap();
let right = parse_expression(parts.next().unwrap());
let right = parse_expression(parts.next().unwrap())?;

let operator = match operator.as_str() {
"<" => BinaryOperator::Lt,
Expand All @@ -134,138 +149,153 @@ fn parse_comparison(pair: pest::iterators::Pair<Rule>) -> Expression {
_ => panic!("Unknown comparison operator: {:?}", operator),
};

Expression {
Ok(Expression {
expr: Some(expression::Expr::Binary(Box::new(BinaryExpr {
operator: operator.into(),
left: Some(Box::new(left)),
right: Some(Box::new(right)),
}))),
}
})
}
_ => panic!(
"Unexpected number of parts in comparison: {:?}",
parts.len()
),
_ => Err(ParseError::from_pair(
format!(
"Unexpected number of parts in comparison: {:?}",
parts.len()
),
pair,
)),
}
}

fn parse_additive(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_additive(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
3 => {
let left = parse_expression(parts.next().unwrap());
let left = parse_expression(parts.next().unwrap())?;
let operator = parts.next().unwrap();
let right = parse_expression(parts.next().unwrap());
let right = parse_expression(parts.next().unwrap())?;

let operator = match operator.as_str() {
"+" => BinaryOperator::Add,
"-" => BinaryOperator::Sub,
_ => panic!("Unknown additive operator: {:?}", operator),
};

Expression {
Ok(Expression {
expr: Some(expression::Expr::Binary(Box::new(BinaryExpr {
operator: operator.into(),
left: Some(Box::new(left)),
right: Some(Box::new(right)),
}))),
}
})
}
_ => panic!("Unexpected number of parts in additive: {:?}", parts.len()),
_ => Err(ParseError::from_pair(
format!("Unexpected number of parts in additive: {:?}", parts.len()),
pair,
)),
}
}

fn parse_multiplicative(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_multiplicative(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
3 => {
let left = parse_expression(parts.next().unwrap());
let left = parse_expression(parts.next().unwrap())?;
let operator = parts.next().unwrap();
let right = parse_expression(parts.next().unwrap());
let right = parse_expression(parts.next().unwrap())?;

let operator = match operator.as_str() {
"*" => BinaryOperator::Mul,
"/" => BinaryOperator::Div,
_ => panic!("Unknown multiplicative operator: {:?}", operator),
};

Expression {
Ok(Expression {
expr: Some(expression::Expr::Binary(Box::new(BinaryExpr {
operator: operator.into(),
left: Some(Box::new(left)),
right: Some(Box::new(right)),
}))),
}
})
}
_ => panic!(
"Unexpected number of parts in multiplicative: {:?}",
parts.len()
),
_ => Err(ParseError::from_pair(
format!(
"Unexpected number of parts in multiplicative: {:?}",
parts.len()
),
pair,
)),
}
}

fn parse_unary(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_unary(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
2 => {
let operator = parts.next().unwrap();
let operand = parse_expression(parts.next().unwrap());
let operand = parse_expression(parts.next().unwrap())?;

let operator = match operator.as_str() {
"!" => UnaryOperator::Not,
"-" => UnaryOperator::Neg,
_ => panic!("Unknown unary operator: {:?}", operator),
};

Expression {
Ok(Expression {
expr: Some(expression::Expr::Unary(Box::new(UnaryExpr {
operator: operator.into(),
operand: Some(Box::new(operand)),
}))),
}
})
}
_ => panic!("Unexpected number of parts in unary: {:?}", parts.len()),
_ => Err(ParseError::from_pair(
format!("Unexpected number of parts in unary: {:?}", parts.len()),
pair,
)),
}
}

fn parse_postfix(pair: pest::iterators::Pair<Rule>) -> Expression {
let mut parts = pair.into_inner();
fn parse_postfix(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let mut parts = pair.clone().into_inner();
match parts.len() {
1 => parse_expression(parts.next().unwrap()),
2 => {
let operand = parse_expression(parts.next().unwrap());
let argument_list = parse_argument_list(parts.next().unwrap());
let operand = parse_expression(parts.next().unwrap())?;
let argument_list = parse_argument_list(parts.next().unwrap())?;

Expression {
Ok(Expression {
expr: Some(expression::Expr::FunctionCall(Box::new(FunctionCallExpr {
function: Some(Box::new(operand)),
arguments: argument_list,
}))),
}
})
}
_ => panic!("Unexpected number of parts in postfix: {:?}", parts.len()),
_ => Err(ParseError::from_pair(
format!("Unexpected number of parts in postfix: {:?}", parts.len()),
pair,
)),
}
}

fn parse_argument_list(pair: pest::iterators::Pair<Rule>) -> Vec<Argument> {
pair.into_inner()
.map(|p| {
let mut parts = p.into_inner();
let identifier = parts.next().unwrap();
let expression = parse_expression(parts.next().unwrap());
fn parse_argument_list(pair: pest::iterators::Pair<Rule>) -> Result<Vec<Argument>, ParseError> {
let mut arguments = Vec::new();
for p in pair.into_inner() {
let mut parts = p.into_inner();
let identifier = parts.next().unwrap();
let expression = parse_expression(parts.next().unwrap())?;

Argument {
name: identifier.as_str().to_string(),
value: Some(expression),
}
})
.collect()
arguments.push(Argument {
name: identifier.as_str().to_string(),
value: Some(expression),
});
}
Ok(arguments)
}

fn parse_primary(pair: pest::iterators::Pair<Rule>) -> Expression {
fn parse_primary(pair: pest::iterators::Pair<Rule>) -> Result<Expression, ParseError> {
let parts = pair.into_inner();
match parts.len() {
1 => {
Expand Down
2 changes: 1 addition & 1 deletion klang/src/parser/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub(crate) fn parse_function_def(function_def: Pair<Rule>) -> Result<FunctionDef
Rule::identifier => name = part.as_str().to_string(),
Rule::parameter_list => parameters = parse_parameters(part)?,
Rule::doc_string => doc_string = parse_doc_string(part)?,
Rule::block => body = Some(parse_block(part)),
Rule::block => body = Some(parse_block(part)?),
_ => {
return Err(ParseError::from_pair(
format!("Unknown rule: {:?}", part.as_rule()),
Expand Down
Loading

0 comments on commit 861d2a2

Please sign in to comment.