[Syntax] Parse var/val binding as statemente
This commit is contained in:
parent
0630287e34
commit
18cbe2a8ab
@ -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() {
|
||||||
|
@ -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() {
|
||||||
|
@ -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>),
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
|
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::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"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -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"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error_handling::SyntaxError,
|
|
||||||
lexic::token::{Token, TokenType},
|
lexic::token::{Token, TokenType},
|
||||||
utils::Result3,
|
utils::Result3,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user