1use crate::reference::Val;
2use std::collections::BTreeMap;
3
4pub mod operators;
5
6pub struct Ast {
7 pub expr: IdedExpr,
8}
9
10#[derive(Clone, Debug, Default, PartialEq)]
11pub enum Expr {
12 #[default]
13 Unspecified,
15
16 Call(CallExpr),
18
19 Comprehension(ComprehensionExpr),
21
22 Ident(String),
24
25 List(ListExpr),
27
28 Literal(Val),
30
31 Map(MapExpr),
33
34 Select(SelectExpr),
36
37 Struct(StructExpr),
39}
40
41#[derive(Clone, Debug, PartialEq)]
42pub enum EntryExpr {
43 StructField(StructFieldExpr),
44 MapEntry(MapEntryExpr),
45}
46
47#[derive(Clone, Debug, Default, PartialEq)]
48pub struct IdedExpr {
49 pub id: u64,
50 pub expr: Expr,
51}
52
53#[derive(Clone, Debug, PartialEq)]
54pub struct IdedEntryExpr {
55 pub id: u64,
56 pub expr: EntryExpr,
57}
58
59#[derive(Clone, Debug, Default, PartialEq)]
60pub struct CallExpr {
61 pub func_name: String,
62 pub target: Option<Box<IdedExpr>>,
63 pub args: Vec<IdedExpr>,
64}
65
66#[derive(Clone, Debug, Default, PartialEq)]
67pub struct SelectExpr {
68 pub operand: Box<IdedExpr>,
69 pub field: String,
70 pub test: bool,
71}
72
73#[derive(Clone, Debug, Default, PartialEq)]
74pub struct StructExpr {
75 pub type_name: String,
76 pub entries: Vec<IdedEntryExpr>,
77}
78
79#[derive(Clone, Debug, Default, PartialEq)]
80pub struct MapExpr {
81 pub entries: Vec<IdedEntryExpr>,
82}
83
84#[derive(Clone, Debug, Default, PartialEq)]
85pub struct ListExpr {
86 pub elements: Vec<IdedExpr>,
87}
88
89#[derive(Clone, Debug, Default, PartialEq)]
90pub struct StructFieldExpr {
91 pub field: String,
92 pub value: IdedExpr,
93 pub optional: bool,
94}
95
96#[derive(Clone, Debug, Default, PartialEq)]
97pub struct MapEntryExpr {
98 pub key: IdedExpr,
99 pub value: IdedExpr,
100 pub optional: bool,
101}
102
103#[derive(Clone, Debug, Default, PartialEq)]
104pub struct ComprehensionExpr {
105 pub iter_range: Box<IdedExpr>,
106 pub iter_var: String,
107 pub iter_var2: Option<String>,
108 pub accu_var: String,
109 pub accu_init: Box<IdedExpr>,
110 pub loop_cond: Box<IdedExpr>,
111 pub loop_step: Box<IdedExpr>,
112 pub result: Box<IdedExpr>,
113}
114
115#[derive(Debug, Default)]
116pub struct SourceInfo {
117 offsets: BTreeMap<u64, OffsetRange>,
118 pub source: String,
119}
120
121impl SourceInfo {
122 pub fn add_offset(&mut self, id: u64, start: u32, stop: u32) {
123 self.offsets.insert(id, OffsetRange { start, stop });
124 }
125
126 pub fn offset_for(&self, id: u64) -> Option<(u32, u32)> {
127 self.offsets.get(&id).map(|range| (range.start, range.stop))
128 }
129
130 pub(crate) fn pos_for(&self, id: u64) -> Option<(isize, isize)> {
131 match self.offset_for(id) {
132 Some((start, _)) => {
133 let start = start as isize;
134 let mut offset = 0;
135 let mut line = 0;
136 for l in self.source.split_inclusive('\n') {
137 line += 1;
138 offset += l.len() as isize;
139 if start < offset {
140 return Some((line, start + (l.len() as isize) - offset + 1));
141 }
142 }
143 None
144 }
145 None => None,
146 }
147 }
148
149 pub fn snippet(&self, line: isize) -> Option<&str> {
150 self.source.lines().nth(line as usize)
151 }
152}
153
154#[derive(Clone, Debug, Default, PartialEq)]
155pub struct OffsetRange {
156 pub start: u32,
157 pub stop: u32,
158}