Structure for parsing operators. Parse unary operator
This commit is contained in:
parent
c045721f46
commit
a54abcc394
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
- Parse block of code
|
- Parse block of code
|
||||||
- Parse multiple statements inside a block
|
- Parse multiple statements inside a block
|
||||||
|
- Parse unary operator (`!` & `-`)
|
||||||
|
|
||||||
|
|
||||||
## v0.0.7
|
## v0.0.7
|
||||||
|
@ -21,6 +21,9 @@ impl Transpilable for Expression {
|
|||||||
Expression::BinaryOperator(_, _, _) => {
|
Expression::BinaryOperator(_, _, _) => {
|
||||||
todo!("BinaryOperator codegen is not implemented yet")
|
todo!("BinaryOperator codegen is not implemented yet")
|
||||||
}
|
}
|
||||||
|
Expression::UnaryOperator(_, _) => {
|
||||||
|
todo!("UnaryOperator codegen is not implemented yet")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,6 @@ pub enum Expression {
|
|||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Identifier(Box<String>),
|
Identifier(Box<String>),
|
||||||
FunctionCall(FunctionCall),
|
FunctionCall(FunctionCall),
|
||||||
|
UnaryOperator(Box<String>, Box<Expression>),
|
||||||
BinaryOperator(Box<Expression>, Box<Expression>, Box<String>),
|
BinaryOperator(Box<Expression>, Box<Expression>, Box<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
src/syntax/expression/comparison.rs
Normal file
8
src/syntax/expression/comparison.rs
Normal 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);
|
||||||
|
}
|
@ -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, ()> {
|
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
|
||||||
//
|
return super::comparison::try_parse(tokens, pos);
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
8
src/syntax/expression/factor.rs
Normal file
8
src/syntax/expression/factor.rs
Normal 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);
|
||||||
|
}
|
@ -1,36 +1,14 @@
|
|||||||
use super::{ast::Expression, functions::function_call, ParseResult};
|
use super::{ast::Expression, ParseResult};
|
||||||
use crate::lexic::token::{Token, TokenType};
|
use crate::lexic::token::Token;
|
||||||
|
|
||||||
|
mod comparison;
|
||||||
mod equality;
|
mod equality;
|
||||||
|
mod factor;
|
||||||
mod primary;
|
mod primary;
|
||||||
|
mod term;
|
||||||
|
mod unary;
|
||||||
|
|
||||||
/// Expression is defined in the grammar.
|
/// Expression is defined in the grammar.
|
||||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
|
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()> {
|
||||||
match function_call::try_parse(tokens, pos) {
|
return equality::try_parse(tokens, pos);
|
||||||
super::ParseResult::Ok(function_call, next_pos) => {
|
|
||||||
return ParseResult::Ok::<_, ()>(Expression::FunctionCall(function_call), next_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,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// This grammar may not be up to date. Refer to the spec for the latest grammar.
|
/// This grammar may not be up to date. Refer to the spec for the latest grammar.
|
||||||
///
|
///
|
||||||
/// ```ebnf
|
/// ```ebnf
|
||||||
/// primary = number | string | boolean | identifier | ("(", expression, ")");
|
/// primary = number | string | boolean | identifier | ("(", expression, ")");
|
||||||
/// ```
|
/// ```
|
||||||
@ -34,13 +34,27 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression, ()>
|
|||||||
Expression::Identifier(Box::new(token.value.clone())),
|
Expression::Identifier(Box::new(token.value.clone())),
|
||||||
pos + 1,
|
pos + 1,
|
||||||
),
|
),
|
||||||
// TODO: Parse parenthesized expressions.
|
TokenType::LeftParen => parse_parenthesized_expression(tokens, pos),
|
||||||
_ => ParseResult::Unmatched,
|
_ => ParseResult::Unmatched,
|
||||||
},
|
},
|
||||||
None => 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
8
src/syntax/expression/term.rs
Normal file
8
src/syntax/expression/term.rs
Normal 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);
|
||||||
|
}
|
25
src/syntax/expression/unary.rs
Normal file
25
src/syntax/expression/unary.rs
Normal 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),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user