@@ -26,8 +26,8 @@ impl Extractor {
2626 . expect ( "Failed to parse file" ) ;
2727 let mut visitor = Visitor {
2828 source : & source,
29- program : vec ! [ Fact :: Comment ( format!(
30- "Auto-generated FACT file for {}, generated by the cool kids " ,
29+ trap_output : vec ! [ TrapEntry :: Comment ( format!(
30+ "Auto-generated TRAP file for {}" ,
3131 path. display( )
3232 ) ) ] ,
3333 counter : -1 ,
@@ -40,7 +40,7 @@ impl Extractor {
4040 traverse ( & tree, & mut visitor) ;
4141
4242 & self . parser . reset ( ) ;
43- Ok ( Program ( visitor. program ) )
43+ Ok ( Program ( visitor. trap_output ) )
4444 }
4545}
4646
@@ -65,13 +65,24 @@ fn build_union_type_lookup<'a>(schema: &'a Vec<Entry>) -> Map<&'a TypeName, &'a
6565}
6666
6767struct Visitor < ' a > {
68+ /// The file path of the source code (as string)
69+ path : String ,
70+ /// The source code as a UTF-8 byte array
6871 source : & ' a Vec < u8 > ,
69- program : Vec < Fact > ,
72+ /// The accumulated trap entries
73+ trap_output : Vec < TrapEntry > ,
74+ /// A counter for generating fresh labels
7075 counter : i32 ,
71- path : String ,
72- stack : Vec < Vec < ( Option < & ' static str > , Id , TypeName ) > > ,
76+ /// A lookup table from type name to dbscheme table entries
7377 tables : Map < & ' a TypeName , & ' a Entry > ,
78+ /// A lookup table for union types mapping a type name to its direct members
7479 union_types : Map < & ' a TypeName , & ' a Set < TypeName > > ,
80+ /// A stack for gathering information from hild nodes. Whenever a node is entered
81+ /// an empty list is pushed. All children append their data (field name, label, type) to
82+ /// the the list. When the visitor leaves a node the list containing the child data is popped
83+ /// from the stack and matched against the dbscheme for the node. If the expectations are met
84+ /// the corresponding row definitions are added to the trap_output.
85+ stack : Vec < Vec < ( Option < & ' static str > , Label , TypeName ) > > ,
7586}
7687
7788impl Visitor < ' _ > {
@@ -113,11 +124,11 @@ impl Visitor<'_> {
113124 } ) ;
114125 if let Some ( Entry :: Table { fields, .. } ) = table {
115126 self . counter += 1 ;
116- let id = Id ( self . counter ) ;
117- let loc = Loc ( self . counter ) ;
118- self . program . push ( Fact :: New ( Arg :: IdArg ( id ) ) ) ;
119- self . program . push ( Fact :: New ( Arg :: LocArg ( loc) ) ) ;
120- self . program . push ( location_for ( & self . path , loc, node) ) ;
127+ let id = Label :: Normal ( self . counter ) ;
128+ let loc = Label :: Location ( self . counter ) ;
129+ self . trap_output . push ( TrapEntry :: New ( id ) ) ;
130+ self . trap_output . push ( TrapEntry :: New ( loc) ) ;
131+ self . trap_output . push ( location_for ( & self . path , loc, node) ) ;
121132 let table_name = node_type_name ( node. kind ( ) , node. is_named ( ) ) ;
122133 let args: Option < Vec < Arg > > ;
123134 if fields. is_empty ( ) {
@@ -126,8 +137,8 @@ impl Visitor<'_> {
126137 args = self . complex_node ( & node, fields, child_nodes, id) ;
127138 }
128139 if let Some ( args) = args {
129- self . program
130- . push ( Fact :: Definition ( table_name, id, args, loc) ) ;
140+ self . trap_output
141+ . push ( TrapEntry :: Definition ( table_name, id, args, loc) ) ;
131142 }
132143 if let Some ( parent) = self . stack . last_mut ( ) {
133144 parent. push ( (
@@ -152,10 +163,10 @@ impl Visitor<'_> {
152163 & mut self ,
153164 node : & Node ,
154165 fields : & Vec < Field > ,
155- child_nodes : Vec < ( Option < & str > , Id , TypeName ) > ,
156- parent_id : Id ,
166+ child_nodes : Vec < ( Option < & str > , Label , TypeName ) > ,
167+ parent_id : Label ,
157168 ) -> Option < Vec < Arg > > {
158- let mut map: Map < & Option < String > , ( & Field , Vec < Id > ) > = std:: collections:: BTreeMap :: new ( ) ;
169+ let mut map: Map < & Option < String > , ( & Field , Vec < Label > ) > = std:: collections:: BTreeMap :: new ( ) ;
159170 for field in fields {
160171 map. insert ( & field. name , ( field, Vec :: new ( ) ) ) ;
161172 }
@@ -195,7 +206,7 @@ impl Visitor<'_> {
195206 match & field. storage {
196207 Storage :: Column => {
197208 if child_ids. len ( ) == 1 {
198- args. push ( Arg :: IdArg ( * child_ids. first ( ) . unwrap ( ) ) ) ;
209+ args. push ( Arg :: Label ( * child_ids. first ( ) . unwrap ( ) ) ) ;
199210 } else {
200211 is_valid = false ;
201212 println ! (
@@ -217,7 +228,7 @@ impl Visitor<'_> {
217228 }
218229 Storage :: Table { parent, index } => {
219230 for child_id in child_ids {
220- self . program . push ( Fact :: ChildOf (
231+ self . trap_output . push ( TrapEntry :: ChildOf (
221232 node_type_name ( & parent. kind , parent. named ) ,
222233 parent_id,
223234 match & field. name {
@@ -255,24 +266,24 @@ impl Visitor<'_> {
255266// Emit a slice of a source file as an Arg.
256267fn sliced_source_arg ( source : & Vec < u8 > , n : Node ) -> Arg {
257268 let range = n. byte_range ( ) ;
258- Arg :: StringArg ( String :: from (
269+ Arg :: String ( String :: from (
259270 std:: str:: from_utf8 ( & source[ range. start ..range. end ] ) . expect ( "Failed to decode string" ) ,
260271 ) )
261272}
262273
263- // Emit a 'Located' fact for the provided node, appropriately calibrated.
264- fn location_for < ' a > ( fp : & String , ident : Loc , n : Node ) -> Fact {
274+ // Emit a 'Located' TrapEntry for the provided node, appropriately calibrated.
275+ fn location_for < ' a > ( fp : & String , label : Label , n : Node ) -> TrapEntry {
265276 let start_line = n. start_position ( ) . row ;
266277 let start_col = n. start_position ( ) . column ;
267278 let end_line = n. end_position ( ) . row ;
268279 let end_col = n. end_position ( ) . column ;
269- Fact :: Located ( vec ! [
270- Arg :: LocArg ( ident ) ,
271- Arg :: StringArg ( fp. to_owned( ) ) ,
272- Arg :: IntArg ( start_line) ,
273- Arg :: IntArg ( start_col) ,
274- Arg :: IntArg ( end_line) ,
275- Arg :: IntArg ( end_col) ,
280+ TrapEntry :: Located ( vec ! [
281+ Arg :: Label ( label ) ,
282+ Arg :: String ( fp. to_owned( ) ) ,
283+ Arg :: Int ( start_line) ,
284+ Arg :: Int ( start_col) ,
285+ Arg :: Int ( end_line) ,
286+ Arg :: Int ( end_col) ,
276287 ] )
277288}
278289
@@ -296,34 +307,35 @@ fn traverse(tree: &Tree, visitor: &mut Visitor) {
296307 }
297308 }
298309}
299- pub struct Program ( Vec < Fact > ) ;
310+
311+ pub struct Program ( Vec < TrapEntry > ) ;
300312
301313impl fmt:: Display for Program {
302314 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
303315 let mut text = String :: new ( ) ;
304- for fact in & self . 0 {
305- text. push_str ( & format ! ( "{}\n " , fact ) ) ;
316+ for trap_entry in & self . 0 {
317+ text. push_str ( & format ! ( "{}\n " , trap_entry ) ) ;
306318 }
307319 write ! ( f, "{}" , text)
308320 }
309321}
310- # [ derive ( Debug ) ]
311- enum Fact {
322+
323+ enum TrapEntry {
312324 // @id = *@
313- New ( Arg ) ,
325+ New ( Label ) ,
314326 // @node_def(self, arg?, location)@
315- Definition ( String , Id , Vec < Arg > , Loc ) ,
327+ Definition ( String , Label , Vec < Arg > , Label ) ,
316328 // @node_child(self, index, parent)@
317- ChildOf ( String , Id , String , Index , Id ) ,
329+ ChildOf ( String , Label , String , Index , Label ) ,
318330 // @location(loc, path, r1, c1, r2, c2)
319331 Located ( Vec < Arg > ) ,
320332 Comment ( String ) ,
321333}
322- impl fmt:: Display for Fact {
334+ impl fmt:: Display for TrapEntry {
323335 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
324336 match self {
325- Fact :: New ( id) => write ! ( f, "{} = *" , id) ,
326- Fact :: Definition ( n, id, args, loc) => {
337+ TrapEntry :: New ( id) => write ! ( f, "{} = *" , id) ,
338+ TrapEntry :: Definition ( n, id, args, loc) => {
327339 let mut args_str = String :: new ( ) ;
328340 for arg in args {
329341 args_str. push_str ( & format ! ( "{}, " , arg) ) ;
@@ -337,15 +349,15 @@ impl fmt::Display for Fact {
337349 loc
338350 )
339351 }
340- Fact :: ChildOf ( pname, id, fname, idx, p) => write ! (
352+ TrapEntry :: ChildOf ( pname, id, fname, idx, p) => write ! (
341353 f,
342354 "{}({}, {}, {})" ,
343355 escape_name( & format!( "{}_{}" , & pname, & fname) ) ,
344356 id,
345357 idx,
346358 p
347359 ) ,
348- Fact :: Located ( args) => write ! (
360+ TrapEntry :: Located ( args) => write ! (
349361 f,
350362 "location({}, {}, {}, {}, {}, {})" ,
351363 args. get( 0 ) . unwrap( ) ,
@@ -355,28 +367,28 @@ impl fmt::Display for Fact {
355367 args. get( 4 ) . unwrap( ) ,
356368 args. get( 5 ) . unwrap( ) ,
357369 ) ,
358- Fact :: Comment ( line) => write ! ( f, "// {}" , line) ,
370+ TrapEntry :: Comment ( line) => write ! ( f, "// {}" , line) ,
359371 }
360372 }
361373}
362- // Identifiers of the form #0, #1...
363- #[ derive( Debug , Copy , Clone ) ]
364- struct Id ( i32 ) ;
365374
366- impl fmt:: Display for Id {
367- fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
368- write ! ( f, "#{}" , self . 0 )
369- }
370- }
371- // Locative identifiers of the form #0_loc, #1_loc...
372375#[ derive( Debug , Copy , Clone ) ]
373- struct Loc ( i32 ) ;
376+ enum Label {
377+ // Identifiers of the form #0, #1...
378+ Normal ( i32 ) , // #0, #1, etc.
379+ // Location identifiers of the form #0_loc, #1_loc...
380+ Location ( i32 ) , // #0_loc, #1_loc, etc.
381+ }
374382
375- impl fmt:: Display for Loc {
383+ impl fmt:: Display for Label {
376384 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
377- write ! ( f, "#{}_loc" , self . 0 )
385+ match self {
386+ Label :: Normal ( x) => write ! ( f, "#{}" , x) ,
387+ Label :: Location ( x) => write ! ( f, "#{}_loc" , x) ,
388+ }
378389 }
379390}
391+
380392// Numeric indices.
381393#[ derive( Debug , Copy , Clone ) ]
382394struct Index ( usize ) ;
@@ -387,22 +399,20 @@ impl fmt::Display for Index {
387399 }
388400}
389401
390- // Some untyped argument to a fact .
402+ // Some untyped argument to a TrapEntry .
391403#[ derive( Debug ) ]
392404enum Arg {
393- IntArg ( usize ) ,
394- StringArg ( String ) ,
395- IdArg ( Id ) ,
396- LocArg ( Loc ) ,
405+ Label ( Label ) ,
406+ Int ( usize ) ,
407+ String ( String ) ,
397408}
398409
399410impl fmt:: Display for Arg {
400411 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
401412 match self {
402- Arg :: IntArg ( x) => write ! ( f, "{}" , x) ,
403- Arg :: StringArg ( x) => write ! ( f, "\" {}\" " , x. replace( "\" " , "\" \" " ) ) ,
404- Arg :: IdArg ( x) => write ! ( f, "{}" , x) ,
405- Arg :: LocArg ( x) => write ! ( f, "{}" , x) ,
413+ Arg :: Label ( x) => write ! ( f, "{}" , x) ,
414+ Arg :: Int ( x) => write ! ( f, "{}" , x) ,
415+ Arg :: String ( x) => write ! ( f, "\" {}\" " , x. replace( "\" " , "\" \" " ) ) ,
406416 }
407417 }
408418}
0 commit comments