[fine] Lifetime garbage, big refactor
So it turns out that I can't hold `&str` in token because it makes it impossible to encapsulate a source file in the larger context- self referential structure problems again. Everything gets rebuilt so that the source can be passed through. While we're at it, more things become Rc<> because, man..... life it too short. Semantics in particular has become a giant hub of the module state: we can basically just hold an Rc<Semantics> and have everything we could possibly want to know about a source file, computed lazily if necessary.
This commit is contained in:
parent
d5059dd450
commit
2dbdbb3957
7 changed files with 502 additions and 329 deletions
|
|
@ -5,6 +5,7 @@ use fine::tokens::Lines;
|
|||
use fine::vm::{eval_export_fn, Context};
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::fmt::Write as _;
|
||||
use std::rc::Rc;
|
||||
|
||||
fn rebase_section(source_path: &str, section: &str, value: &str) {
|
||||
let contents = std::fs::read_to_string(source_path)
|
||||
|
|
@ -83,8 +84,8 @@ fn should_rebase() -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn assert_concrete(tree: &SyntaxTree, expected: &str, source_path: &str) {
|
||||
let dump = tree.dump(false);
|
||||
fn assert_concrete(source: Rc<str>, tree: Rc<SyntaxTree>, expected: &str, source_path: &str) {
|
||||
let dump = tree.dump(&source, false);
|
||||
if dump != expected {
|
||||
if should_rebase() {
|
||||
rebase_section(source_path, "concrete", &dump)
|
||||
|
|
@ -128,13 +129,14 @@ macro_rules! semantic_assert_eq {
|
|||
}
|
||||
|
||||
fn assert_type_at(
|
||||
tree: &SyntaxTree,
|
||||
lines: &Lines,
|
||||
source: Rc<str>,
|
||||
tree: Rc<SyntaxTree>,
|
||||
lines: Rc<Lines>,
|
||||
pos: usize,
|
||||
expected: &str,
|
||||
_source_path: &str,
|
||||
) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
let semantics = Semantics::new(source, tree.clone(), lines);
|
||||
let tree_ref = match tree.find_tree_at(pos) {
|
||||
Some(t) => t,
|
||||
None => semantic_panic!(
|
||||
|
|
@ -156,13 +158,14 @@ fn assert_type_at(
|
|||
}
|
||||
|
||||
fn assert_type_error_at(
|
||||
tree: &SyntaxTree,
|
||||
lines: &Lines,
|
||||
source: Rc<str>,
|
||||
tree: Rc<SyntaxTree>,
|
||||
lines: Rc<Lines>,
|
||||
pos: usize,
|
||||
expected: &str,
|
||||
_source_path: &str,
|
||||
) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
let semantics = Semantics::new(source, tree.clone(), lines);
|
||||
let tree_ref = match tree.find_tree_at(pos) {
|
||||
Some(t) => t,
|
||||
None => semantic_panic!(
|
||||
|
|
@ -222,9 +225,15 @@ fn dump_module(out: &mut String, module: &Module) -> std::fmt::Result {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn assert_compiles_to(tree: &SyntaxTree, lines: &Lines, expected: &str, source_path: &str) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
let module = compile(&semantics);
|
||||
fn assert_compiles_to(
|
||||
source: Rc<str>,
|
||||
tree: Rc<SyntaxTree>,
|
||||
lines: Rc<Lines>,
|
||||
expected: &str,
|
||||
source_path: &str,
|
||||
) {
|
||||
let semantics = Rc::new(Semantics::new(source, tree, lines));
|
||||
let module = compile(semantics.clone());
|
||||
|
||||
let mut actual = String::new();
|
||||
dump_module(&mut actual, &module).expect("no dumping?");
|
||||
|
|
@ -244,8 +253,8 @@ fn assert_compiles_to(tree: &SyntaxTree, lines: &Lines, expected: &str, source_p
|
|||
}
|
||||
}
|
||||
|
||||
fn assert_no_errors(tree: &SyntaxTree, lines: &Lines) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
fn assert_no_errors(source: Rc<str>, tree: Rc<SyntaxTree>, lines: Rc<Lines>) {
|
||||
let semantics = Semantics::new(source, tree, lines);
|
||||
check(&semantics);
|
||||
|
||||
let expected_errors: Vec<Error> = Vec::new();
|
||||
|
|
@ -259,10 +268,10 @@ fn assert_no_errors(tree: &SyntaxTree, lines: &Lines) {
|
|||
);
|
||||
}
|
||||
|
||||
fn assert_eval_ok(tree: &SyntaxTree, lines: &Lines, expected: &str) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
fn assert_eval_ok(source: Rc<str>, tree: Rc<SyntaxTree>, lines: Rc<Lines>, expected: &str) {
|
||||
let semantics = Rc::new(Semantics::new(source, tree, lines));
|
||||
|
||||
let module = compile(&semantics);
|
||||
let module = compile(semantics.clone());
|
||||
let mut context = Context::new(module.clone());
|
||||
context.init().expect("Unable to initialize module");
|
||||
|
||||
|
|
@ -301,8 +310,13 @@ fn assert_eval_ok(tree: &SyntaxTree, lines: &Lines, expected: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
fn assert_errors(tree: &SyntaxTree, lines: &Lines, expected_errors: Vec<&str>) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
fn assert_errors(
|
||||
source: Rc<str>,
|
||||
tree: Rc<SyntaxTree>,
|
||||
lines: Rc<Lines>,
|
||||
expected_errors: Vec<&str>,
|
||||
) {
|
||||
let semantics = Semantics::new(source, tree, lines);
|
||||
check(&semantics);
|
||||
|
||||
let errors: Vec<String> = semantics
|
||||
|
|
@ -320,8 +334,8 @@ fn assert_errors(tree: &SyntaxTree, lines: &Lines, expected_errors: Vec<&str>) {
|
|||
);
|
||||
}
|
||||
|
||||
fn assert_check_error(tree: &SyntaxTree, lines: &Lines, expected: &str) {
|
||||
let semantics = Semantics::new(tree, lines);
|
||||
fn assert_check_error(source: Rc<str>, tree: Rc<SyntaxTree>, lines: Rc<Lines>, expected: &str) {
|
||||
let semantics = Semantics::new(source, tree, lines);
|
||||
check(&semantics);
|
||||
|
||||
let errors = semantics.snapshot_errors();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue