[Syntax] Parse var/val binding as statemente

master
Araozu 2023-10-05 06:51:48 -05:00
parent 0630287e34
commit 18cbe2a8ab
9 changed files with 71 additions and 50 deletions

View File

@ -1,5 +1,5 @@
use super::Transpilable; use super::Transpilable;
use crate::syntax::ast::Binding; use crate::syntax::ast::var_binding::Binding;
impl Transpilable for Binding { impl Transpilable for Binding {
/// Transpiles val and var bindings into PHP. /// Transpiles val and var bindings into PHP.
@ -22,7 +22,10 @@ impl Transpilable for Binding {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::syntax::ast::{Binding, Expression, ValBinding}; use crate::syntax::ast::{
var_binding::{Binding, ValBinding},
Expression,
};
#[test] #[test]
fn binding_should_transpile() { fn binding_should_transpile() {

View File

@ -18,7 +18,10 @@ impl Transpilable for ModuleAST {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::syntax::ast::{Binding, Expression, TopLevelDeclaration, ValBinding}; use crate::syntax::ast::{
var_binding::{Binding, ValBinding},
Expression, TopLevelDeclaration,
};
#[test] #[test]
fn module_ast_should_transpile() { fn module_ast_should_transpile() {

View File

@ -1,5 +1,6 @@
pub mod functions; pub mod functions;
pub mod statement; pub mod statement;
pub mod var_binding;
pub struct ModuleAST { pub struct ModuleAST {
pub declarations: Vec<TopLevelDeclaration>, pub declarations: Vec<TopLevelDeclaration>,
@ -7,7 +8,7 @@ pub struct ModuleAST {
#[derive(Debug)] #[derive(Debug)]
pub enum TopLevelDeclaration { pub enum TopLevelDeclaration {
Binding(Binding), Binding(var_binding::Binding),
FunctionDeclaration(FunctionDeclaration), FunctionDeclaration(FunctionDeclaration),
} }
@ -25,26 +26,6 @@ pub struct Block {
#[derive(Debug)] #[derive(Debug)]
pub struct ParamsList {} pub struct ParamsList {}
#[derive(Debug)]
pub enum Binding {
Val(ValBinding),
Var(VarBinding),
}
#[derive(Debug)]
pub struct ValBinding {
pub datatype: Option<String>,
pub identifier: Box<String>,
pub expression: Expression,
}
#[derive(Debug)]
pub struct VarBinding {
pub datatype: Option<String>,
pub identifier: Box<String>,
pub expression: Expression,
}
#[derive(Debug)] #[derive(Debug)]
pub enum Expression { pub enum Expression {
Number(Box<String>), Number(Box<String>),

View File

@ -1,6 +1,7 @@
use super::functions::FunctionCall; use super::{functions::FunctionCall, var_binding::Binding};
#[derive(Debug)] #[derive(Debug)]
pub enum Statement { pub enum Statement {
FunctionCall(FunctionCall), FunctionCall(FunctionCall),
Binding(Binding),
} }

View File

@ -0,0 +1,21 @@
use super::Expression;
#[derive(Debug)]
pub enum Binding {
Val(ValBinding),
Var(VarBinding),
}
#[derive(Debug)]
pub struct ValBinding {
pub datatype: Option<String>,
pub identifier: Box<String>,
pub expression: Expression,
}
#[derive(Debug)]
pub struct VarBinding {
pub datatype: Option<String>,
pub identifier: Box<String>,
pub expression: Expression,
}

View File

@ -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::utils::{try_operator, try_token_type};
use super::{expression, ParseResult}; use super::{expression, ParseResult};
use crate::error_handling::SyntaxError; use crate::error_handling::SyntaxError;
use crate::lexic::token::{Token, TokenType}; use crate::lexic::token::{Token, TokenType};
use crate::utils::Result3; 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<Token>, pos: usize) -> ParseResult<Binding, ()> { pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding, ()> {
let mut current_pos = pos; let mut current_pos = pos;
// Optional datatype annotation // Optional datatype annotation
@ -19,9 +15,7 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding,
Some(String::from(&t.value)) Some(String::from(&t.value))
} }
Result3::Err(_) => None, Result3::Err(_) => None,
Result3::None => panic!( Result3::None => return ParseResult::Unmatched,
"Internal compiler error: Illegal token stream at src/syntax/binding.rs#try_parse"
),
} }
}; };

View File

@ -32,7 +32,6 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block,
ParseResult::Mismatch(_) => {} ParseResult::Mismatch(_) => {}
} }
// Parse closing brace // Parse closing brace
let (_closing_brace, next_pos) = let (_closing_brace, next_pos) =
match parse_token_type(tokens, current_pos, TokenType::RightBrace) { match parse_token_type(tokens, current_pos, TokenType::RightBrace) {
@ -55,10 +54,5 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block,
}; };
current_pos = next_pos; current_pos = next_pos;
ParseResult::Ok( ParseResult::Ok(Block { statements }, current_pos)
Block {
statements,
},
current_pos,
)
} }

View File

@ -1,17 +1,24 @@
use crate::lexic::token::Token; use crate::lexic::token::Token;
use super::{ast::statement::Statement, functions::function_call, ParseResult}; use super::{ast::statement::Statement, functions::function_call, ParseResult, binding};
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Statement, ()> { pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Statement, ()> {
None.or_else(|| match function_call::try_parse(tokens, pos) { None
ParseResult::Ok(f, next) => Some(ParseResult::Ok(Statement::FunctionCall(f), next)), .or_else(
ParseResult::Err(err) => Some(ParseResult::Err(err)), || match binding::try_parse(tokens, pos) {
_ => None, ParseResult::Ok(b, next) => Some(ParseResult::Ok(Statement::Binding(b), next)),
}) ParseResult::Err(err) => Some(ParseResult::Err(err)),
.unwrap_or_else(|| ParseResult::Unmatched) _ => 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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -24,7 +31,7 @@ mod tests {
let statement = match statement { let statement = match statement {
ParseResult::Ok(s, _) => s, ParseResult::Ok(s, _) => s,
_ => panic!("Expected a function call"), _ => panic!("Expected a statement"),
}; };
match statement { match statement {
@ -32,4 +39,22 @@ mod tests {
_ => panic!("Expected a function call"), _ => 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"),
}
}
} }

View File

@ -1,5 +1,4 @@
use crate::{ use crate::{
error_handling::SyntaxError,
lexic::token::{Token, TokenType}, lexic::token::{Token, TokenType},
utils::Result3, utils::Result3,
}; };