Simple type checking in the symbol table
This commit is contained in:
parent
1c90ee293b
commit
418be5dc17
@ -13,7 +13,7 @@ fn compile(input: &String) {
|
|||||||
Ok(tokens) => {
|
Ok(tokens) => {
|
||||||
let mut ast = syntax::construct_ast(&tokens).unwrap();
|
let mut ast = syntax::construct_ast(&tokens).unwrap();
|
||||||
let mut table = SymbolTable::new();
|
let mut table = SymbolTable::new();
|
||||||
let new_ast = semantic::check_ast(&mut ast, &mut table);
|
semantic::check_ast(&mut ast, &mut table);
|
||||||
},
|
},
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
eprintln!("Error scanning.\n{} at pos {}", error.reason, error.position)
|
eprintln!("Error scanning.\n{} at pos {}", error.reason, error.position)
|
||||||
|
@ -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;
|
/// Checks the ast. In the future should return a list of errors.
|
||||||
use super::ast_types::ModuleAST;
|
pub fn check_ast<'a>(ast: &'a mut ModuleAST, symbol_table: &'a mut SymbolTable) {
|
||||||
|
for binding in &ast.bindings {
|
||||||
pub fn check_ast<'a>(ast: &'a mut ModuleAST, symbol_table: &'a mut SymbolTable) -> Option<ModuleAST<'a>> {
|
match binding {
|
||||||
None
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::syntax;
|
||||||
|
use crate::lexic;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -31,4 +40,16 @@ mod tests {
|
|||||||
identifier: Num
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ pub struct SymbolTable {
|
|||||||
|
|
||||||
impl SymbolTable {
|
impl SymbolTable {
|
||||||
pub fn new() -> SymbolTable {
|
pub fn new() -> SymbolTable {
|
||||||
let mut symbol_table = HashMap::<String, String>::new();
|
let symbol_table = HashMap::<String, String>::new();
|
||||||
|
|
||||||
SymbolTable {
|
SymbolTable {
|
||||||
table: symbol_table,
|
table: symbol_table,
|
||||||
@ -25,6 +25,20 @@ impl SymbolTable {
|
|||||||
pub fn test(&self, identifier: &str) -> bool {
|
pub fn test(&self, identifier: &str) -> bool {
|
||||||
return self.table.contains_key::<String>(&String::from(identifier));
|
return self.table.contains_key::<String>(&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);
|
table.add("identifier", _NUMBER);
|
||||||
assert_eq!(true, table.test("identifier"))
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user