diff --git a/src/repl/mod.rs b/src/repl/mod.rs index 9d8bb74..a943d96 100755 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -13,7 +13,7 @@ fn compile(input: &String) { Ok(tokens) => { let mut ast = syntax::construct_ast(&tokens).unwrap(); let mut table = SymbolTable::new(); - let new_ast = semantic::check_ast(&mut ast, &mut table); + semantic::check_ast(&mut ast, &mut table); }, Err(error) => { eprintln!("Error scanning.\n{} at pos {}", error.reason, error.position) diff --git a/src/semantic/mod.rs b/src/semantic/mod.rs index f240336..2437f0f 100644 --- a/src/semantic/mod.rs +++ b/src/semantic/mod.rs @@ -1,14 +1,23 @@ -use crate::symbol_table; +use super::symbol_table::{SymbolTable, _NUMBER}; +use super::ast_types::{ModuleAST, Binding}; -use super::symbol_table::SymbolTable; -use super::ast_types::ModuleAST; - -pub fn check_ast<'a>(ast: &'a mut ModuleAST, symbol_table: &'a mut SymbolTable) -> Option> { - None +/// Checks the ast. In the future should return a list of errors. +pub fn check_ast<'a>(ast: &'a mut ModuleAST, symbol_table: &'a mut SymbolTable) { + for binding in &ast.bindings { + match binding { + Binding::Val(val_binding) => { + // TODO: create a function to get the datatype, instead of a hardcoded value + symbol_table.add(val_binding.identifier, _NUMBER); + } + } + } } #[cfg(test)] mod tests { + use crate::syntax; + use crate::lexic; + use super::*; /* @@ -31,4 +40,16 @@ mod tests { identifier: Num } */ + + #[test] + fn should_update_symbol_table() { + let tokens = lexic::get_tokens(&String::from("val identifier = 20")).unwrap(); + let mut table = SymbolTable::new(); + let mut ast = syntax::construct_ast(&tokens).unwrap(); + + check_ast(&mut ast, &mut table); + + let result = table.test("identifier"); + assert_eq!(true, result); + } } diff --git a/src/symbol_table.rs b/src/symbol_table.rs index 2e53bd3..3b7e716 100644 --- a/src/symbol_table.rs +++ b/src/symbol_table.rs @@ -11,7 +11,7 @@ pub struct SymbolTable { impl SymbolTable { pub fn new() -> SymbolTable { - let mut symbol_table = HashMap::::new(); + let symbol_table = HashMap::::new(); SymbolTable { table: symbol_table, @@ -25,6 +25,20 @@ impl SymbolTable { pub fn test(&self, identifier: &str) -> bool { return self.table.contains_key::(&String::from(identifier)); } + + pub fn check_type(&self, identifier: &str, datatype: &str) -> bool { + self.table + .get_key_value(&String::from(identifier)) + .and_then(|(_, value)| { + if value == &String::from(datatype) { + Some(true) + } + else { + Some(false) + } + }) + .unwrap_or(false) + } } @@ -43,4 +57,12 @@ mod tests { table.add("identifier", _NUMBER); assert_eq!(true, table.test("identifier")) } + + #[test] + fn should_check_type() { + let mut table = SymbolTable::new(); + table.add("firstNumber", _NUMBER); + + assert!(table.check_type("firstNumber", _NUMBER)); + } }