Structure for parsing operators. Parse unary operator

This commit is contained in:
Araozu 2023-11-21 21:00:58 -05:00
parent c045721f46
commit a54abcc394
10 changed files with 82 additions and 37 deletions

View File

@ -18,6 +18,7 @@
- Parse block of code
- Parse multiple statements inside a block
- Parse unary operator (`!` & `-`)
## v0.0.7

View File

@ -21,6 +21,9 @@ impl Transpilable for Expression {
Expression::BinaryOperator(_, _, _) => {
todo!("BinaryOperator codegen is not implemented yet")
}
Expression::UnaryOperator(_, _) => {
todo!("UnaryOperator codegen is not implemented yet")
}
}
}
}

View File

@ -35,6 +35,6 @@ pub enum Expression {
Boolean(bool),
Identifier(Box<String>),
FunctionCall(FunctionCall),
UnaryOperator(Box<String>, Box<Expression>),
BinaryOperator(Box<Expression>, Box<Expression>, Box<String>),
}

View File

@ -0,0 +1,8 @@
use crate::{
lexic::token::Token,
syntax::{ast::Expression, ParseResult},
};
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
return super::term::try_parse(tokens, pos);
}

View File

@ -1,8 +1,8 @@
use crate::{syntax::{ParseResult, ast::Expression}, lexic::token::Token};
use crate::{
lexic::token::Token,
syntax::{ast::Expression, ParseResult},
};
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
//
todo!()
return super::comparison::try_parse(tokens, pos);
}

View File

@ -0,0 +1,8 @@
use crate::{
lexic::token::Token,
syntax::{ast::Expression, ParseResult},
};
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
return super::unary::try_parse(tokens, pos);
}

View File

@ -1,36 +1,14 @@
use super::{ast::Expression, functions::function_call, ParseResult};
use crate::lexic::token::{Token, TokenType};
use super::{ast::Expression, ParseResult};
use crate::lexic::token::Token;
mod comparison;
mod equality;
mod factor;
mod primary;
mod term;
mod unary;
/// Expression is defined in the grammar.
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
match function_call::try_parse(tokens, pos) {
super::ParseResult::Ok(function_call, next_pos) => {
return ParseResult::Ok::<_, ()>(Expression::FunctionCall(function_call), next_pos)
return equality::try_parse(tokens, pos);
}
_ => {}
};
match tokens.get(pos) {
Some(token) => match token.token_type {
TokenType::Number => {
ParseResult::Ok(Expression::Number(Box::new(token.value.clone())), pos + 1)
}
TokenType::String => {
ParseResult::Ok(Expression::String(Box::new(token.value.clone())), pos + 1)
}
TokenType::Identifier if token.value == "true" || token.value == "false" => {
ParseResult::Ok(Expression::Boolean(token.value == "true"), pos + 1)
}
TokenType::Identifier => ParseResult::Ok(
Expression::Identifier(Box::new(token.value.clone())),
pos + 1,
),
_ => ParseResult::Unmatched,
},
None => ParseResult::Unmatched,
}
}

View File

@ -34,13 +34,27 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
Expression::Identifier(Box::new(token.value.clone())),
pos + 1,
),
// TODO: Parse parenthesized expressions.
TokenType::LeftParen => parse_parenthesized_expression(tokens, pos),
_ => ParseResult::Unmatched,
},
None => ParseResult::Unmatched,
}
}
fn parse_parenthesized_expression(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
let expression = super::try_parse(tokens, pos + 1);
match expression {
ParseResult::Ok(expression, next_pos) => match tokens.get(next_pos) {
Some(token) => match token.token_type {
TokenType::RightParen => ParseResult::Ok(expression, next_pos + 1),
_ => ParseResult::Unmatched,
},
None => ParseResult::Unmatched,
},
_ => ParseResult::Unmatched,
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -0,0 +1,8 @@
use crate::{
lexic::token::Token,
syntax::{ast::Expression, ParseResult},
};
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
return super::factor::try_parse(tokens, pos);
}

View File

@ -0,0 +1,25 @@
use crate::{
lexic::token::Token,
syntax::{ast::Expression, expression::primary, ParseResult},
};
/// Parses an unary expression.
///
/// ```ebnf
/// unary = ("!" | "-"), expression
/// | primary;
/// ```
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
match tokens.get(pos) {
Some(token) if token.value == "!" || token.value == "-" => {
match super::try_parse(tokens, pos + 1) {
ParseResult::Ok(expression, next_pos) => ParseResult::Ok(
Expression::UnaryOperator(Box::new(token.value.clone()), Box::new(expression)),
next_pos,
),
_ => ParseResult::Unmatched,
}
}
_ => return primary::try_parse(tokens, pos),
}
}