Parse simple var binding

This commit is contained in:
Araozu 2023-02-09 18:44:31 -05:00
parent df772ec737
commit 850ed4cdaf
4 changed files with 45 additions and 9 deletions

View File

@ -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),
} }

View File

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

View File

@ -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);
}
} }
} }
} }

View File

@ -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);
}
} }
} }