Add interpreter context management
This commit is contained in:
parent
501801b63e
commit
d3f5585d07
@ -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);
|
||||||
|
|
||||||
|
@ -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)]
|
||||||
|
@ -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(
|
||||||
|
@ -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}"),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user