Add interpreter context management

This commit is contained in:
Jeff 2024-07-15 16:58:54 -04:00
parent 501801b63e
commit d3f5585d07
4 changed files with 30 additions and 14 deletions

View File

@ -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);

View File

@ -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)]

View File

@ -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(

View File

@ -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}"),
}