Skip to content

Commit

Permalink
🚧 WIP
Browse files Browse the repository at this point in the history
semver: chore
  • Loading branch information
Lucas de Jong committed Oct 28, 2024
1 parent f17c1d3 commit 8853e48
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 33 deletions.
22 changes: 5 additions & 17 deletions src/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ pub fn parse<'de>(
}
.with_source_code(parser.source.to_string()),
)?;

let mut lhs = handler(parser)?;

while let Some(token) = parser.lexer.peek() {
let mut next_token = parser.lexer.peek();

while let Some(token) = next_token {
let token = match token {
Ok(token) => token,
Err(err) => return Err(miette::miette!(err.to_string())), // FIXME: better error handling
Expand All @@ -64,22 +65,9 @@ pub fn parse<'de>(
parser.lexer.next();

lhs = handler(parser, lhs, token_binding_power)?;

next_token = parser.lexer.peek();
}

Ok(lhs)
}

pub fn add_handlers<'de>(lookup: &'de mut Lookup<'de>) {
lookup.add_left_expression_handler(
TokenKind::Plus,
BindingPower::Additive,
|parser: &mut Parser<'_>, lhs: Expression<'_>, bp| -> Result<Expression<'_>> {
let rhs = parse(parser, bp)?;
Ok(Expression::Binary {
operator: BinaryOperator::Add,
left: Box::new(lhs),
right: Box::new(rhs),
})
},
);
}
64 changes: 48 additions & 16 deletions src/parser/lookup.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::lexer::TokenKind;
use crate::lexer::{TokenKind, TokenValue};
use miette::Result;
use std::collections::HashMap;

use super::{
ast::{Expression, Statement},
ast::{BinaryOperator, Expression, Primitive, Statement},
expression, Parser,
};

Expand All @@ -25,10 +25,10 @@ pub enum BindingPower {
// pub type TypeHandler<'de> = fn(&mut Parser<'de>) -> Result<(Type, usize), Error<'de>>;
// pub type LeftTypeHandler<'de> =
// fn(&'de Parser<'de>, usize, Type, &BindingPower) -> Result<(Type, usize), Error<'de>>;
pub type StatementHandler<'de> = fn(&'de mut Parser<'de>) -> Result<Statement<'de>>;
pub type ExpressionHandler<'de> = fn(&'de mut Parser<'de>) -> Result<Expression<'de>>;
pub type StatementHandler<'de> = fn(&mut Parser<'de>) -> Result<Statement<'de>>;
pub type ExpressionHandler<'de> = fn(&mut Parser<'de>) -> Result<Expression<'de>>;
pub type LeftExpressionHandler<'de> =
fn(&'de mut Parser<'de>, Expression, BindingPower) -> Result<Expression<'de>>;
fn(&mut Parser<'de>, Expression, BindingPower) -> Result<Expression<'de>>;

pub struct Lookup<'de> {
pub statement_lookup: HashMap<TokenKind, StatementHandler<'de>>,
Expand All @@ -41,41 +41,44 @@ pub struct Lookup<'de> {

impl<'de> Lookup<'de> {
pub(crate) fn add_statement_handler(
&'de mut self,
mut self,
token: TokenKind,
handler: StatementHandler<'de>,
) {
) -> Self {
if self.statement_lookup.contains_key(&token) {
panic!("Token already has a statement handler");
}

self.statement_lookup.insert(token, handler);
self
}

pub(crate) fn add_expression_handler(
&'de mut self,
mut self,
token: TokenKind,
handler: ExpressionHandler<'de>,
) {
) -> Self {
if self.expression_lookup.contains_key(&token) {
panic!("Token already has an expression handler");
}

self.expression_lookup.insert(token, handler);
self
}

pub(crate) fn add_left_expression_handler(
&'de mut self,
mut self,
token: TokenKind,
binding_power: BindingPower,
handler: LeftExpressionHandler<'de>,
) {
) -> Self {
if self.binding_power_lookup.contains_key(&token) {
panic!("Token already has a binding power");
}

self.left_expression_lookup.insert(token.clone(), handler);
self.binding_power_lookup.insert(token, binding_power);
self
}

// pub(crate) fn add_type_handler(&mut self, token: TokenType, handler: TypeHandler<'de>) {
Expand All @@ -98,17 +101,46 @@ impl<'de> Lookup<'de> {

impl<'de> Default for Lookup<'de> {
fn default() -> Self {
let mut lookup = Lookup {
Lookup {
statement_lookup: HashMap::new(),
expression_lookup: HashMap::new(),
left_expression_lookup: HashMap::new(),
binding_power_lookup: HashMap::new(),
// type_lookup: HashMap::new(),
// left_type_lookup: HashMap::new(),
};
}
.add_expression_handler(TokenKind::Integer, integer)
.add_left_expression_handler(TokenKind::Plus, BindingPower::Additive, addition)
}
}

expression::add_handlers(&mut lookup);
fn integer<'de>(parser: &mut Parser) -> Result<Expression<'de>> {
let token = parser
.lexer
.expect(TokenKind::Integer, "expected an integer")?;

lookup
}
let value = match token.value {
TokenValue::Integer(v) => v,
_ => unreachable!(),
};

Ok(Expression::Primitive(Primitive::Integer(value)))
}

fn addition<'de>(
parser: &mut Parser,
lhs: Expression,
bp: BindingPower,
) -> Result<Expression<'de>> {
let token = parser
.lexer
.expect(TokenKind::Plus, "expected a plus sign")?;

let rhs = expression::parse(parser, bp)?;

Ok(Expression::Binary {
operator: BinaryOperator::Add,
left: Box::new(lhs),
right: Box::new(rhs),
})
}

0 comments on commit 8853e48

Please sign in to comment.