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, time::Duration,
}; };
use context::Context;
use dust_lang::*; use dust_lang::*;
fn run_fibnacci(interpreter: &Interpreter, i: u8) -> Value { fn run_fibnacci(interpreter: &Interpreter, i: u8) -> Value {
@ -30,13 +29,15 @@ fn run_fibnacci(interpreter: &Interpreter, i: u8) -> Value {
} }
fn main() { fn main() {
let interpreter = Interpreter::new(Context::new()); let interpreter = Interpreter::new();
let (tx, rx) = channel(); let (tx, rx) = channel();
for i in 1..10 { for i in 1..10 {
let interpreter = interpreter.clone(); let interpreter = interpreter.clone();
let tx = tx.clone(); let tx = tx.clone();
println!("Spawning thread for fib({})", i);
thread::spawn(move || { thread::spawn(move || {
let value = run_fibnacci(&interpreter, i); let value = run_fibnacci(&interpreter, i);

View File

@ -23,6 +23,7 @@ use std::{
}; };
pub use abstract_tree::Type; pub use abstract_tree::Type;
use standard_library::core_context;
pub use value::Value; pub use value::Value;
use abstract_tree::AbstractTree; use abstract_tree::AbstractTree;
@ -33,7 +34,7 @@ use lexer::{lex, Token};
use parser::{parse, parser}; use parser::{parse, parser};
pub fn interpret(source_id: &str, source: &str) -> Result<Option<Value>, InterpreterError> { 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)) 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. /// used to identify the source of errors and to provide more detailed error messages.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Interpreter { pub struct Interpreter {
context: Context, contexts: Arc<RwLock<HashMap<Arc<str>, Context>>>,
sources: Arc<RwLock<HashMap<Arc<str>, Arc<str>>>>, sources: Arc<RwLock<HashMap<Arc<str>, Arc<str>>>>,
} }
impl Interpreter { impl Interpreter {
pub fn new(context: Context) -> Self { pub fn new() -> Self {
Interpreter { Interpreter {
context, contexts: Arc::new(RwLock::new(HashMap::new())),
sources: Arc::new(RwLock::new(HashMap::new())), sources: Arc::new(RwLock::new(HashMap::new())),
} }
} }
@ -111,8 +112,9 @@ impl Interpreter {
source_id: source_id.clone(), source_id: source_id.clone(),
errors, errors,
})?; })?;
let context = self.get_or_create_context(&source_id);
let value_option = abstract_tree let value_option = abstract_tree
.run(&self.context, true) .run(&context, true)
.map_err(|errors| InterpreterError { source_id, errors })?; .map_err(|errors| InterpreterError { source_id, errors })?;
Ok(value_option) Ok(value_option)
@ -121,6 +123,20 @@ impl Interpreter {
pub fn sources(&self) -> hash_map::IntoIter<Arc<str>, Arc<str>> { pub fn sources(&self) -> hash_map::IntoIter<Arc<str>, Arc<str>> {
self.sources.read().unwrap().clone().into_iter() 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)] #[derive(Debug, PartialEq)]

View File

@ -7,7 +7,7 @@ use std::{
}; };
use ariadne::sources; use ariadne::sources;
use dust_lang::{context::Context, *}; use dust_lang::*;
use nu_ansi_term::{Color, Style}; use nu_ansi_term::{Color, Style};
use reedline::{ use reedline::{
default_emacs_keybindings, ColumnarMenu, DefaultHinter, EditCommand, Emacs, KeyCode, default_emacs_keybindings, ColumnarMenu, DefaultHinter, EditCommand, Emacs, KeyCode,
@ -15,8 +15,8 @@ use reedline::{
SqliteBackedHistory, SqliteBackedHistory,
}; };
pub fn run_shell(context: Context) -> Result<(), io::Error> { pub fn run_shell() -> Result<(), io::Error> {
let interpreter = Interpreter::new(context.clone()); let interpreter = Interpreter::new();
let mut keybindings = default_emacs_keybindings(); let mut keybindings = default_emacs_keybindings();
keybindings.add_binding( keybindings.add_binding(

View File

@ -14,7 +14,7 @@ use std::{
sync::Arc, sync::Arc,
}; };
use dust_lang::{context::Context, Interpreter}; use dust_lang::Interpreter;
/// Command-line arguments to be parsed. /// Command-line arguments to be parsed.
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -56,8 +56,7 @@ fn main() {
.init(); .init();
let args = Args::parse(); let args = Args::parse();
let context = Context::new_with_std_core().unwrap(); let interpreter = Interpreter::new();
let interpreter = Interpreter::new(context.clone());
let (source_id, source): (Arc<str>, Arc<str>) = if let Some(path) = args.path { let (source_id, source): (Arc<str>, Arc<str>) = if let Some(path) = args.path {
let source = read_to_string(&path).unwrap(); let source = read_to_string(&path).unwrap();
@ -66,7 +65,7 @@ fn main() {
} else if let Some(command) = args.command { } else if let Some(command) = args.command {
(Arc::from("command"), Arc::from(command)) (Arc::from("command"), Arc::from(command))
} else { } else {
match run_shell(context) { match run_shell() {
Ok(_) => {} Ok(_) => {}
Err(error) => eprintln!("{error}"), Err(error) => eprintln!("{error}"),
} }