Pass around reference to type context in evaluator
This commit is contained in:
parent
160ce95e5f
commit
3ac50f974d
@ -1,3 +1,4 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -6,9 +7,11 @@ use itertools::Itertools;
|
|||||||
|
|
||||||
use util::StateStack;
|
use util::StateStack;
|
||||||
use ast_reducing::{ReducedAST, Stmt, Expr, Lit, Func};
|
use ast_reducing::{ReducedAST, Stmt, Expr, Lit, Func};
|
||||||
|
use typechecking::TypeContext;
|
||||||
|
|
||||||
pub struct State<'a> {
|
pub struct State<'a> {
|
||||||
values: StateStack<'a, Rc<String>, ValueEntry>
|
values: StateStack<'a, Rc<String>, ValueEntry>,
|
||||||
|
type_context_handle: Option<Rc<RefCell<TypeContext>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! builtin_binding {
|
macro_rules! builtin_binding {
|
||||||
@ -18,12 +21,12 @@ macro_rules! builtin_binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> State<'a> {
|
impl<'a> State<'a> {
|
||||||
pub fn new() -> State<'a> {
|
pub fn new(type_context_handle: Option<Rc<RefCell<TypeContext>>>) -> State<'a> {
|
||||||
let mut values = StateStack::new(Some(format!("global")));
|
let mut values = StateStack::new(Some(format!("global")));
|
||||||
builtin_binding!("print", values);
|
builtin_binding!("print", values);
|
||||||
builtin_binding!("println", values);
|
builtin_binding!("println", values);
|
||||||
builtin_binding!("getline", values);
|
builtin_binding!("getline", values);
|
||||||
State { values }
|
State { values, type_context_handle }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_print(&self) -> String {
|
pub fn debug_print(&self) -> String {
|
||||||
@ -415,7 +418,10 @@ impl<'a> State<'a> {
|
|||||||
if params.len() != args.len() {
|
if params.len() != args.len() {
|
||||||
return Err(format!("calling a {}-argument function with {} args", params.len(), args.len()))
|
return Err(format!("calling a {}-argument function with {} args", params.len(), args.len()))
|
||||||
}
|
}
|
||||||
let mut func_state = State { values: self.values.new_frame(name.map(|n| format!("{}", n))) };
|
let mut func_state = State {
|
||||||
|
values: self.values.new_frame(name.map(|n| format!("{}", n))),
|
||||||
|
type_context_handle: self.type_context_handle.clone(),
|
||||||
|
};
|
||||||
for (param, val) in params.into_iter().zip(args.into_iter()) {
|
for (param, val) in params.into_iter().zip(args.into_iter()) {
|
||||||
let val = func_state.expression(val)?;
|
let val = func_state.expression(val)?;
|
||||||
func_state.values.insert(param, ValueEntry::Binding { constant: true, val });
|
func_state.values.insert(param, ValueEntry::Binding { constant: true, val });
|
||||||
@ -518,7 +524,7 @@ mod eval_tests {
|
|||||||
|
|
||||||
macro_rules! fresh_env {
|
macro_rules! fresh_env {
|
||||||
($string:expr, $correct:expr) => {
|
($string:expr, $correct:expr) => {
|
||||||
let mut state = State::new();
|
let mut state = State::new(None);
|
||||||
let all_output = state.evaluate(parse(tokenize($string)).0.unwrap().reduce(), true);
|
let all_output = state.evaluate(parse(tokenize($string)).0.unwrap().reduce(), true);
|
||||||
let ref output = all_output.last().unwrap();
|
let ref output = all_output.last().unwrap();
|
||||||
assert_eq!(**output, Ok($correct.to_string()));
|
assert_eq!(**output, Ok($correct.to_string()));
|
||||||
|
@ -10,6 +10,9 @@ extern crate schala_repl;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate schala_codegen;
|
extern crate schala_codegen;
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use schala_repl::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, UnfinishedComputation, FinishedComputation};
|
use schala_repl::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, UnfinishedComputation, FinishedComputation};
|
||||||
|
|
||||||
@ -31,14 +34,15 @@ mod eval;
|
|||||||
#[PipelineSteps(tokenizing, parsing, symbol_table, typechecking, ast_reducing, eval)]
|
#[PipelineSteps(tokenizing, parsing, symbol_table, typechecking, ast_reducing, eval)]
|
||||||
pub struct Schala {
|
pub struct Schala {
|
||||||
state: eval::State<'static>,
|
state: eval::State<'static>,
|
||||||
type_context: typechecking::TypeContext
|
type_context: Rc<RefCell<typechecking::TypeContext>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Schala {
|
impl Schala {
|
||||||
pub fn new() -> Schala {
|
pub fn new() -> Schala {
|
||||||
|
let type_context = Rc::new(RefCell::new(typechecking::TypeContext::new()));
|
||||||
Schala {
|
Schala {
|
||||||
state: eval::State::new(),
|
type_context: type_context.clone(),
|
||||||
type_context: typechecking::TypeContext::new(),
|
state: eval::State::new(Some(type_context)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,9 +74,10 @@ fn parsing(_handle: &mut Schala, input: Vec<tokenizing::Token>, comp: Option<&mu
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_table(handle: &mut Schala, input: parsing::AST, comp: Option<&mut UnfinishedComputation>) -> Result<parsing::AST, String> {
|
fn symbol_table(handle: &mut Schala, input: parsing::AST, comp: Option<&mut UnfinishedComputation>) -> Result<parsing::AST, String> {
|
||||||
match handle.type_context.add_top_level_types(&input) {
|
let add = handle.type_context.borrow_mut().add_top_level_types(&input);
|
||||||
|
match add {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let artifact = TraceArtifact::new("symbol_table", handle.type_context.debug_symbol_table());
|
let artifact = TraceArtifact::new("symbol_table", handle.type_context.borrow().debug_symbol_table());
|
||||||
comp.map(|comp| comp.add_artifact(artifact));
|
comp.map(|comp| comp.add_artifact(artifact));
|
||||||
Ok(input)
|
Ok(input)
|
||||||
},
|
},
|
||||||
@ -81,7 +86,7 @@ fn symbol_table(handle: &mut Schala, input: parsing::AST, comp: Option<&mut Unfi
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn typechecking(handle: &mut Schala, input: parsing::AST, comp: Option<&mut UnfinishedComputation>) -> Result<parsing::AST, String> {
|
fn typechecking(handle: &mut Schala, input: parsing::AST, comp: Option<&mut UnfinishedComputation>) -> Result<parsing::AST, String> {
|
||||||
match handle.type_context.type_check_ast(&input) {
|
match handle.type_context.borrow_mut().type_check_ast(&input) {
|
||||||
Ok(ty) => {
|
Ok(ty) => {
|
||||||
comp.map(|comp| comp.add_artifact(TraceArtifact::new("type_check", format!("{:?}", ty))));
|
comp.map(|comp| comp.add_artifact(TraceArtifact::new("type_check", format!("{:?}", ty))));
|
||||||
Ok(input)
|
Ok(input)
|
||||||
|
Loading…
Reference in New Issue
Block a user