From 1ac0c0bfc54a449eb3db339a6b4a6654080b3826 Mon Sep 17 00:00:00 2001 From: JT Date: Thu, 22 Jul 2021 19:33:38 +1200 Subject: [PATCH] Move to refcell for permanent parser state --- src/main.rs | 152 +++++++++++--------- src/parser.rs | 43 +++--- src/parser_state.rs | 307 +++++++++++++++++++--------------------- src/syntax_highlight.rs | 6 +- 4 files changed, 258 insertions(+), 250 deletions(-) diff --git a/src/main.rs b/src/main.rs index 52f201be34..385805e8c7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,82 +1,92 @@ -use std::sync::Arc; +use std::{cell::RefCell, rc::Rc}; use engine_q::{ParserState, ParserWorkingSet, Signature, SyntaxShape}; fn main() -> std::io::Result<()> { - let mut parser_state = Arc::new(ParserState::new()); - let mut working_set = ParserWorkingSet::new(Some(parser_state.clone())); + let parser_state = Rc::new(RefCell::new(ParserState::new())); + let delta = { + let parser_state = parser_state.borrow(); + let mut working_set = ParserWorkingSet::new(&*parser_state); - let sig = Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition"); - working_set.add_decl(sig.into()); + let sig = + Signature::build("where").required("cond", SyntaxShape::RowCondition, "condition"); + working_set.add_decl(sig.into()); - let sig = Signature::build("if") - .required("cond", SyntaxShape::RowCondition, "condition") - .required("then_block", SyntaxShape::Block, "then block") - .required( - "else", - SyntaxShape::Literal(b"else".to_vec()), - "else keyword", - ) - .required("else_block", SyntaxShape::Block, "else block"); - working_set.add_decl(sig.into()); + let sig = Signature::build("if") + .required("cond", SyntaxShape::RowCondition, "condition") + .required("then_block", SyntaxShape::Block, "then block") + .required( + "else", + SyntaxShape::Literal(b"else".to_vec()), + "else keyword", + ) + .required("else_block", SyntaxShape::Block, "else block"); + working_set.add_decl(sig.into()); - let sig = Signature::build("let") - .required("var_name", SyntaxShape::Variable, "variable name") - .required("=", SyntaxShape::Literal(b"=".to_vec()), "equals sign") - .required( - "value", - SyntaxShape::Expression, - "the value to set the variable to", + let sig = Signature::build("let") + .required("var_name", SyntaxShape::Variable, "variable name") + .required("=", SyntaxShape::Literal(b"=".to_vec()), "equals sign") + .required( + "value", + SyntaxShape::Expression, + "the value to set the variable to", + ); + working_set.add_decl(sig.into()); + + let sig = Signature::build("alias") + .required("var_name", SyntaxShape::Variable, "variable name") + .required("=", SyntaxShape::Literal(b"=".to_vec()), "equals sign") + .required( + "value", + SyntaxShape::Expression, + "the value to set the variable to", + ); + working_set.add_decl(sig.into()); + + let sig = Signature::build("sum").required( + "arg", + SyntaxShape::List(Box::new(SyntaxShape::Number)), + "list of numbers", ); - working_set.add_decl(sig.into()); + working_set.add_decl(sig.into()); - let sig = Signature::build("alias") - .required("var_name", SyntaxShape::Variable, "variable name") - .required("=", SyntaxShape::Literal(b"=".to_vec()), "equals sign") - .required( - "value", - SyntaxShape::Expression, - "the value to set the variable to", - ); - working_set.add_decl(sig.into()); + let sig = Signature::build("def") + .required("def_name", SyntaxShape::String, "definition name") + .required("params", SyntaxShape::Signature, "parameters") + .required("block", SyntaxShape::Block, "body of the definition"); + working_set.add_decl(sig.into()); - let sig = Signature::build("sum").required( - "arg", - SyntaxShape::List(Box::new(SyntaxShape::Number)), - "list of numbers", - ); - working_set.add_decl(sig.into()); + // let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); + // working_set.add_decl(sig.into()); - let sig = Signature::build("def") - .required("def_name", SyntaxShape::String, "definition name") - .required("params", SyntaxShape::Signature, "parameters") - .required("block", SyntaxShape::Block, "body of the definition"); - working_set.add_decl(sig.into()); + // let sig = Signature::build("bar") + // .named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')) + // .switch("--rock", "rock!!", Some('r')); + // working_set.add_decl(sig.into()); - // let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); - // working_set.add_decl(sig.into()); + let sig = Signature::build("add"); + working_set.add_decl(sig.into()); + let sig = Signature::build("add it"); + working_set.add_decl(sig.into()); - // let sig = Signature::build("bar") - // .named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')) - // .switch("--rock", "rock!!", Some('r')); - // working_set.add_decl(sig.into()); + let sig = Signature::build("add it together") + .required("x", SyntaxShape::Int, "x value") + .required("y", SyntaxShape::Int, "y value"); + working_set.add_decl(sig.into()); - let sig = Signature::build("add"); - working_set.add_decl(sig.into()); - let sig = Signature::build("add it"); - working_set.add_decl(sig.into()); + working_set.delta + }; - let sig = Signature::build("add it together") - .required("x", SyntaxShape::Int, "x value") - .required("y", SyntaxShape::Int, "y value"); - working_set.add_decl(sig.into()); - ParserState::merge_working_set(&mut parser_state, working_set); + { + ParserState::merge_delta(&mut *parser_state.borrow_mut(), delta); + } if let Some(path) = std::env::args().nth(1) { // let file = std::fs::read(&path)?; // let (output, err) = working_set.parse_file(&path, file); - let mut working_set = ParserWorkingSet::new(Some(parser_state.clone())); + let parser_state = parser_state.borrow(); + let mut working_set = ParserWorkingSet::new(&*parser_state); let (output, err) = working_set.parse_source(path.as_bytes(), false); println!("{:#?}", output); println!("error: {:?}", err); @@ -113,18 +123,22 @@ fn main() -> std::io::Result<()> { break; } println!("input: '{}'", s); - let mut working_set = ParserWorkingSet::new(Some(parser_state.clone())); - let (output, err) = working_set.parse_file( - &format!("line_{}", current_line), - s.as_bytes(), - false, - ); - ParserState::merge_working_set(&mut parser_state, working_set); - println!("{:#?}", parser_state); + let delta = { + let parser_state = parser_state.borrow(); + let mut working_set = ParserWorkingSet::new(&*parser_state); + let (output, err) = working_set.parse_file( + &format!("line_{}", current_line), + s.as_bytes(), + false, + ); + println!("{:#?}", output); + println!("Error: {:?}", err); + working_set.delta + }; - println!("{:#?}", output); - println!("Error: {:?}", err); + ParserState::merge_delta(&mut *parser_state.borrow_mut(), delta); + // println!("{:#?}", parser_state); } Signal::CtrlC => { println!("Ctrl-c"); diff --git a/src/parser.rs b/src/parser.rs index 84c6dc3d57..3598bbeaa9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -345,7 +345,7 @@ fn span(spans: &[Span]) -> Span { } } -impl ParserWorkingSet { +impl<'a> ParserWorkingSet<'a> { pub fn parse_external_call(&mut self, spans: &[Span]) -> (Expression, Option) { // TODO: add external parsing let mut args = vec![]; @@ -990,7 +990,7 @@ impl ParserWorkingSet { } let span = Span { start, end }; - let source = &self.file_contents[..span.end]; + let source = &self.delta.file_contents[..span.end]; let (output, err) = lex(&source, span.start, &[b'\n', b','], &[b':']); error = error.or(err); @@ -1004,7 +1004,7 @@ impl ParserWorkingSet { contents: crate::TokenContents::Item, span, } => { - let contents = &self.file_contents[span.start..span.end]; + let contents = &self.delta.file_contents[span.start..span.end]; if contents == b":" { match parse_mode { @@ -1182,7 +1182,7 @@ impl ParserWorkingSet { contents: crate::TokenContents::Comment, span, } => { - let contents = &self.file_contents[span.start + 1..span.end]; + let contents = &self.delta.file_contents[span.start + 1..span.end]; let mut contents = String::from_utf8_lossy(contents).to_string(); contents = contents.trim().into(); @@ -1272,7 +1272,7 @@ impl ParserWorkingSet { } let span = Span { start, end }; - let source = &self.file_contents[..span.end]; + let source = &self.delta.file_contents[..span.end]; let (output, err) = lex(&source, span.start, &[b'\n', b','], &[]); error = error.or(err); @@ -1336,7 +1336,7 @@ impl ParserWorkingSet { let span = Span { start, end }; - let source = &self.file_contents[..end]; + let source = &self.delta.file_contents[..end]; let (output, err) = lex(&source, start, &[b'\n', b','], &[]); error = error.or(err); @@ -1426,7 +1426,7 @@ impl ParserWorkingSet { let span = Span { start, end }; - let source = &self.file_contents[..end]; + let source = &self.delta.file_contents[..end]; let (output, err) = lex(&source, start, &[], &[]); error = error.or(err); @@ -1947,13 +1947,14 @@ impl ParserWorkingSet { #[cfg(test)] mod tests { - use crate::{ParseError, Signature}; + use crate::{parser_state, ParseError, ParserState, Signature}; use super::*; #[test] pub fn parse_int() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let (block, err) = working_set.parse_source(b"3", true); @@ -1970,7 +1971,8 @@ mod tests { #[test] pub fn parse_call() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); working_set.add_decl(sig.into()); @@ -1993,7 +1995,8 @@ mod tests { #[test] pub fn parse_call_missing_flag_arg() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); working_set.add_decl(sig.into()); @@ -2004,7 +2007,8 @@ mod tests { #[test] pub fn parse_call_missing_short_flag_arg() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); working_set.add_decl(sig.into()); @@ -2015,7 +2019,8 @@ mod tests { #[test] pub fn parse_call_too_many_shortflag_args() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo") .named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')) @@ -2030,7 +2035,8 @@ mod tests { #[test] pub fn parse_call_unknown_shorthand() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j')); working_set.add_decl(sig.into()); @@ -2040,7 +2046,8 @@ mod tests { #[test] pub fn parse_call_extra_positional() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").switch("--jazz", "jazz!!", Some('j')); working_set.add_decl(sig.into()); @@ -2050,7 +2057,8 @@ mod tests { #[test] pub fn parse_call_missing_req_positional() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").required("jazz", SyntaxShape::Int, "jazz!!"); working_set.add_decl(sig.into()); @@ -2060,7 +2068,8 @@ mod tests { #[test] pub fn parse_call_missing_req_flag() { - let mut working_set = ParserWorkingSet::new(None); + let parser_state = ParserState::new(); + let mut working_set = ParserWorkingSet::new(&parser_state); let sig = Signature::build("foo").required_named("--jazz", SyntaxShape::Int, "jazz!!", None); diff --git a/src/parser_state.rs b/src/parser_state.rs index db8447f5dd..894687a117 100644 --- a/src/parser_state.rs +++ b/src/parser_state.rs @@ -1,5 +1,5 @@ use crate::{parser::Block, Declaration, Span}; -use std::{collections::HashMap, sync::Arc}; +use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc}; #[derive(Debug)] pub struct ParserState { @@ -54,29 +54,22 @@ impl ParserState { } } - pub fn merge_working_set(this: &mut Arc, mut working_set: ParserWorkingSet) { - // Remove the working set's reference to the permanent state so we can safely take a mutable reference - working_set.permanent_state = None; - + pub fn merge_delta(this: &mut ParserState, mut delta: ParserDelta) { // Take the mutable reference and extend the permanent state from the working set - if let Some(this) = std::sync::Arc::::get_mut(this) { - this.files.extend(working_set.files); - this.file_contents.extend(working_set.file_contents); - this.decls.extend(working_set.decls); - this.vars.extend(working_set.vars); - this.blocks.extend(working_set.blocks); + this.files.extend(delta.files); + this.file_contents.extend(delta.file_contents); + this.decls.extend(delta.decls); + this.vars.extend(delta.vars); + this.blocks.extend(delta.blocks); - if let Some(last) = this.scope.last_mut() { - let first = working_set.scope.remove(0); - for item in first.decls.into_iter() { - last.decls.insert(item.0, item.1); - } - for item in first.vars.into_iter() { - last.vars.insert(item.0, item.1); - } + if let Some(last) = this.scope.last_mut() { + let first = delta.scope.remove(0); + for item in first.decls.into_iter() { + last.decls.insert(item.0, item.1); + } + for item in first.vars.into_iter() { + last.vars.insert(item.0, item.1); } - } else { - panic!("Internal error: merging working set should always succeed"); } } @@ -123,111 +116,32 @@ impl ParserState { } #[derive(Debug)] -pub struct ParserWorkingSet { +pub struct ParserWorkingSet<'a> { + permanent_state: &'a ParserState, + pub delta: ParserDelta, +} + +#[derive(Debug)] +pub struct ParserDelta { files: Vec<(String, usize, usize)>, pub(crate) file_contents: Vec, vars: Vec, // indexed by VarId decls: Vec, // indexed by DeclId blocks: Vec, // indexed by BlockId - permanent_state: Option>, scope: Vec, } -impl ParserWorkingSet { - pub fn new(permanent_state: Option>) -> Self { - Self { - files: vec![], - file_contents: vec![], - vars: vec![], - decls: vec![], - blocks: vec![], - permanent_state, - scope: vec![ScopeFrame::new()], - } - } - +impl ParserDelta { pub fn num_files(&self) -> usize { - let parent_len = if let Some(permanent_state) = &self.permanent_state { - permanent_state.num_files() - } else { - 0 - }; - - self.files.len() + parent_len + self.files.len() } pub fn num_decls(&self) -> usize { - let parent_len = if let Some(permanent_state) = &self.permanent_state { - permanent_state.num_decls() - } else { - 0 - }; - - self.decls.len() + parent_len + self.decls.len() } pub fn num_blocks(&self) -> usize { - let parent_len = if let Some(permanent_state) = &self.permanent_state { - permanent_state.num_blocks() - } else { - 0 - }; - - self.blocks.len() + parent_len - } - - pub fn add_decl(&mut self, decl: Declaration) -> DeclId { - let name = decl.signature.name.as_bytes().to_vec(); - - self.decls.push(decl); - let decl_id = self.num_decls() - 1; - - let scope_frame = self - .scope - .last_mut() - .expect("internal error: missing required scope frame"); - scope_frame.decls.insert(name, decl_id); - - decl_id - } - - pub fn add_block(&mut self, block: Block) -> BlockId { - self.blocks.push(block); - - self.num_blocks() - 1 - } - - pub fn next_span_start(&self) -> usize { - if let Some(permanent_state) = &self.permanent_state { - permanent_state.next_span_start() + self.file_contents.len() - } else { - self.file_contents.len() - } - } - - pub fn add_file(&mut self, filename: String, contents: &[u8]) -> usize { - let next_span_start = self.next_span_start(); - - self.file_contents.extend(contents); - - let next_span_end = self.next_span_start(); - - self.files.push((filename, next_span_start, next_span_end)); - - self.num_files() - 1 - } - - pub fn get_span_contents(&self, span: Span) -> &[u8] { - if let Some(permanent_state) = &self.permanent_state { - let permanent_end = permanent_state.next_span_start(); - if permanent_end <= span.start { - &self.file_contents[(span.start - permanent_end)..(span.end - permanent_end)] - } else { - &permanent_state.file_contents[span.start..span.end] - } - } else { - &self.file_contents[span.start..span.end] - } + self.blocks.len() } pub fn enter_scope(&mut self) { @@ -237,19 +151,102 @@ impl ParserWorkingSet { pub fn exit_scope(&mut self) { self.scope.pop(); } +} + +impl<'a> ParserWorkingSet<'a> { + pub fn new(permanent_state: &'a ParserState) -> Self { + Self { + delta: ParserDelta { + files: vec![], + file_contents: vec![], + vars: vec![], + decls: vec![], + blocks: vec![], + scope: vec![ScopeFrame::new()], + }, + permanent_state, + } + } + + pub fn num_files(&self) -> usize { + self.delta.num_files() + self.permanent_state.num_files() + } + + pub fn num_decls(&self) -> usize { + self.delta.num_decls() + self.permanent_state.num_decls() + } + + pub fn num_blocks(&self) -> usize { + self.delta.num_blocks() + self.permanent_state.num_blocks() + } + + pub fn add_decl(&mut self, decl: Declaration) -> DeclId { + let name = decl.signature.name.as_bytes().to_vec(); + + self.delta.decls.push(decl); + let decl_id = self.num_decls() - 1; + + let scope_frame = self + .delta + .scope + .last_mut() + .expect("internal error: missing required scope frame"); + scope_frame.decls.insert(name, decl_id); + + decl_id + } + + pub fn add_block(&mut self, block: Block) -> BlockId { + self.delta.blocks.push(block); + + self.num_blocks() - 1 + } + + pub fn next_span_start(&self) -> usize { + self.permanent_state.next_span_start() + self.delta.file_contents.len() + } + + pub fn add_file(&mut self, filename: String, contents: &[u8]) -> usize { + let next_span_start = self.next_span_start(); + + self.delta.file_contents.extend(contents); + + let next_span_end = self.next_span_start(); + + self.delta + .files + .push((filename, next_span_start, next_span_end)); + + self.num_files() - 1 + } + + pub fn get_span_contents(&self, span: Span) -> &[u8] { + let permanent_end = self.permanent_state.next_span_start(); + if permanent_end <= span.start { + &self.delta.file_contents[(span.start - permanent_end)..(span.end - permanent_end)] + } else { + &self.permanent_state.file_contents[span.start..span.end] + } + } + + pub fn enter_scope(&mut self) { + self.delta.enter_scope(); + } + + pub fn exit_scope(&mut self) { + self.delta.exit_scope(); + } pub fn find_decl(&self, name: &[u8]) -> Option { - for scope in self.scope.iter().rev() { + for scope in self.delta.scope.iter().rev() { if let Some(decl_id) = scope.decls.get(name) { return Some(*decl_id); } } - if let Some(permanent_state) = &self.permanent_state { - for scope in permanent_state.scope.iter().rev() { - if let Some(decl_id) = scope.decls.get(name) { - return Some(*decl_id); - } + for scope in self.permanent_state.scope.iter().rev() { + if let Some(decl_id) = scope.decls.get(name) { + return Some(*decl_id); } } @@ -257,7 +254,7 @@ impl ParserWorkingSet { } pub fn contains_decl_partial_match(&self, name: &[u8]) -> bool { - for scope in self.scope.iter().rev() { + for scope in self.delta.scope.iter().rev() { for decl in &scope.decls { if decl.0.starts_with(name) { return true; @@ -265,12 +262,10 @@ impl ParserWorkingSet { } } - if let Some(permanent_state) = &self.permanent_state { - for scope in permanent_state.scope.iter().rev() { - for decl in &scope.decls { - if decl.0.starts_with(name) { - return true; - } + for scope in self.permanent_state.scope.iter().rev() { + for decl in &scope.decls { + if decl.0.starts_with(name) { + return true; } } } @@ -279,26 +274,20 @@ impl ParserWorkingSet { } pub fn next_var_id(&self) -> VarId { - if let Some(permanent_state) = &self.permanent_state { - let num_permanent_vars = permanent_state.num_vars(); - num_permanent_vars + self.vars.len() - } else { - self.vars.len() - } + let num_permanent_vars = self.permanent_state.num_vars(); + num_permanent_vars + self.delta.vars.len() } pub fn find_variable(&self, name: &[u8]) -> Option { - for scope in self.scope.iter().rev() { + for scope in self.delta.scope.iter().rev() { if let Some(var_id) = scope.vars.get(name) { return Some(*var_id); } } - if let Some(permanent_state) = &self.permanent_state { - for scope in permanent_state.scope.iter().rev() { - if let Some(var_id) = scope.vars.get(name) { - return Some(*var_id); - } + for scope in self.permanent_state.scope.iter().rev() { + if let Some(var_id) = scope.vars.get(name) { + return Some(*var_id); } } @@ -309,40 +298,33 @@ impl ParserWorkingSet { let next_id = self.next_var_id(); let last = self + .delta .scope .last_mut() .expect("internal error: missing stack frame"); last.vars.insert(name, next_id); - self.vars.insert(next_id, ty); + self.delta.vars.insert(next_id, ty); next_id } - pub fn get_variable(&self, var_id: VarId) -> Option<&Type> { - if let Some(permanent_state) = &self.permanent_state { - let num_permanent_vars = permanent_state.num_vars(); - if var_id < num_permanent_vars { - permanent_state.get_var(var_id) - } else { - self.vars.get(var_id - num_permanent_vars) - } + pub fn get_variable(&self, var_id: VarId) -> Option { + let num_permanent_vars = self.permanent_state.num_vars(); + if var_id < num_permanent_vars { + self.permanent_state.get_var(var_id).cloned() } else { - self.vars.get(var_id) + self.delta.vars.get(var_id - num_permanent_vars).cloned() } } - pub fn get_decl(&self, decl_id: DeclId) -> Option<&Declaration> { - if let Some(permanent_state) = &self.permanent_state { - let num_permanent_decls = permanent_state.num_decls(); - if decl_id < num_permanent_decls { - permanent_state.get_decl(decl_id) - } else { - self.decls.get(decl_id - num_permanent_decls) - } + pub fn get_decl(&self, decl_id: DeclId) -> Option { + let num_permanent_decls = self.permanent_state.num_decls(); + if decl_id < num_permanent_decls { + self.permanent_state.get_decl(decl_id).cloned() } else { - self.decls.get(decl_id) + self.delta.decls.get(decl_id - num_permanent_decls).cloned() } } } @@ -353,7 +335,8 @@ mod parser_state_tests { #[test] fn add_file_gives_id() { - let mut parser_state = ParserWorkingSet::new(Some(Arc::new(ParserState::new()))); + let parser_state = ParserState::new(); + let mut parser_state = ParserWorkingSet::new(&parser_state); let id = parser_state.add_file("test.nu".into(), &[]); assert_eq!(id, 0); @@ -364,7 +347,7 @@ mod parser_state_tests { let mut parser_state = ParserState::new(); let parent_id = parser_state.add_file("test.nu".into(), vec![]); - let mut working_set = ParserWorkingSet::new(Some(Arc::new(parser_state))); + let mut working_set = ParserWorkingSet::new(&parser_state); let working_set_id = working_set.add_file("child.nu".into(), &[]); assert_eq!(parent_id, 0); @@ -375,12 +358,14 @@ mod parser_state_tests { fn merge_states() { let mut parser_state = ParserState::new(); parser_state.add_file("test.nu".into(), vec![]); - let mut parser_state = Arc::new(parser_state); - let mut working_set = ParserWorkingSet::new(Some(parser_state.clone())); - working_set.add_file("child.nu".into(), &[]); + let delta = { + let mut working_set = ParserWorkingSet::new(&parser_state); + working_set.add_file("child.nu".into(), &[]); + working_set.delta + }; - ParserState::merge_working_set(&mut parser_state, working_set); + ParserState::merge_delta(&mut parser_state, delta); assert_eq!(parser_state.num_files(), 2); assert_eq!(&parser_state.files[0].0, "test.nu"); diff --git a/src/syntax_highlight.rs b/src/syntax_highlight.rs index a8a68b821e..22f31f63a0 100644 --- a/src/syntax_highlight.rs +++ b/src/syntax_highlight.rs @@ -2,10 +2,10 @@ use std::sync::Arc; use crate::{Block, Expr, Expression, ParserState, ParserWorkingSet, Statement}; -fn syntax_highlight(parser_state: Arc, input: &[u8]) { - let mut working_set = ParserWorkingSet::new(Some(parser_state)); +fn syntax_highlight<'a, 'b>(parser_state: &'a ParserState, input: &'b [u8]) { + // let mut working_set = ParserWorkingSet::new(parser_state); - let (block, _) = working_set.parse_source(input, false); + // let (block, _) = working_set.parse_source(input, false); // for stmt in &block.stmts { // match stmt {