mirror of
https://github.com/Noratrieb/dilaria.git
synced 2026-01-14 17:35:03 +01:00
use macro for binop parse
This commit is contained in:
parent
1c63f198dc
commit
64a747850c
1 changed files with 22 additions and 52 deletions
74
src/parse.rs
74
src/parse.rs
|
|
@ -20,6 +20,19 @@ struct Parser<'code> {
|
||||||
|
|
||||||
type ParseResult<'code, T> = Result<T, ParseErr<'code>>;
|
type ParseResult<'code, T> = Result<T, ParseErr<'code>>;
|
||||||
|
|
||||||
|
macro_rules! parse_bin_op {
|
||||||
|
($self: ident, $lhs: ident, $kind: expr, $function: ident) => {{
|
||||||
|
let _ = $self.next();
|
||||||
|
let rhs = $self.$function()?;
|
||||||
|
Ok(Expr::BinaryOp(Box::new(BinaryOp {
|
||||||
|
span: $lhs.span().extend(rhs.span()),
|
||||||
|
lhs: $lhs,
|
||||||
|
rhs,
|
||||||
|
kind: $kind,
|
||||||
|
})))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
impl<'code> Parser<'code> {
|
impl<'code> Parser<'code> {
|
||||||
fn program(&mut self) -> ParseResult<'code, Program> {
|
fn program(&mut self) -> ParseResult<'code, Program> {
|
||||||
Ok(Program(self.block()?))
|
Ok(Program(self.block()?))
|
||||||
|
|
@ -86,25 +99,13 @@ impl<'code> Parser<'code> {
|
||||||
fn comparison(&mut self) -> ParseResult<'code, Expr> {
|
fn comparison(&mut self) -> ParseResult<'code, Expr> {
|
||||||
let lhs = self.term()?;
|
let lhs = self.term()?;
|
||||||
match self.peek().map(|token| &token.kind) {
|
match self.peek().map(|token| &token.kind) {
|
||||||
Some(TokenType::Greater) => {
|
Some(TokenType::Greater) => parse_bin_op!(self, lhs, BinaryOpKind::Greater, term),
|
||||||
let _ = self.next();
|
|
||||||
let rhs = self.term()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::Greater, rhs)
|
|
||||||
}
|
|
||||||
Some(TokenType::GreaterEqual) => {
|
Some(TokenType::GreaterEqual) => {
|
||||||
let _ = self.next();
|
parse_bin_op!(self, lhs, BinaryOpKind::GreaterEqual, term)
|
||||||
let rhs = self.term()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::GreaterEqual, rhs)
|
|
||||||
}
|
|
||||||
Some(TokenType::Less) => {
|
|
||||||
let _ = self.next();
|
|
||||||
let rhs = self.term()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::Less, rhs)
|
|
||||||
}
|
}
|
||||||
|
Some(TokenType::Less) => parse_bin_op!(self, lhs, BinaryOpKind::Less, term),
|
||||||
Some(TokenType::LessEqual) => {
|
Some(TokenType::LessEqual) => {
|
||||||
let _ = self.next();
|
parse_bin_op!(self, lhs, BinaryOpKind::LessEqual, term)
|
||||||
let rhs = self.term()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::LessEqual, rhs)
|
|
||||||
}
|
}
|
||||||
_ => Ok(lhs),
|
_ => Ok(lhs),
|
||||||
}
|
}
|
||||||
|
|
@ -113,16 +114,8 @@ impl<'code> Parser<'code> {
|
||||||
fn term(&mut self) -> ParseResult<'code, Expr> {
|
fn term(&mut self) -> ParseResult<'code, Expr> {
|
||||||
let lhs = self.factor()?;
|
let lhs = self.factor()?;
|
||||||
match self.peek().map(|token| &token.kind) {
|
match self.peek().map(|token| &token.kind) {
|
||||||
Some(TokenType::Plus) => {
|
Some(TokenType::Plus) => parse_bin_op!(self, lhs, BinaryOpKind::Add, term),
|
||||||
let _ = self.next();
|
Some(TokenType::Minus) => parse_bin_op!(self, lhs, BinaryOpKind::Sub, term),
|
||||||
let rhs = self.factor()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::Add, rhs)
|
|
||||||
}
|
|
||||||
Some(TokenType::Minus) => {
|
|
||||||
let _ = self.next();
|
|
||||||
let rhs = self.factor()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::Sub, rhs)
|
|
||||||
}
|
|
||||||
_ => Ok(lhs),
|
_ => Ok(lhs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -130,21 +123,9 @@ impl<'code> Parser<'code> {
|
||||||
fn factor(&mut self) -> ParseResult<'code, Expr> {
|
fn factor(&mut self) -> ParseResult<'code, Expr> {
|
||||||
let lhs = self.unary()?;
|
let lhs = self.unary()?;
|
||||||
match self.peek().map(|token| &token.kind) {
|
match self.peek().map(|token| &token.kind) {
|
||||||
Some(TokenType::Asterisk) => {
|
Some(TokenType::Asterisk) => parse_bin_op!(self, lhs, BinaryOpKind::Mul, term),
|
||||||
let _ = self.next();
|
Some(TokenType::Slash) => parse_bin_op!(self, lhs, BinaryOpKind::Div, term),
|
||||||
let rhs = self.unary()?;
|
Some(TokenType::Percent) => parse_bin_op!(self, lhs, BinaryOpKind::Mod, term),
|
||||||
self.binary_op(lhs, BinaryOpKind::Mul, rhs)
|
|
||||||
}
|
|
||||||
Some(TokenType::Slash) => {
|
|
||||||
let _ = self.next();
|
|
||||||
let rhs = self.unary()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::Div, rhs)
|
|
||||||
}
|
|
||||||
Some(TokenType::Percent) => {
|
|
||||||
let _ = self.next();
|
|
||||||
let rhs = self.unary()?;
|
|
||||||
self.binary_op(lhs, BinaryOpKind::Mod, rhs)
|
|
||||||
}
|
|
||||||
_ => Ok(lhs),
|
_ => Ok(lhs),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,17 +195,6 @@ impl<'code> Parser<'code> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
// other helpers
|
|
||||||
|
|
||||||
fn binary_op(&mut self, lhs: Expr, kind: BinaryOpKind, rhs: Expr) -> ParseResult<'code, Expr> {
|
|
||||||
Ok(Expr::BinaryOp(Box::new(BinaryOp {
|
|
||||||
span: lhs.span().extend(rhs.span()),
|
|
||||||
lhs,
|
|
||||||
rhs,
|
|
||||||
kind,
|
|
||||||
})))
|
|
||||||
}
|
|
||||||
|
|
||||||
// token helpers
|
// token helpers
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue