Refactoring and troubleshooting
This commit is contained in:
parent
041480a953
commit
890baa5d51
@ -112,7 +112,7 @@ impl AbstractTree {
|
|||||||
|
|
||||||
pub fn run(
|
pub fn run(
|
||||||
self,
|
self,
|
||||||
context: &mut Context,
|
context: &Context,
|
||||||
manage_memory: bool,
|
manage_memory: bool,
|
||||||
) -> Result<Option<Value>, Vec<DustError>> {
|
) -> Result<Option<Value>, Vec<DustError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
@ -296,13 +296,6 @@ impl AbstractNode for ValueNode {
|
|||||||
body,
|
body,
|
||||||
} => {
|
} => {
|
||||||
let function_context = context.create_child();
|
let function_context = context.create_child();
|
||||||
let mut value_parameters = Vec::with_capacity(constructors.len());
|
|
||||||
|
|
||||||
for (identifier, constructor) in constructors {
|
|
||||||
let r#type = constructor.construct(&function_context)?;
|
|
||||||
|
|
||||||
value_parameters.push((identifier, r#type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(identifiers) = &type_parameters {
|
if let Some(identifiers) = &type_parameters {
|
||||||
for identifier in identifiers {
|
for identifier in identifiers {
|
||||||
@ -316,6 +309,14 @@ impl AbstractNode for ValueNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut value_parameters = Vec::with_capacity(constructors.len());
|
||||||
|
|
||||||
|
for (identifier, constructor) in constructors {
|
||||||
|
let r#type = constructor.construct(&function_context)?;
|
||||||
|
|
||||||
|
value_parameters.push((identifier, r#type));
|
||||||
|
}
|
||||||
|
|
||||||
let return_type = if let Some(constructor) = return_type {
|
let return_type = if let Some(constructor) = return_type {
|
||||||
Some(constructor.construct(&function_context)?)
|
Some(constructor.construct(&function_context)?)
|
||||||
} else {
|
} else {
|
||||||
|
@ -14,16 +14,15 @@ use std::{
|
|||||||
|
|
||||||
use abstract_tree::{AbstractTree, Type};
|
use abstract_tree::{AbstractTree, Type};
|
||||||
use ariadne::{Color, Config, Fmt, Label, Report, ReportKind};
|
use ariadne::{Color, Config, Fmt, Label, Report, ReportKind};
|
||||||
use chumsky::prelude::*;
|
|
||||||
use context::Context;
|
use context::Context;
|
||||||
use error::{DustError, RuntimeError, TypeConflict, ValidationError};
|
use error::{DustError, RuntimeError, TypeConflict, ValidationError};
|
||||||
use lexer::{lex, Token};
|
use lexer::{lex, Token};
|
||||||
use parser::{parse, parser};
|
use parser::parse;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
pub use value::Value;
|
pub use value::Value;
|
||||||
|
|
||||||
pub fn interpret<'src>(source_id: &str, source: &str) -> Result<Option<Value>, InterpreterError> {
|
pub fn interpret<'src>(source_id: &str, source: &str) -> Result<Option<Value>, InterpreterError> {
|
||||||
let mut interpreter = Interpreter::new(Context::new(None));
|
let interpreter = Interpreter::new(Context::new(None));
|
||||||
|
|
||||||
interpreter.load_std()?;
|
interpreter.load_std()?;
|
||||||
interpreter.run(Arc::from(source_id), Arc::from(source))
|
interpreter.run(Arc::from(source_id), Arc::from(source))
|
||||||
@ -33,7 +32,7 @@ pub fn interpret_without_std(
|
|||||||
source_id: &str,
|
source_id: &str,
|
||||||
source: &str,
|
source: &str,
|
||||||
) -> Result<Option<Value>, InterpreterError> {
|
) -> Result<Option<Value>, InterpreterError> {
|
||||||
let mut interpreter = Interpreter::new(Context::new(None));
|
let interpreter = Interpreter::new(Context::new(None));
|
||||||
|
|
||||||
interpreter.run(Arc::from(source_id.to_string()), Arc::from(source))
|
interpreter.run(Arc::from(source_id.to_string()), Arc::from(source))
|
||||||
}
|
}
|
||||||
@ -51,11 +50,11 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lex<'source>(
|
pub fn lex<'src>(
|
||||||
&mut self,
|
&self,
|
||||||
source_id: Arc<str>,
|
source_id: Arc<str>,
|
||||||
source: &'source str,
|
source: &'src str,
|
||||||
) -> Result<Vec<Token<'source>>, InterpreterError> {
|
) -> Result<Vec<Token<'src>>, InterpreterError> {
|
||||||
let mut sources = self.sources.write().unwrap();
|
let mut sources = self.sources.write().unwrap();
|
||||||
|
|
||||||
sources.clear();
|
sources.clear();
|
||||||
@ -66,10 +65,10 @@ impl Interpreter {
|
|||||||
.map_err(|errors| InterpreterError { source_id, errors })
|
.map_err(|errors| InterpreterError { source_id, errors })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse<'source>(
|
pub fn parse<'src>(
|
||||||
&mut self,
|
&self,
|
||||||
source_id: Arc<str>,
|
source_id: Arc<str>,
|
||||||
source: &'source str,
|
source: &'src str,
|
||||||
) -> Result<AbstractTree, InterpreterError> {
|
) -> Result<AbstractTree, InterpreterError> {
|
||||||
let mut sources = self.sources.write().unwrap();
|
let mut sources = self.sources.write().unwrap();
|
||||||
|
|
||||||
@ -84,7 +83,7 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&mut self,
|
&self,
|
||||||
source_id: Arc<str>,
|
source_id: Arc<str>,
|
||||||
source: Arc<str>,
|
source: Arc<str>,
|
||||||
) -> Result<Option<Value>, InterpreterError> {
|
) -> Result<Option<Value>, InterpreterError> {
|
||||||
@ -102,18 +101,20 @@ impl Interpreter {
|
|||||||
errors,
|
errors,
|
||||||
})?;
|
})?;
|
||||||
let value_option = abstract_tree
|
let value_option = abstract_tree
|
||||||
.run(&mut self.context, true)
|
.run(&self.context, true)
|
||||||
.map_err(|errors| InterpreterError { source_id, errors })?;
|
.map_err(|errors| InterpreterError { source_id, errors })?;
|
||||||
|
|
||||||
Ok(value_option)
|
Ok(value_option)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_std(&mut self) -> Result<(), InterpreterError> {
|
pub fn load_std(&self) -> Result<(), InterpreterError> {
|
||||||
let std_sources: [(Arc<str>, Arc<str>); 5] = [
|
let std_core_source: (Arc<str>, Arc<str>) = {
|
||||||
(
|
(
|
||||||
Arc::from("std/core.ds"),
|
Arc::from("std/core.ds"),
|
||||||
Arc::from(include_str!("../../std/core.ds")),
|
Arc::from(include_str!("../../std/core.ds")),
|
||||||
),
|
)
|
||||||
|
};
|
||||||
|
let std_sources: [(Arc<str>, Arc<str>); 4] = [
|
||||||
(
|
(
|
||||||
Arc::from("std/fs.ds"),
|
Arc::from("std/fs.ds"),
|
||||||
Arc::from(include_str!("../../std/fs.ds")),
|
Arc::from(include_str!("../../std/fs.ds")),
|
||||||
@ -134,39 +135,21 @@ impl Interpreter {
|
|||||||
|
|
||||||
log::info!("Start loading standard library...");
|
log::info!("Start loading standard library...");
|
||||||
|
|
||||||
let error = std_sources
|
// Always load the core library first because other parts of the standard library may depend
|
||||||
.into_par_iter()
|
// on it.
|
||||||
.find_map_any(|(source_id, source)| {
|
self.run(std_core_source.0, std_core_source.1)?;
|
||||||
self.sources
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.push((source_id.clone(), source.clone()));
|
|
||||||
|
|
||||||
let lex_result = lex(source.as_ref()).map_err(|errors| InterpreterError {
|
let error = if cfg!(test) {
|
||||||
source_id: source_id.clone(),
|
// In debug mode, load the standard library sequentially to get consistent errors.
|
||||||
errors,
|
std_sources
|
||||||
});
|
.into_iter()
|
||||||
let tokens = match lex_result {
|
.find_map(|(source_id, source)| self.run(source_id, source).err())
|
||||||
Ok(tokens) => tokens,
|
} else {
|
||||||
Err(error) => return Some(error),
|
// In release mode, load the standard library asynchronously.
|
||||||
};
|
std_sources
|
||||||
let parse_result = parser(true)
|
.into_par_iter()
|
||||||
.parse(tokens.spanned((tokens.len()..tokens.len()).into()))
|
.find_map_any(|(source_id, source)| self.run(source_id, source).err())
|
||||||
.into_result()
|
};
|
||||||
.map_err(|errors| InterpreterError {
|
|
||||||
source_id: source_id.clone(),
|
|
||||||
errors: errors.into_iter().map(DustError::from).collect(),
|
|
||||||
});
|
|
||||||
let abstract_tree = match parse_result {
|
|
||||||
Ok(statements) => AbstractTree::new(statements),
|
|
||||||
Err(error) => return Some(error),
|
|
||||||
};
|
|
||||||
|
|
||||||
abstract_tree
|
|
||||||
.run(&mut self.context.clone(), false)
|
|
||||||
.map_err(|errors| InterpreterError { source_id, errors })
|
|
||||||
.err()
|
|
||||||
});
|
|
||||||
|
|
||||||
log::info!("Finish loading standard library.");
|
log::info!("Finish loading standard library.");
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ use reedline::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn run_shell(context: Context) -> Result<(), io::Error> {
|
pub fn run_shell(context: Context) -> Result<(), io::Error> {
|
||||||
let mut interpreter = Interpreter::new(context.clone());
|
let interpreter = Interpreter::new(context.clone());
|
||||||
let mut keybindings = default_emacs_keybindings();
|
let mut keybindings = default_emacs_keybindings();
|
||||||
|
|
||||||
keybindings.add_binding(
|
keybindings.add_binding(
|
||||||
|
@ -57,7 +57,7 @@ fn main() {
|
|||||||
|
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
let context = Context::new(None);
|
let context = Context::new(None);
|
||||||
let mut interpreter = Interpreter::new(context.clone());
|
let interpreter = Interpreter::new(context.clone());
|
||||||
|
|
||||||
if !args.no_std {
|
if !args.no_std {
|
||||||
let load_std_result = interpreter.load_std();
|
let load_std_result = interpreter.load_std();
|
||||||
|
Loading…
Reference in New Issue
Block a user