diff --git a/src/parser.rs b/src/parser.rs index d1c4115af2..5f9ba3810d 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,3 +1,5 @@ +use std::ops::{Index, IndexMut}; + use crate::{ lex, lite_parse, parser_state::{Type, VarId}, @@ -97,7 +99,31 @@ pub enum Import {} #[derive(Debug)] pub struct Block { - stmts: Vec, + pub stmts: Vec, +} + +impl Block { + pub fn len(&self) -> usize { + self.stmts.len() + } + + pub fn is_empty(&self) -> bool { + self.stmts.is_empty() + } +} + +impl Index for Block { + type Output = Statement; + + fn index(&self, index: usize) -> &Self::Output { + &self.stmts[index] + } +} + +impl IndexMut for Block { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.stmts[index] + } } impl Default for Block { @@ -583,3 +609,47 @@ impl ParserWorkingSet { (output, error) } } + +#[cfg(test)] +mod tests { + use crate::Signature; + + use super::*; + + #[test] + pub fn parse_int() { + let mut working_set = ParserWorkingSet::new(None); + + let (block, err) = working_set.parse_source(b"3"); + + assert!(err.is_none()); + assert!(block.len() == 1); + assert!(matches!( + block[0], + Statement::Expression(Expression { + expr: Expr::Int(3), + .. + }) + )); + } + + #[test] + pub fn parse_call() { + let mut working_set = ParserWorkingSet::new(None); + + let sig = Signature::build("foo").named("--jazz", SyntaxShape::Int, "jazz!!", Some('j')); + working_set.add_decl((b"foo").to_vec(), sig); + + let (block, err) = working_set.parse_source(b"foo"); + + assert!(err.is_none()); + assert!(block.len() == 1); + assert!(matches!( + block[0], + Statement::Expression(Expression { + expr: Expr::Call(Call { decl_id: 0, .. }), + .. + }) + )); + } +} diff --git a/src/parser_state.rs b/src/parser_state.rs index 63a51d19e2..39648c067f 100644 --- a/src/parser_state.rs +++ b/src/parser_state.rs @@ -53,6 +53,10 @@ impl ParserState { // 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.decls.extend(working_set.decls); + this.vars.extend(working_set.vars); + + //FIXME: add scope frame merging } else { panic!("Internal error: merging working set should always succeed"); }