Add interpreter context management
This commit is contained in:
parent
501801b63e
commit
d3f5585d07
@ -4,7 +4,6 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use context::Context;
|
||||
use dust_lang::*;
|
||||
|
||||
fn run_fibnacci(interpreter: &Interpreter, i: u8) -> Value {
|
||||
@ -30,13 +29,15 @@ fn run_fibnacci(interpreter: &Interpreter, i: u8) -> Value {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let interpreter = Interpreter::new(Context::new());
|
||||
let interpreter = Interpreter::new();
|
||||
let (tx, rx) = channel();
|
||||
|
||||
for i in 1..10 {
|
||||
let interpreter = interpreter.clone();
|
||||
let tx = tx.clone();
|
||||
|
||||
println!("Spawning thread for fib({})", i);
|
||||
|
||||
thread::spawn(move || {
|
||||
let value = run_fibnacci(&interpreter, i);
|
||||
|
||||
|
@ -23,6 +23,7 @@ use std::{
|
||||
};
|
||||
|
||||
pub use abstract_tree::Type;
|
||||
use standard_library::core_context;
|
||||
pub use value::Value;
|
||||
|
||||
use abstract_tree::AbstractTree;
|
||||
@ -33,7 +34,7 @@ use lexer::{lex, Token};
|
||||
use parser::{parse, parser};
|
||||
|
||||
pub fn interpret(source_id: &str, source: &str) -> Result<Option<Value>, InterpreterError> {
|
||||
let interpreter = Interpreter::new(Context::new());
|
||||
let interpreter = Interpreter::new();
|
||||
|
||||
interpreter.run(Arc::from(source_id), Arc::from(source))
|
||||
}
|
||||
@ -44,14 +45,14 @@ pub fn interpret(source_id: &str, source: &str) -> Result<Option<Value>, Interpr
|
||||
/// used to identify the source of errors and to provide more detailed error messages.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Interpreter {
|
||||
context: Context,
|
||||
contexts: Arc<RwLock<HashMap<Arc<str>, Context>>>,
|
||||
sources: Arc<RwLock<HashMap<Arc<str>, Arc<str>>>>,
|
||||
}
|
||||
|
||||
impl Interpreter {
|
||||
pub fn new(context: Context) -> Self {
|
||||
pub fn new() -> Self {
|
||||
Interpreter {
|
||||
context,
|
||||
contexts: Arc::new(RwLock::new(HashMap::new())),
|
||||
sources: Arc::new(RwLock::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
@ -111,8 +112,9 @@ impl Interpreter {
|
||||
source_id: source_id.clone(),
|
||||
errors,
|
||||
})?;
|
||||
let context = self.get_or_create_context(&source_id);
|
||||
let value_option = abstract_tree
|
||||
.run(&self.context, true)
|
||||
.run(&context, true)
|
||||
.map_err(|errors| InterpreterError { source_id, errors })?;
|
||||
|
||||
Ok(value_option)
|
||||
@ -121,6 +123,20 @@ impl Interpreter {
|
||||
pub fn sources(&self) -> hash_map::IntoIter<Arc<str>, Arc<str>> {
|
||||
self.sources.read().unwrap().clone().into_iter()
|
||||
}
|
||||
|
||||
fn get_or_create_context(&self, source_id: &Arc<str>) -> Context {
|
||||
let mut contexts = self.contexts.write().unwrap();
|
||||
|
||||
if let Some(context) = contexts.get(source_id) {
|
||||
context.clone()
|
||||
} else {
|
||||
let context = core_context().clone();
|
||||
|
||||
contexts.insert(source_id.clone(), context.clone());
|
||||
|
||||
context
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -7,7 +7,7 @@ use std::{
|
||||
};
|
||||
|
||||
use ariadne::sources;
|
||||
use dust_lang::{context::Context, *};
|
||||
use dust_lang::*;
|
||||
use nu_ansi_term::{Color, Style};
|
||||
use reedline::{
|
||||
default_emacs_keybindings, ColumnarMenu, DefaultHinter, EditCommand, Emacs, KeyCode,
|
||||
@ -15,8 +15,8 @@ use reedline::{
|
||||
SqliteBackedHistory,
|
||||
};
|
||||
|
||||
pub fn run_shell(context: Context) -> Result<(), io::Error> {
|
||||
let interpreter = Interpreter::new(context.clone());
|
||||
pub fn run_shell() -> Result<(), io::Error> {
|
||||
let interpreter = Interpreter::new();
|
||||
let mut keybindings = default_emacs_keybindings();
|
||||
|
||||
keybindings.add_binding(
|
||||
|
@ -14,7 +14,7 @@ use std::{
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use dust_lang::{context::Context, Interpreter};
|
||||
use dust_lang::Interpreter;
|
||||
|
||||
/// Command-line arguments to be parsed.
|
||||
#[derive(Parser, Debug)]
|
||||
@ -56,8 +56,7 @@ fn main() {
|
||||
.init();
|
||||
|
||||
let args = Args::parse();
|
||||
let context = Context::new_with_std_core().unwrap();
|
||||
let interpreter = Interpreter::new(context.clone());
|
||||
let interpreter = Interpreter::new();
|
||||
|
||||
let (source_id, source): (Arc<str>, Arc<str>) = if let Some(path) = args.path {
|
||||
let source = read_to_string(&path).unwrap();
|
||||
@ -66,7 +65,7 @@ fn main() {
|
||||
} else if let Some(command) = args.command {
|
||||
(Arc::from("command"), Arc::from(command))
|
||||
} else {
|
||||
match run_shell(context) {
|
||||
match run_shell() {
|
||||
Ok(_) => {}
|
||||
Err(error) => eprintln!("{error}"),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user