From 18cbe2a8ab932e17a84ba882e0ada5d7fe87635e Mon Sep 17 00:00:00 2001 From: Araozu Date: Thu, 5 Oct 2023 06:51:48 -0500 Subject: [PATCH] [Syntax] Parse var/val binding as statemente --- src/codegen/binding.rs | 7 ++++-- src/codegen/module_ast.rs | 5 +++- src/syntax/ast/mod.rs | 23 ++----------------- src/syntax/ast/statement.rs | 3 ++- src/syntax/ast/var_binding.rs | 21 +++++++++++++++++ src/syntax/binding.rs | 10 ++------ src/syntax/block.rs | 8 +------ src/syntax/statement.rs | 43 +++++++++++++++++++++++++++-------- src/syntax/utils.rs | 1 - 9 files changed, 71 insertions(+), 50 deletions(-) create mode 100644 src/syntax/ast/var_binding.rs diff --git a/src/codegen/binding.rs b/src/codegen/binding.rs index fdb41bc..391f2e2 100644 --- a/src/codegen/binding.rs +++ b/src/codegen/binding.rs @@ -1,5 +1,5 @@ use super::Transpilable; -use crate::syntax::ast::Binding; +use crate::syntax::ast::var_binding::Binding; impl Transpilable for Binding { /// Transpiles val and var bindings into PHP. @@ -22,7 +22,10 @@ impl Transpilable for Binding { #[cfg(test)] mod tests { use super::*; - use crate::syntax::ast::{Binding, Expression, ValBinding}; + use crate::syntax::ast::{ + var_binding::{Binding, ValBinding}, + Expression, + }; #[test] fn binding_should_transpile() { diff --git a/src/codegen/module_ast.rs b/src/codegen/module_ast.rs index a01d1c1..eaf691b 100644 --- a/src/codegen/module_ast.rs +++ b/src/codegen/module_ast.rs @@ -18,7 +18,10 @@ impl Transpilable for ModuleAST { #[cfg(test)] mod tests { use super::*; - use crate::syntax::ast::{Binding, Expression, TopLevelDeclaration, ValBinding}; + use crate::syntax::ast::{ + var_binding::{Binding, ValBinding}, + Expression, TopLevelDeclaration, + }; #[test] fn module_ast_should_transpile() { diff --git a/src/syntax/ast/mod.rs b/src/syntax/ast/mod.rs index 9b18d6f..15f362a 100644 --- a/src/syntax/ast/mod.rs +++ b/src/syntax/ast/mod.rs @@ -1,5 +1,6 @@ pub mod functions; pub mod statement; +pub mod var_binding; pub struct ModuleAST { pub declarations: Vec, @@ -7,7 +8,7 @@ pub struct ModuleAST { #[derive(Debug)] pub enum TopLevelDeclaration { - Binding(Binding), + Binding(var_binding::Binding), FunctionDeclaration(FunctionDeclaration), } @@ -25,26 +26,6 @@ pub struct Block { #[derive(Debug)] pub struct ParamsList {} -#[derive(Debug)] -pub enum Binding { - Val(ValBinding), - Var(VarBinding), -} - -#[derive(Debug)] -pub struct ValBinding { - pub datatype: Option, - pub identifier: Box, - pub expression: Expression, -} - -#[derive(Debug)] -pub struct VarBinding { - pub datatype: Option, - pub identifier: Box, - pub expression: Expression, -} - #[derive(Debug)] pub enum Expression { Number(Box), diff --git a/src/syntax/ast/statement.rs b/src/syntax/ast/statement.rs index 054a1bb..7e0bc69 100644 --- a/src/syntax/ast/statement.rs +++ b/src/syntax/ast/statement.rs @@ -1,6 +1,7 @@ -use super::functions::FunctionCall; +use super::{functions::FunctionCall, var_binding::Binding}; #[derive(Debug)] pub enum Statement { FunctionCall(FunctionCall), + Binding(Binding), } diff --git a/src/syntax/ast/var_binding.rs b/src/syntax/ast/var_binding.rs new file mode 100644 index 0000000..939eb01 --- /dev/null +++ b/src/syntax/ast/var_binding.rs @@ -0,0 +1,21 @@ +use super::Expression; + +#[derive(Debug)] +pub enum Binding { + Val(ValBinding), + Var(VarBinding), +} + +#[derive(Debug)] +pub struct ValBinding { + pub datatype: Option, + pub identifier: Box, + pub expression: Expression, +} + +#[derive(Debug)] +pub struct VarBinding { + pub datatype: Option, + pub identifier: Box, + pub expression: Expression, +} diff --git a/src/syntax/binding.rs b/src/syntax/binding.rs index ad7bd5c..1a41ea1 100644 --- a/src/syntax/binding.rs +++ b/src/syntax/binding.rs @@ -1,14 +1,10 @@ -use super::ast::{Binding, ValBinding, VarBinding}; +use super::ast::var_binding::{Binding, ValBinding, VarBinding}; use super::utils::{try_operator, try_token_type}; use super::{expression, ParseResult}; use crate::error_handling::SyntaxError; use crate::lexic::token::{Token, TokenType}; use crate::utils::Result3; -// TODO: Should return a 3 state value: -// - Success: binding parsed successfully -// - NotFound: the first token (var | val) was not found, so the parser should try other options -// - Error: token (var | val) was found, but then other expected tokens were not found pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult { let mut current_pos = pos; // Optional datatype annotation @@ -19,9 +15,7 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> ParseResult None, - Result3::None => panic!( - "Internal compiler error: Illegal token stream at src/syntax/binding.rs#try_parse" - ), + Result3::None => return ParseResult::Unmatched, } }; diff --git a/src/syntax/block.rs b/src/syntax/block.rs index 3f0201c..2dc6455 100644 --- a/src/syntax/block.rs +++ b/src/syntax/block.rs @@ -32,7 +32,6 @@ pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult {} } - // Parse closing brace let (_closing_brace, next_pos) = match parse_token_type(tokens, current_pos, TokenType::RightBrace) { @@ -55,10 +54,5 @@ pub fn parse_block<'a>(tokens: &'a Vec, pos: usize) -> ParseResult(tokens: &'a Vec, pos: usize) -> ParseResult { - None.or_else(|| match function_call::try_parse(tokens, pos) { - ParseResult::Ok(f, next) => Some(ParseResult::Ok(Statement::FunctionCall(f), next)), - ParseResult::Err(err) => Some(ParseResult::Err(err)), - _ => None, - }) - .unwrap_or_else(|| ParseResult::Unmatched) + None + .or_else( + || match binding::try_parse(tokens, pos) { + ParseResult::Ok(b, next) => Some(ParseResult::Ok(Statement::Binding(b), next)), + ParseResult::Err(err) => Some(ParseResult::Err(err)), + _ => None, + } + ) + .or_else(|| match function_call::try_parse(tokens, pos) { + ParseResult::Ok(f, next) => Some(ParseResult::Ok(Statement::FunctionCall(f), next)), + ParseResult::Err(err) => Some(ParseResult::Err(err)), + _ => None, + }) + .unwrap_or_else(|| ParseResult::Unmatched) } - #[cfg(test)] mod tests { use super::*; @@ -24,7 +31,7 @@ mod tests { let statement = match statement { ParseResult::Ok(s, _) => s, - _ => panic!("Expected a function call"), + _ => panic!("Expected a statement"), }; match statement { @@ -32,4 +39,22 @@ mod tests { _ => panic!("Expected a function call"), } } + + + #[test] + fn should_parse_binding() { + let input = String::from("val identifier = 20"); + let tokens = crate::lexic::get_tokens(&input).unwrap(); + let statement = try_parse(&tokens, 0); + + let statement = match statement { + ParseResult::Ok(s, _) => s, + _ => panic!("Expected a statement"), + }; + + match statement { + Statement::Binding(_) => assert!(true), + _ => panic!("Expected a binding"), + } + } } diff --git a/src/syntax/utils.rs b/src/syntax/utils.rs index 1f5ed7a..ac6f472 100644 --- a/src/syntax/utils.rs +++ b/src/syntax/utils.rs @@ -1,5 +1,4 @@ use crate::{ - error_handling::SyntaxError, lexic::token::{Token, TokenType}, utils::Result3, };