[Syntax] Parse var/val binding as statemente
This commit is contained in:
parent
0630287e34
commit
18cbe2a8ab
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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>),
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::functions::FunctionCall;
|
||||
use super::{functions::FunctionCall, var_binding::Binding};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Statement {
|
||||
FunctionCall(FunctionCall),
|
||||
Binding(Binding),
|
||||
}
|
||||
|
21
src/syntax/ast/var_binding.rs
Normal file
21
src/syntax/ast/var_binding.rs
Normal 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,
|
||||
}
|
@ -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,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -1,17 +1,24 @@
|
||||
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) {
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::{
|
||||
error_handling::SyntaxError,
|
||||
lexic::token::{Token, TokenType},
|
||||
utils::Result3,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user