1use regex::Regex;
11use std::collections::HashMap;
12use std::collections::HashSet;
13use std::fmt;
14use tree_sitter::CaptureQuantifier;
15use tree_sitter::Language;
16use tree_sitter::Query;
17
18use crate::parser::Range;
19use crate::Identifier;
20use crate::Location;
21
22#[derive(Debug)]
24pub struct File {
25 pub language: Language,
26 pub globals: Vec<Global>,
28 pub inherited_variables: HashSet<Identifier>,
30 pub query: Option<Query>,
32 pub stanzas: Vec<Stanza>,
34 pub shorthands: AttributeShorthands,
36}
37
38impl File {
39 pub fn new(language: Language) -> File {
40 File {
41 language,
42 globals: Vec::new(),
43 inherited_variables: HashSet::new(),
44 query: None,
45 stanzas: Vec::new(),
46 shorthands: AttributeShorthands::new(),
47 }
48 }
49}
50
51#[derive(Debug, Eq, PartialEq)]
53pub struct Global {
54 pub name: Identifier,
56 pub quantifier: CaptureQuantifier,
58 pub default: Option<String>,
60 pub location: Location,
61}
62
63#[derive(Debug)]
65pub struct Stanza {
66 pub query: Query,
68 pub statements: Vec<Statement>,
70 pub full_match_stanza_capture_index: usize,
72 pub full_match_file_capture_index: usize,
74 pub range: Range,
75}
76
77#[derive(Debug, Eq, PartialEq)]
79pub enum Statement {
80 DeclareImmutable(DeclareImmutable),
82 DeclareMutable(DeclareMutable),
83 Assign(Assign),
84 CreateGraphNode(CreateGraphNode),
86 AddGraphNodeAttribute(AddGraphNodeAttribute),
87 CreateEdge(CreateEdge),
89 AddEdgeAttribute(AddEdgeAttribute),
90 Scan(Scan),
92 Print(Print),
94 If(If),
96 ForIn(ForIn),
98}
99
100impl std::fmt::Display for Statement {
101 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
102 match self {
103 Self::DeclareImmutable(stmt) => stmt.fmt(f),
104 Self::DeclareMutable(stmt) => stmt.fmt(f),
105 Self::Assign(stmt) => stmt.fmt(f),
106 Self::CreateGraphNode(stmt) => stmt.fmt(f),
107 Self::AddGraphNodeAttribute(stmt) => stmt.fmt(f),
108 Self::CreateEdge(stmt) => stmt.fmt(f),
109 Self::AddEdgeAttribute(stmt) => stmt.fmt(f),
110 Self::Scan(stmt) => stmt.fmt(f),
111 Self::Print(stmt) => stmt.fmt(f),
112 Self::If(stmt) => stmt.fmt(f),
113 Self::ForIn(stmt) => stmt.fmt(f),
114 }
115 }
116}
117
118#[derive(Debug, Eq, PartialEq)]
120pub struct AddEdgeAttribute {
121 pub source: Expression,
122 pub sink: Expression,
123 pub attributes: Vec<Attribute>,
124 pub location: Location,
125}
126
127impl From<AddEdgeAttribute> for Statement {
128 fn from(statement: AddEdgeAttribute) -> Statement {
129 Statement::AddEdgeAttribute(statement)
130 }
131}
132
133impl std::fmt::Display for AddEdgeAttribute {
134 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
135 write!(f, "attr ({} -> {})", self.source, self.sink)?;
136 for attr in &self.attributes {
137 write!(f, " {}", attr)?;
138 }
139 write!(f, " at {}", self.location)
140 }
141}
142
143#[derive(Debug, Eq, PartialEq)]
145pub struct AddGraphNodeAttribute {
146 pub node: Expression,
147 pub attributes: Vec<Attribute>,
148 pub location: Location,
149}
150
151impl From<AddGraphNodeAttribute> for Statement {
152 fn from(statement: AddGraphNodeAttribute) -> Statement {
153 Statement::AddGraphNodeAttribute(statement)
154 }
155}
156
157impl std::fmt::Display for AddGraphNodeAttribute {
158 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
159 write!(f, "attr ({})", self.node)?;
160 for attr in &self.attributes {
161 write!(f, " {}", attr)?;
162 }
163 write!(f, " at {}", self.location)
164 }
165}
166
167#[derive(Debug, Eq, PartialEq)]
169pub struct Assign {
170 pub variable: Variable,
171 pub value: Expression,
172 pub location: Location,
173}
174
175impl From<Assign> for Statement {
176 fn from(statement: Assign) -> Statement {
177 Statement::Assign(statement)
178 }
179}
180
181impl std::fmt::Display for Assign {
182 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
183 write!(
184 f,
185 "set {} = {} at {}",
186 self.variable, self.value, self.location,
187 )
188 }
189}
190
191#[derive(Debug, Eq, PartialEq)]
193pub struct Attribute {
194 pub name: Identifier,
195 pub value: Expression,
196}
197
198impl std::fmt::Display for Attribute {
199 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
200 write!(f, "{} = {}", self.name, self.value)
201 }
202}
203
204#[derive(Debug, Eq, PartialEq)]
206pub struct CreateEdge {
207 pub source: Expression,
208 pub sink: Expression,
209 pub location: Location,
210}
211
212impl From<CreateEdge> for Statement {
213 fn from(statement: CreateEdge) -> Statement {
214 Statement::CreateEdge(statement)
215 }
216}
217
218impl std::fmt::Display for CreateEdge {
219 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
220 write!(
221 f,
222 "edge {} -> {} at {}",
223 self.source, self.sink, self.location,
224 )
225 }
226}
227
228#[derive(Debug, Eq, PartialEq)]
230pub struct CreateGraphNode {
231 pub node: Variable,
232 pub location: Location,
233}
234
235impl From<CreateGraphNode> for Statement {
236 fn from(statement: CreateGraphNode) -> Statement {
237 Statement::CreateGraphNode(statement)
238 }
239}
240
241impl std::fmt::Display for CreateGraphNode {
242 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
243 write!(f, "node {} at {}", self.node, self.location)
244 }
245}
246
247#[derive(Debug, Eq, PartialEq)]
249pub struct DeclareImmutable {
250 pub variable: Variable,
251 pub value: Expression,
252 pub location: Location,
253}
254
255impl From<DeclareImmutable> for Statement {
256 fn from(statement: DeclareImmutable) -> Statement {
257 Statement::DeclareImmutable(statement)
258 }
259}
260
261impl std::fmt::Display for DeclareImmutable {
262 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
263 write!(
264 f,
265 "let {} = {} at {}",
266 self.variable, self.value, self.location,
267 )
268 }
269}
270
271#[derive(Debug, Eq, PartialEq)]
273pub struct DeclareMutable {
274 pub variable: Variable,
275 pub value: Expression,
276 pub location: Location,
277}
278
279impl From<DeclareMutable> for Statement {
280 fn from(statement: DeclareMutable) -> Statement {
281 Statement::DeclareMutable(statement)
282 }
283}
284
285impl std::fmt::Display for DeclareMutable {
286 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
287 write!(
288 f,
289 "var {} = {} at {}",
290 self.variable, self.value, self.location,
291 )
292 }
293}
294
295#[derive(Debug, Eq, PartialEq)]
297pub struct Print {
298 pub values: Vec<Expression>,
299 pub location: Location,
300}
301
302impl From<Print> for Statement {
303 fn from(statement: Print) -> Statement {
304 Statement::Print(statement)
305 }
306}
307
308impl std::fmt::Display for Print {
309 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
310 write!(f, "print")?;
311 for val in &self.values {
312 write!(f, " {},", val)?;
313 }
314 write!(f, " at {}", self.location)
315 }
316}
317
318#[derive(Debug, Eq, PartialEq)]
320pub struct Scan {
321 pub value: Expression,
322 pub arms: Vec<ScanArm>,
323 pub location: Location,
324}
325
326impl From<Scan> for Statement {
327 fn from(statement: Scan) -> Statement {
328 Statement::Scan(statement)
329 }
330}
331
332impl std::fmt::Display for Scan {
333 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
334 write!(f, "scan {} {{ ... }} at {}", self.value, self.location)
335 }
336}
337
338#[derive(Debug)]
340pub struct ScanArm {
341 pub regex: Regex,
342 pub statements: Vec<Statement>,
343 pub location: Location,
344}
345
346impl Eq for ScanArm {}
347
348impl PartialEq for ScanArm {
349 fn eq(&self, other: &ScanArm) -> bool {
350 self.regex.as_str() == other.regex.as_str() && self.statements == other.statements
351 }
352}
353
354impl std::fmt::Display for ScanArm {
355 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
356 write!(f, "{:?} {{ ... }}", self.regex.as_str())
357 }
358}
359
360#[derive(Debug, Eq, PartialEq)]
362pub struct If {
363 pub arms: Vec<IfArm>,
364 pub location: Location,
365}
366
367impl From<If> for Statement {
368 fn from(statement: If) -> Statement {
369 Statement::If(statement)
370 }
371}
372
373impl std::fmt::Display for If {
374 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
375 let mut first = true;
376 for arm in &self.arms {
377 if first {
378 first = false;
379 write!(f, "if {} {{ ... }}", DisplayConditions(&arm.conditions))?;
380 } else {
381 if !arm.conditions.is_empty() {
382 write!(f, " elif {} {{ ... }}", DisplayConditions(&arm.conditions))?;
383 } else {
384 write!(f, " else {{ ... }}")?;
385 }
386 }
387 }
388 write!(f, " at {}", self.location)
389 }
390}
391
392#[derive(Debug, PartialEq, Eq)]
394pub struct IfArm {
395 pub conditions: Vec<Condition>,
396 pub statements: Vec<Statement>,
397 pub location: Location,
398}
399
400struct DisplayConditions<'a>(&'a Vec<Condition>);
401
402#[derive(Debug, PartialEq, Eq)]
403pub enum Condition {
404 Some {
405 value: Expression,
406 location: Location,
407 },
408 None {
409 value: Expression,
410 location: Location,
411 },
412 Bool {
413 value: Expression,
414 location: Location,
415 },
416}
417
418impl std::fmt::Display for DisplayConditions<'_> {
419 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
420 let mut first = true;
421 for condition in self.0.iter() {
422 if first {
423 first = false;
424 write!(f, "{}", condition)?;
425 } else {
426 write!(f, ", {}", condition)?;
427 }
428 }
429 Ok(())
430 }
431}
432
433impl std::fmt::Display for Condition {
434 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
435 match self {
436 Condition::Some { value, .. } => {
437 write!(f, "some {}", value)
438 }
439 Condition::None { value, .. } => {
440 write!(f, "none {}", value)
441 }
442 Condition::Bool { value, .. } => {
443 write!(f, "{}", value)
444 }
445 }
446 }
447}
448
449#[derive(Debug, Eq, PartialEq)]
451pub struct ForIn {
452 pub variable: UnscopedVariable,
453 pub value: Expression,
454 pub statements: Vec<Statement>,
455 pub location: Location,
456}
457
458impl From<ForIn> for Statement {
459 fn from(statement: ForIn) -> Statement {
460 Statement::ForIn(statement)
461 }
462}
463
464impl std::fmt::Display for ForIn {
465 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
466 write!(
467 f,
468 "for {} in {} {{ ... }} at {}",
469 self.variable, self.value, self.location,
470 )
471 }
472}
473
474#[derive(Debug, Eq, PartialEq)]
476pub enum Variable {
477 Scoped(ScopedVariable),
478 Unscoped(UnscopedVariable),
479}
480
481impl std::fmt::Display for Variable {
482 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
483 match self {
484 Variable::Scoped(variable) => variable.fmt(f),
485 Variable::Unscoped(variable) => variable.fmt(f),
486 }
487 }
488}
489
490#[derive(Debug, Eq, PartialEq)]
492pub struct ScopedVariable {
493 pub scope: Box<Expression>,
494 pub name: Identifier,
495 pub location: Location,
496}
497
498impl From<ScopedVariable> for Variable {
499 fn from(variable: ScopedVariable) -> Variable {
500 Variable::Scoped(variable)
501 }
502}
503
504impl std::fmt::Display for ScopedVariable {
505 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
506 write!(f, "{}.{}", self.scope, self.name)
507 }
508}
509
510#[derive(Debug, Eq, PartialEq)]
512pub struct UnscopedVariable {
513 pub name: Identifier,
514 pub location: Location,
515}
516
517impl From<UnscopedVariable> for Variable {
518 fn from(variable: UnscopedVariable) -> Variable {
519 Variable::Unscoped(variable)
520 }
521}
522
523impl std::fmt::Display for UnscopedVariable {
524 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
525 write!(f, "{}", self.name)
526 }
527}
528
529#[derive(Debug, Eq, PartialEq)]
531pub enum Expression {
532 FalseLiteral,
534 NullLiteral,
535 TrueLiteral,
536 IntegerConstant(IntegerConstant),
538 StringConstant(StringConstant),
539 ListLiteral(ListLiteral),
541 SetLiteral(SetLiteral),
542 ListComprehension(ListComprehension),
544 SetComprehension(SetComprehension),
545 Capture(Capture),
547 Variable(Variable),
549 Call(Call),
551 RegexCapture(RegexCapture),
553}
554
555impl std::fmt::Display for Expression {
556 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
557 match self {
558 Expression::FalseLiteral => write!(f, "false"),
559 Expression::NullLiteral => write!(f, "#null"),
560 Expression::TrueLiteral => write!(f, "true"),
561 Expression::IntegerConstant(expr) => expr.fmt(f),
562 Expression::StringConstant(expr) => expr.fmt(f),
563 Expression::ListLiteral(expr) => expr.fmt(f),
564 Expression::SetLiteral(expr) => expr.fmt(f),
565 Expression::ListComprehension(expr) => expr.fmt(f),
566 Expression::SetComprehension(expr) => expr.fmt(f),
567 Expression::Capture(expr) => expr.fmt(f),
568 Expression::Variable(expr) => expr.fmt(f),
569 Expression::Call(expr) => expr.fmt(f),
570 Expression::RegexCapture(expr) => expr.fmt(f),
571 }
572 }
573}
574
575#[derive(Debug, Eq, PartialEq)]
577pub struct Call {
578 pub function: Identifier,
579 pub parameters: Vec<Expression>,
580}
581
582impl From<Call> for Expression {
583 fn from(expr: Call) -> Expression {
584 Expression::Call(expr)
585 }
586}
587
588impl std::fmt::Display for Call {
589 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
590 write!(f, "({}", self.function)?;
591 for arg in &self.parameters {
592 write!(f, " {}", arg)?;
593 }
594 write!(f, ")")
595 }
596}
597
598#[derive(Debug, Eq, PartialEq)]
600pub struct Capture {
601 pub name: Identifier,
603 pub quantifier: CaptureQuantifier,
605 pub file_capture_index: usize,
607 pub stanza_capture_index: usize,
609 pub location: Location,
610}
611
612impl From<Capture> for Expression {
613 fn from(expr: Capture) -> Expression {
614 Expression::Capture(expr)
615 }
616}
617
618impl std::fmt::Display for Capture {
619 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
620 write!(f, "@{}", self.name)
621 }
622}
623
624#[derive(Debug, Eq, PartialEq)]
626pub struct IntegerConstant {
627 pub value: u32,
628}
629
630impl From<IntegerConstant> for Expression {
631 fn from(expr: IntegerConstant) -> Expression {
632 Expression::IntegerConstant(expr)
633 }
634}
635
636impl std::fmt::Display for IntegerConstant {
637 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
638 write!(f, "{}", self.value)
639 }
640}
641
642#[derive(Debug, Eq, PartialEq)]
644pub struct ListLiteral {
645 pub elements: Vec<Expression>,
646}
647
648impl From<ListLiteral> for Expression {
649 fn from(expr: ListLiteral) -> Expression {
650 Expression::ListLiteral(expr)
651 }
652}
653
654impl std::fmt::Display for ListLiteral {
655 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
656 write!(f, "[")?;
657 let mut first = true;
658 for elem in &self.elements {
659 if first {
660 write!(f, "{}", elem)?;
661 first = false;
662 } else {
663 write!(f, ", {}", elem)?;
664 }
665 }
666 write!(f, "]")
667 }
668}
669
670#[derive(Debug, Eq, PartialEq)]
672pub struct ListComprehension {
673 pub element: Box<Expression>,
674 pub variable: UnscopedVariable,
675 pub value: Box<Expression>,
676 pub location: Location,
677}
678
679impl From<ListComprehension> for Expression {
680 fn from(expr: ListComprehension) -> Expression {
681 Expression::ListComprehension(expr)
682 }
683}
684
685impl std::fmt::Display for ListComprehension {
686 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
687 write!(
688 f,
689 "[ {} for {} in {} ]",
690 self.element, self.variable, self.value
691 )
692 }
693}
694
695#[derive(Debug, Eq, PartialEq)]
697pub struct RegexCapture {
698 pub match_index: usize,
699}
700
701impl From<RegexCapture> for Expression {
702 fn from(expr: RegexCapture) -> Expression {
703 Expression::RegexCapture(expr)
704 }
705}
706
707impl std::fmt::Display for RegexCapture {
708 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
709 write!(f, "${}", self.match_index)
710 }
711}
712
713#[derive(Debug, Eq, PartialEq)]
715pub struct SetLiteral {
716 pub elements: Vec<Expression>,
717}
718
719impl From<SetLiteral> for Expression {
720 fn from(expr: SetLiteral) -> Expression {
721 Expression::SetLiteral(expr)
722 }
723}
724
725impl std::fmt::Display for SetLiteral {
726 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
727 write!(f, "{{")?;
728 let mut first = true;
729 for elem in &self.elements {
730 if first {
731 write!(f, "{}", elem)?;
732 first = false;
733 } else {
734 write!(f, ", {}", elem)?;
735 }
736 }
737 write!(f, "}}")
738 }
739}
740
741#[derive(Debug, Eq, PartialEq)]
743pub struct SetComprehension {
744 pub element: Box<Expression>,
745 pub variable: UnscopedVariable,
746 pub value: Box<Expression>,
747 pub location: Location,
748}
749
750impl From<SetComprehension> for Expression {
751 fn from(expr: SetComprehension) -> Expression {
752 Expression::SetComprehension(expr)
753 }
754}
755
756impl std::fmt::Display for SetComprehension {
757 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
758 write!(
759 f,
760 "{{ {} for {} in {} }}",
761 self.element, self.variable, self.value
762 )
763 }
764}
765
766#[derive(Debug, Eq, PartialEq)]
768pub struct StringConstant {
769 pub value: String,
770}
771
772impl From<StringConstant> for Expression {
773 fn from(expr: StringConstant) -> Expression {
774 Expression::StringConstant(expr)
775 }
776}
777
778impl std::fmt::Display for StringConstant {
779 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
780 write!(f, "{:?}", self.value)
781 }
782}
783
784impl From<String> for Expression {
785 fn from(value: String) -> Expression {
786 Expression::StringConstant(StringConstant { value }.into())
787 }
788}
789
790impl From<UnscopedVariable> for Expression {
791 fn from(variable: UnscopedVariable) -> Expression {
792 Expression::Variable(variable.into())
793 }
794}
795
796impl From<ScopedVariable> for Expression {
797 fn from(variable: ScopedVariable) -> Expression {
798 Expression::Variable(variable.into())
799 }
800}
801
802#[derive(Debug, Eq, PartialEq)]
804pub struct AttributeShorthands(HashMap<Identifier, AttributeShorthand>);
805
806impl AttributeShorthands {
807 pub fn new() -> Self {
808 Self(HashMap::new())
809 }
810
811 pub fn get(&self, name: &Identifier) -> Option<&AttributeShorthand> {
812 self.0.get(name)
813 }
814
815 pub fn add(&mut self, shorthand: AttributeShorthand) {
816 self.0.insert(shorthand.name.clone(), shorthand);
817 }
818
819 pub fn iter(&self) -> impl Iterator<Item = &AttributeShorthand> {
820 self.0.values()
821 }
822
823 pub fn into_iter(self) -> impl Iterator<Item = AttributeShorthand> {
824 self.0.into_values()
825 }
826}
827
828#[derive(Debug, Eq, PartialEq)]
830pub struct AttributeShorthand {
831 pub name: Identifier,
832 pub variable: UnscopedVariable,
833 pub attributes: Vec<Attribute>,
834 pub location: Location,
835}
836
837impl std::fmt::Display for AttributeShorthand {
838 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
839 write!(f, "attribute {} = {} =>", self.name, self.variable,)?;
840 for attr in &self.attributes {
841 write!(f, " {}", attr)?;
842 }
843 write!(f, " at {}", self.location)
844 }
845}