Parse simple var binding
This commit is contained in:
parent
df772ec737
commit
850ed4cdaf
@ -5,6 +5,7 @@ pub struct ModuleAST<'a> {
|
|||||||
|
|
||||||
pub enum Binding<'a> {
|
pub enum Binding<'a> {
|
||||||
Val(ValBinding<'a>),
|
Val(ValBinding<'a>),
|
||||||
|
Var(VarBinding<'a>)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ValBinding<'a> {
|
pub struct ValBinding<'a> {
|
||||||
@ -12,6 +13,11 @@ pub struct ValBinding<'a> {
|
|||||||
pub expression: Expression<'a>,
|
pub expression: Expression<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct VarBinding<'a> {
|
||||||
|
pub identifier: &'a String,
|
||||||
|
pub expression: Expression<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
pub enum Expression<'a> {
|
pub enum Expression<'a> {
|
||||||
Number(&'a String),
|
Number(&'a String),
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,11 @@ impl Transpilable for Binding<'_> {
|
|||||||
|
|
||||||
format!("const {} = {};", val_binding.identifier, expression_str)
|
format!("const {} = {};", val_binding.identifier, expression_str)
|
||||||
}
|
}
|
||||||
|
Binding::Var(var_binding) => {
|
||||||
|
let expression_str = var_binding.expression.transpile();
|
||||||
|
|
||||||
|
format!("let {} = {};", var_binding.identifier, expression_str)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +23,7 @@ impl Transpilable for Binding<'_> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::ast_types::{Expression, ValBinding};
|
use crate::ast_types::{Expression, Binding, ValBinding};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn binding_should_transpile() {
|
fn binding_should_transpile() {
|
||||||
|
@ -9,6 +9,10 @@ pub fn check_ast<'a>(ast: &'a mut ModuleAST, symbol_table: &'a mut SymbolTable)
|
|||||||
// TODO: create a function to get the datatype, instead of a hardcoded value
|
// TODO: create a function to get the datatype, instead of a hardcoded value
|
||||||
symbol_table.add(val_binding.identifier, _NUMBER);
|
symbol_table.add(val_binding.identifier, _NUMBER);
|
||||||
}
|
}
|
||||||
|
Binding::Var(var_binding) => {
|
||||||
|
// TODO: create a function to get the datatype, instead of a hardcoded value
|
||||||
|
symbol_table.add(var_binding.identifier, _NUMBER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::token::{Token, TokenType};
|
use crate::token::{Token, TokenType};
|
||||||
use super::ast_types::{Binding, ValBinding};
|
use super::ast_types::{ValBinding, VarBinding, Binding};
|
||||||
use super::expression;
|
use super::expression;
|
||||||
|
|
||||||
// Should return a 3 state value:
|
// Should return a 3 state value:
|
||||||
@ -7,7 +7,19 @@ use super::expression;
|
|||||||
// - NotFound: the first token (var | val) was not found, so the parser should try other options
|
// - 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
|
// - 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) -> Option<Binding> {
|
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<Binding> {
|
||||||
let _ = try_token_type(tokens, pos, TokenType::VAL)?;
|
let is_val = {
|
||||||
|
let res1 = try_token_type(tokens, pos, TokenType::VAL);
|
||||||
|
match res1 {
|
||||||
|
Some(_) => true,
|
||||||
|
None => {
|
||||||
|
let res2 = try_token_type(tokens, pos, TokenType::VAR);
|
||||||
|
match res2 {
|
||||||
|
Some(_) => false,
|
||||||
|
None => return None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let identifier = try_token_type(tokens, pos + 1, TokenType::Identifier);
|
let identifier = try_token_type(tokens, pos + 1, TokenType::Identifier);
|
||||||
if identifier.is_none() { return None }
|
if identifier.is_none() { return None }
|
||||||
@ -21,12 +33,18 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> Option<Binding> {
|
|||||||
if expression.is_none() { return None }
|
if expression.is_none() { return None }
|
||||||
let expression = expression.unwrap();
|
let expression = expression.unwrap();
|
||||||
|
|
||||||
let bind = ValBinding {
|
if is_val {
|
||||||
identifier: &identifier.value,
|
Some(Binding::Val(ValBinding {
|
||||||
expression,
|
identifier: &identifier.value,
|
||||||
};
|
expression,
|
||||||
|
}))
|
||||||
Some(Binding::Val(bind))
|
}
|
||||||
|
else {
|
||||||
|
Some(Binding::Var(VarBinding {
|
||||||
|
identifier: &identifier.value,
|
||||||
|
expression,
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_token_type(tokens: &Vec<Token>, pos: usize, token_type: TokenType) -> Option<&Token> {
|
fn try_token_type(tokens: &Vec<Token>, pos: usize, token_type: TokenType) -> Option<&Token> {
|
||||||
@ -62,6 +80,9 @@ mod tests {
|
|||||||
Binding::Val(binding) => {
|
Binding::Val(binding) => {
|
||||||
assert_eq!("identifier", binding.identifier);
|
assert_eq!("identifier", binding.identifier);
|
||||||
}
|
}
|
||||||
|
Binding::Var(binding) => {
|
||||||
|
assert_eq!("identifier", binding.identifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user