diff --git a/extractor/src/extractor.rs b/extractor/src/extractor.rs index db328b631d0..b724ce384a2 100644 --- a/extractor/src/extractor.rs +++ b/extractor/src/extractor.rs @@ -26,8 +26,8 @@ impl Extractor { .expect("Failed to parse file"); let mut visitor = Visitor { source: &source, - program: vec![Fact::Comment(format!( - "Auto-generated FACT file for {}, generated by the cool kids", + trap_output: vec![TrapEntry::Comment(format!( + "Auto-generated TRAP file for {}", path.display() ))], counter: -1, @@ -40,7 +40,7 @@ impl Extractor { traverse(&tree, &mut visitor); &self.parser.reset(); - Ok(Program(visitor.program)) + Ok(Program(visitor.trap_output)) } } @@ -65,13 +65,24 @@ fn build_union_type_lookup<'a>(schema: &'a Vec) -> Map<&'a TypeName, &'a } struct Visitor<'a> { - source: &'a Vec, - program: Vec, - counter: i32, + /// The file path of the source code (as string) path: String, - stack: Vec, Id, TypeName)>>, + /// The source code as a UTF-8 byte array + source: &'a Vec, + /// The accumulated trap entries + trap_output: Vec, + /// A counter for generating fresh labels + counter: i32, + /// A lookup table from type name to dbscheme table entries tables: Map<&'a TypeName, &'a Entry>, + /// A lookup table for union types mapping a type name to its direct members union_types: Map<&'a TypeName, &'a Set>, + /// A stack for gathering information from hild nodes. Whenever a node is entered + /// an empty list is pushed. All children append their data (field name, label, type) to + /// the the list. When the visitor leaves a node the list containing the child data is popped + /// from the stack and matched against the dbscheme for the node. If the expectations are met + /// the corresponding row definitions are added to the trap_output. + stack: Vec, Label, TypeName)>>, } impl Visitor<'_> { @@ -113,11 +124,11 @@ impl Visitor<'_> { }); if let Some(Entry::Table { fields, .. }) = table { self.counter += 1; - let id = Id(self.counter); - let loc = Loc(self.counter); - self.program.push(Fact::New(Arg::IdArg(id))); - self.program.push(Fact::New(Arg::LocArg(loc))); - self.program.push(location_for(&self.path, loc, node)); + let id = Label::Normal(self.counter); + let loc = Label::Location(self.counter); + self.trap_output.push(TrapEntry::New(id)); + self.trap_output.push(TrapEntry::New(loc)); + self.trap_output.push(location_for(&self.path, loc, node)); let table_name = node_type_name(node.kind(), node.is_named()); let args: Option>; if fields.is_empty() { @@ -126,8 +137,8 @@ impl Visitor<'_> { args = self.complex_node(&node, fields, child_nodes, id); } if let Some(args) = args { - self.program - .push(Fact::Definition(table_name, id, args, loc)); + self.trap_output + .push(TrapEntry::Definition(table_name, id, args, loc)); } if let Some(parent) = self.stack.last_mut() { parent.push(( @@ -152,10 +163,10 @@ impl Visitor<'_> { &mut self, node: &Node, fields: &Vec, - child_nodes: Vec<(Option<&str>, Id, TypeName)>, - parent_id: Id, + child_nodes: Vec<(Option<&str>, Label, TypeName)>, + parent_id: Label, ) -> Option> { - let mut map: Map<&Option, (&Field, Vec)> = std::collections::BTreeMap::new(); + let mut map: Map<&Option, (&Field, Vec