Add very basic symbol table test shim
This commit is contained in:
parent
7694afc9e2
commit
98db60498a
@ -498,21 +498,13 @@ mod eval_tests {
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::tokenizing::{Token, tokenize};
|
|
||||||
use crate::parsing::ParseResult;
|
|
||||||
use crate::ast::AST;
|
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
use crate::eval::State;
|
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>> {
|
fn evaluate_all_outputs(input: &str) -> Vec<Result<String, String>> {
|
||||||
let symbol_table = Rc::new(RefCell::new(SymbolTable::new()));
|
let symbol_table = Rc::new(RefCell::new(SymbolTable::new()));
|
||||||
let mut state = State::new(symbol_table);
|
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();
|
state.symbol_table_handle.borrow_mut().add_top_level_symbols(&ast).unwrap();
|
||||||
let reduced = ast.reduce(&state.symbol_table_handle.borrow());
|
let reduced = ast.reduce(&state.symbol_table_handle.borrow());
|
||||||
let all_output = state.evaluate(reduced, true);
|
let all_output = state.evaluate(reduced, true);
|
||||||
|
@ -15,14 +15,18 @@ struct SymbolPath {
|
|||||||
|
|
||||||
//cf. p. 150 or so of Language Implementation Patterns
|
//cf. p. 150 or so of Language Implementation Patterns
|
||||||
pub struct SymbolTable {
|
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
|
//TODO add various types of lookups here, maybe multiple hash tables internally? also make values
|
||||||
//non-public
|
//non-public
|
||||||
impl SymbolTable {
|
impl SymbolTable {
|
||||||
pub fn new() -> 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) {
|
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))
|
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()) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -444,18 +444,11 @@ impl<'a> TypeContext<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod typechecking_tests {
|
mod typechecking_tests {
|
||||||
use super::*;
|
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 {
|
macro_rules! assert_type_in_fresh_context {
|
||||||
($string:expr, $type:expr) => {
|
($string:expr, $type:expr) => {
|
||||||
let mut tc = TypeContext::new();
|
let mut tc = TypeContext::new();
|
||||||
let ref ast = parse($string);
|
let ref ast = crate::util::quick_ast($string);
|
||||||
let ty = tc.typecheck(ast).unwrap();
|
let ty = tc.typecheck(ast).unwrap();
|
||||||
assert_eq!(ty, $type)
|
assert_eq!(ty, $type)
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user