diff --git a/parser/src/list_parser.rs b/parser/src/list_parser.rs index 4996069..f8da430 100644 --- a/parser/src/list_parser.rs +++ b/parser/src/list_parser.rs @@ -9,13 +9,13 @@ use sym_parser::SymParser; #[derive(Debug)] pub struct ListParser { - list: Obj + list: Option } impl ListParser { pub fn new() -> ListParser { ListParser { - list: Obj::Null + list: None } } } @@ -25,12 +25,12 @@ impl NodeParser for ListParser { match lex.token() { Token::LeftParen => { match self.list { - Obj::Null => { + None => { // Create our empty pair and proceed parsing this list. - self.list = Obj::new(Pair::empty()); + self.list = Some(Pair::empty()); NodeParseResult::Continue }, - Obj::Ptr(_) => { + Some(_) => { // This is an embedded list. Create a new parser for it. let parser = ListParser::new(); NodeParseResult::Push { next: Box::new(parser) } @@ -42,7 +42,17 @@ impl NodeParser for ListParser { NodeParseResult::Push { next: Box::new(parser) } }, Token::RightParen => { - NodeParseResult::Complete { obj: self.list.take() } + match self.list { + None => { + let msg = format!("Found right paren without matching left paren"); + NodeParseResult::error(msg) + }, + Some(_) => { + let taken = self.list.take().unwrap(); + // TODO: If the cdr is Null, fill it in with an empty pair. + NodeParseResult::Complete { obj: Obj::new(taken) } + } + } } } } @@ -51,4 +61,22 @@ impl NodeParser for ListParser { let msg = format!("Unmatched paren, found EOF"); NodeParseResult::error(msg) } + + fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult { + if let Some(ref mut list) = self.list { + match list.car { + Obj::Null => { + list.car = obj; + }, + Obj::Ptr(_) => { + let pair = Pair::with_car(obj); + list.cdr = Obj::new(pair); + } + } + NodeParseResult::Continue + } else { + let msg = format!("what happened here???"); + NodeParseResult::error(msg) + } + } } diff --git a/parser/src/node_parser.rs b/parser/src/node_parser.rs index fede135..ac9fa98 100644 --- a/parser/src/node_parser.rs +++ b/parser/src/node_parser.rs @@ -10,11 +10,9 @@ use sibiltypes::Obj; pub enum NodeParseResult { /// Continue parsing with this NodeParser. The passed in Lex was consumed. Continue, - /// This NodeParser has completed its work and has produced the given Object - /// as a result. + /// This NodeParser has completed its work and has produced the given Object as a result. Complete { obj: Obj }, - /// Push a new NodeParser onto the parsing stack and let that parser proceed - /// with the current Lex. + /// Push a new NodeParser onto the parsing stack and let that parser proceed with the current Lex. Push { next: Box }, /// There was an error parsing with the current Lex. Error { msg: String }, @@ -26,13 +24,16 @@ impl NodeParseResult { } } -/// A `NodeParser` is responsible for parsing one particular thing in the Scheme -/// parse tree. Roughly, there should be one `XParser` for each variant of the -/// `sibiltypes::Object` enum. As the top-level `Parser` object progresses -/// through the stream of tokens, new NodeParsers are created to handle the -/// nodes it encounters. +/// A `NodeParser` is responsible for parsing one particular thing in the Scheme parse tree. +/// Roughly, there should be one NodeParser for each type of object in `sibiltypes`. As the +/// top-level `Parser` object progresses through the stream of tokens, new NodeParsers are created +/// to handle the nodes it encounters. pub trait NodeParser: Debug { + /// Called on a NodeParser when a Lex is encountered in the input. fn parse(&mut self, lex: &Lex) -> NodeParseResult; /// Called on a NodeParser when None is encountered in the input. fn none(&mut self) -> NodeParseResult; + /// Called on a NodeParser when a NodeParser created by this one returns an object via + /// `NodeParseResult::Complete`. + fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult; } diff --git a/parser/src/program_parser.rs b/parser/src/program_parser.rs index 665ae4f..d8ce16e 100644 --- a/parser/src/program_parser.rs +++ b/parser/src/program_parser.rs @@ -40,5 +40,9 @@ impl NodeParser for ProgramParser { fn none(&mut self) -> NodeParseResult { NodeParseResult::Complete { obj: Obj::Null } } + + fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult { + NodeParseResult::Complete { obj: obj } + } } diff --git a/parser/src/sym_parser.rs b/parser/src/sym_parser.rs index 7933884..cb51116 100644 --- a/parser/src/sym_parser.rs +++ b/parser/src/sym_parser.rs @@ -29,4 +29,9 @@ impl NodeParser for SymParser { let msg = format!("Expected symbol, found EOF"); NodeParseResult::error(msg) } + + fn subparser_completed(&mut self, obj: Obj) -> NodeParseResult { + let msg = format!("Unexpected parser result: {}", obj); + NodeParseResult::error(msg) + } }