Skip to content

Commit 0f576fe

Browse files
committed
Address review comments
1 parent 1d36b50 commit 0f576fe

File tree

1 file changed

+73
-63
lines changed

1 file changed

+73
-63
lines changed

extractor/src/extractor.rs

Lines changed: 73 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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

6767
struct 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

7788
impl 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.
256267
fn 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

301313
impl 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)]
382394
struct 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)]
392404
enum Arg {
393-
IntArg(usize),
394-
StringArg(String),
395-
IdArg(Id),
396-
LocArg(Loc),
405+
Label(Label),
406+
Int(usize),
407+
String(String),
397408
}
398409

399410
impl 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

Comments
 (0)