diff --git a/src/ast_types.rs b/src/ast_types.rs index 9be6918..afdc884 100644 --- a/src/ast_types.rs +++ b/src/ast_types.rs @@ -5,6 +5,7 @@ pub struct ModuleAST<'a> { pub enum Binding<'a> { Val(ValBinding<'a>), + Var(VarBinding<'a>) } pub struct ValBinding<'a> { @@ -12,6 +13,11 @@ pub struct ValBinding<'a> { pub expression: Expression<'a>, } +pub struct VarBinding<'a> { + pub identifier: &'a String, + pub expression: Expression<'a>, +} + pub enum Expression<'a> { Number(&'a String), } diff --git a/src/codegen/binding.rs b/src/codegen/binding.rs index c5b1354..5155562 100644 --- a/src/codegen/binding.rs +++ b/src/codegen/binding.rs @@ -9,6 +9,11 @@ impl Transpilable for Binding<'_> { 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)] mod tests { use super::*; - use crate::ast_types::{Expression, ValBinding}; + use crate::ast_types::{Expression, Binding, ValBinding}; #[test] fn binding_should_transpile() { diff --git a/src/semantic/mod.rs b/src/semantic/mod.rs index 072457f..ed460f6 100644 --- a/src/semantic/mod.rs +++ b/src/semantic/mod.rs @@ -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 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); + } } } } diff --git a/src/syntax/val_binding.rs b/src/syntax/val_binding.rs index dc50712..fae7e9e 100644 --- a/src/syntax/val_binding.rs +++ b/src/syntax/val_binding.rs @@ -1,5 +1,5 @@ use crate::token::{Token, TokenType}; -use super::ast_types::{Binding, ValBinding}; +use super::ast_types::{ValBinding, VarBinding, Binding}; use super::expression; // 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 // - Error: token (var | val) was found, but then other expected tokens were not found pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> Option { - 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); if identifier.is_none() { return None } @@ -21,12 +33,18 @@ pub fn try_parse<'a>(tokens: &'a Vec, pos: usize) -> Option { if expression.is_none() { return None } let expression = expression.unwrap(); - let bind = ValBinding { - identifier: &identifier.value, - expression, - }; - - Some(Binding::Val(bind)) + if is_val { + Some(Binding::Val(ValBinding { + identifier: &identifier.value, + expression, + })) + } + else { + Some(Binding::Var(VarBinding { + identifier: &identifier.value, + expression, + })) + } } fn try_token_type(tokens: &Vec, pos: usize, token_type: TokenType) -> Option<&Token> { @@ -62,6 +80,9 @@ mod tests { Binding::Val(binding) => { assert_eq!("identifier", binding.identifier); } + Binding::Var(binding) => { + assert_eq!("identifier", binding.identifier); + } } }