[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 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() {

View File

@ -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() {

View File

@ -1,5 +1,6 @@
pub mod functions;
pub mod statement;
pub mod var_binding;
pub struct ModuleAST {
pub declarations: Vec<TopLevelDeclaration>,
@ -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<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)]
pub enum Expression {
Number(Box<String>),

View File

@ -1,6 +1,7 @@
use super::functions::FunctionCall;
use super::{functions::FunctionCall, var_binding::Binding};
#[derive(Debug)]
pub enum Statement {
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::{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<Token>, pos: usize) -> ParseResult<Binding, ()> {
let mut current_pos = pos;
// 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))
}
Result3::Err(_) => None,
Result3::None => panic!(
"Internal compiler error: Illegal token stream at src/syntax/binding.rs#try_parse"
),
Result3::None => return ParseResult::Unmatched,
}
};

View File

@ -32,7 +32,6 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block,
ParseResult::Mismatch(_) => {}
}
// 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<Token>, pos: usize) -> ParseResult<Block,
};
current_pos = next_pos;
ParseResult::Ok(
Block {
statements,
},
current_pos,
)
ParseResult::Ok(Block { statements }, current_pos)
}

View File

@ -1,9 +1,17 @@
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, ()> {
None.or_else(|| match function_call::try_parse(tokens, pos) {
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,
@ -11,7 +19,6 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Statemen
.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"),
}
}
}

View File

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