Add very basic symbol table test shim

This commit is contained in:
greg 2019-03-07 23:51:31 -08:00
parent 7694afc9e2
commit 98db60498a
4 changed files with 42 additions and 19 deletions

View File

@ -498,21 +498,13 @@ mod eval_tests {
use std::cell::RefCell;
use std::rc::Rc;
use crate::tokenizing::{Token, tokenize};
use crate::parsing::ParseResult;
use crate::ast::AST;
use crate::symbol_table::SymbolTable;
use crate::eval::State;
fn parse(tokens: Vec<Token>) -> ParseResult<AST> {
let mut parser = crate::parsing::Parser::new(tokens);
parser.parse()
}
fn evaluate_all_outputs(input: &str) -> Vec<Result<String, String>> {
let symbol_table = Rc::new(RefCell::new(SymbolTable::new()));
let mut state = State::new(symbol_table);
let ast = parse(tokenize(input)).unwrap();
let ast = crate::util::quick_ast(input);
state.symbol_table_handle.borrow_mut().add_top_level_symbols(&ast).unwrap();
let reduced = ast.reduce(&state.symbol_table_handle.borrow());
let all_output = state.evaluate(reduced, true);

View File

@ -15,14 +15,18 @@ struct SymbolPath {
//cf. p. 150 or so of Language Implementation Patterns
pub struct SymbolTable {
values: HashMap<SymbolPath, Symbol> //TODO this will eventually have real type information
values: HashMap<SymbolPath, Symbol>,
scope_name_stack: Vec<String>,
}
//TODO add various types of lookups here, maybe multiple hash tables internally? also make values
//non-public
impl SymbolTable {
pub fn new() -> SymbolTable {
SymbolTable { values: HashMap::new() }
SymbolTable {
values: HashMap::new(),
scope_name_stack: vec![],
}
}
pub fn add_new_symbol(&mut self, path: &Rc<String>, symbol: Symbol) {
@ -174,3 +178,31 @@ impl LocalTypeContext {
Rc::new(format!("{}", (('a' as u8) + n) as char))
}
}
#[cfg(test)]
mod symbol_table_tests {
use super::*;
macro_rules! values_in_table {
//TODO multiple values
($source:expr, $single_value:expr) => {
{
let mut symbol_table = SymbolTable::new();
let ast = crate::util::quick_ast($source);
symbol_table.add_top_level_symbols(&ast).unwrap();
println!("TAAABL: {}", symbol_table.debug_symbol_table());
match symbol_table.lookup_by_name($single_value) {
Some(_spec) => (),
None => panic!(),
};
}
}
}
#[test]
fn basic_symbol_table() {
values_in_table! { "let a = 10; fn b() { 20 }", &Rc::new("b".to_string()) };
}
}

View File

@ -444,18 +444,11 @@ impl<'a> TypeContext<'a> {
#[cfg(test)]
mod typechecking_tests {
use super::*;
use crate::ast::AST;
fn parse(input: &str) -> AST {
let tokens = crate::tokenizing::tokenize(input);
let mut parser = crate::parsing::Parser::new(tokens);
parser.parse().unwrap()
}
macro_rules! assert_type_in_fresh_context {
($string:expr, $type:expr) => {
let mut tc = TypeContext::new();
let ref ast = parse($string);
let ref ast = crate::util::quick_ast($string);
let ty = tc.typecheck(ast).unwrap();
assert_eq!(ty, $type)
}

View File

@ -41,3 +41,9 @@ impl<'a, T, V> ScopeStack<'a, T, V> where T: Hash + Eq {
}
}
/// this is intended for use in tests, and does no error-handling whatsoever
pub fn quick_ast(input: &str) -> crate::ast::AST {
let tokens = crate::tokenizing::tokenize(input);
let mut parser = crate::parsing::Parser::new(tokens);
parser.parse().unwrap()
}