1use crate::egraph::{Analysis, EGraph, Id};
2use crate::intent::{CrossLanguageCall, IKun};
3use chomsky_types::Loc;
4
5pub struct IntentBuilder<'a, A: Analysis<IKun>> {
6 pub egraph: &'a mut EGraph<IKun, A>,
7}
8
9impl<'a, A: Analysis<IKun>> IntentBuilder<'a, A> {
10 pub fn new(egraph: &'a mut EGraph<IKun, A>) -> Self {
11 Self { egraph }
12 }
13
14 pub fn add(&mut self, node: IKun, loc: Loc) -> Id {
16 self.egraph.add_with_loc(node, loc)
17 }
18
19 pub fn constant(&mut self, v: i64, loc: Loc) -> Id {
22 self.add(IKun::Constant(v), loc)
23 }
24
25 pub fn int(&mut self, v: i64, loc: Loc) -> Id {
26 self.constant(v, loc)
27 }
28
29 pub fn float(&mut self, v: f64, loc: Loc) -> Id {
30 self.add(IKun::FloatConstant(v.to_bits()), loc)
31 }
32
33 pub fn bool(&mut self, v: bool, loc: Loc) -> Id {
34 self.add(IKun::BooleanConstant(v), loc)
35 }
36
37 pub fn none(&mut self, loc: Loc) -> Id {
38 self.add(IKun::None, loc)
39 }
40
41 pub fn string(&mut self, s: &str, loc: Loc) -> Id {
42 self.add(IKun::StringConstant(s.to_string()), loc)
43 }
44
45 pub fn symbol(&mut self, s: &str, loc: Loc) -> Id {
46 self.add(IKun::Symbol(s.to_string()), loc)
47 }
48
49 pub fn import(&mut self, module: &str, name: &str, loc: Loc) -> Id {
50 self.add(IKun::Import(module.to_string(), name.to_string()), loc)
51 }
52
53 pub fn export(&mut self, name: &str, body: Id, loc: Loc) -> Id {
54 self.add(IKun::Export(name.to_string(), body), loc)
55 }
56
57 pub fn seq(&mut self, items: Vec<Id>, loc: Loc) -> Id {
60 self.add(IKun::Seq(items), loc)
61 }
62
63 pub fn map(&mut self, f: Id, input: Id, loc: Loc) -> Id {
64 self.add(IKun::Map(f, input), loc)
65 }
66
67 pub fn reduce(&mut self, f: Id, init: Id, list: Id, loc: Loc) -> Id {
68 self.add(IKun::Reduce(f, init, list), loc)
69 }
70
71 pub fn filter(&mut self, f: Id, input: Id, loc: Loc) -> Id {
72 self.add(IKun::Filter(f, input), loc)
73 }
74
75 pub fn call(&mut self, func: Id, args: Vec<Id>, loc: Loc) -> Id {
76 self.add(IKun::Apply(func, args), loc)
77 }
78
79 pub fn lambda(&mut self, params: Vec<String>, body: Id, loc: Loc) -> Id {
80 self.add(IKun::Lambda(params, body), loc)
81 }
82
83 pub fn assign(&mut self, name: &str, value: Id, loc: Loc) -> Id {
84 let sym = self.symbol(name, loc);
85 self.add(IKun::StateUpdate(sym, value), loc)
86 }
87
88 pub fn assign_to_id(&mut self, target: Id, value: Id, loc: Loc) -> Id {
89 self.add(IKun::StateUpdate(target, value), loc)
90 }
91
92 pub fn block(&mut self, stmts: Vec<Id>, loc: Loc) -> Id {
93 self.seq(stmts, loc)
94 }
95
96 pub fn module(&mut self, name: &str, items: Vec<Id>, loc: Loc) -> Id {
97 self.add(IKun::Module(name.to_string(), items), loc)
98 }
99
100 pub fn branch(&mut self, cond: Id, then_branch: Id, else_branch: Id, loc: Loc) -> Id {
103 self.add(IKun::Choice(cond, then_branch, else_branch), loc)
104 }
105
106 pub fn if_(&mut self, cond: Id, then_branch: Id, else_branch: Option<Id>, loc: Loc) -> Id {
107 let else_id = else_branch.unwrap_or_else(|| self.block(vec![], loc));
108 self.branch(cond, then_branch, else_id, loc)
109 }
110
111 pub fn loop_(&mut self, count: Id, body: Id, loc: Loc) -> Id {
112 self.add(IKun::Repeat(count, body), loc)
113 }
114
115 pub fn while_loop(&mut self, cond: Id, body: Id, loc: Loc) -> Id {
116 self.extension("while", vec![cond, body], loc)
122 }
123
124 pub fn while_(&mut self, cond: Id, body: Id, loc: Loc) -> Id {
125 self.while_loop(cond, body, loc)
126 }
127
128 pub fn break_(&mut self, loc: Loc) -> Id {
129 self.extension("break", vec![], loc)
130 }
131
132 pub fn continue_(&mut self, loc: Loc) -> Id {
133 self.extension("continue", vec![], loc)
134 }
135
136 pub fn return_(&mut self, value: Id, loc: Loc) -> Id {
137 self.add(IKun::Return(value), loc)
138 }
139
140 pub fn cross_lang_call(
141 &mut self,
142 lang: &str,
143 group: &str,
144 func: &str,
145 args: Vec<Id>,
146 loc: Loc,
147 ) -> Id {
148 self.add(
149 IKun::CrossLangCall(CrossLanguageCall {
150 language: lang.to_string(),
151 module_path: group.to_string(),
152 function_name: func.to_string(),
153 arguments: args,
154 }),
155 loc,
156 )
157 }
158
159 pub fn extension(&mut self, name: &str, args: Vec<Id>, loc: Loc) -> Id {
162 self.add(IKun::Extension(name.to_string(), args), loc)
163 }
164
165 pub fn binary_op(&mut self, op: &str, left: Id, right: Id, loc: Loc) -> Id {
166 self.add(IKun::BinaryOp(op.to_string(), left, right), loc)
167 }
168
169 pub fn unary_op(&mut self, op: &str, operand: Id, loc: Loc) -> Id {
170 self.add(IKun::UnaryOp(op.to_string(), operand), loc)
171 }
172
173 pub fn address_of(&mut self, target: Id, loc: Loc) -> Id {
174 self.add(IKun::AddrOf(target), loc)
175 }
176
177 pub fn deref(&mut self, pointer: Id, loc: Loc) -> Id {
178 self.add(IKun::Deref(pointer), loc)
179 }
180
181 pub fn ptr_offset(&mut self, base: Id, offset: Id, loc: Loc) -> Id {
182 self.add(IKun::PtrOffset(base, offset), loc)
183 }
184
185 pub fn class_def(&mut self, name: &str, bases: Vec<Id>, body: Id, loc: Loc) -> Id {
186 self.add(IKun::ClassDef(name.to_string(), bases, body), loc)
187 }
188
189 pub fn table(&mut self, pairs: Vec<Id>, loc: Loc) -> Id {
190 self.add(IKun::Table(pairs), loc)
191 }
192
193 pub fn pair(&mut self, key: Id, value: Id, loc: Loc) -> Id {
194 self.add(IKun::Pair(key, value), loc)
195 }
196
197 pub fn get_index(&mut self, receiver: Id, index: Id, loc: Loc) -> Id {
198 self.add(IKun::GetIndex(receiver, index), loc)
199 }
200
201 pub fn set_index(&mut self, receiver: Id, index: Id, value: Id, loc: Loc) -> Id {
202 self.add(IKun::SetIndex(receiver, index, value), loc)
203 }
204
205 pub fn add_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
206 self.binary_op("add", left, right, loc)
207 }
208
209 pub fn sub_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
210 self.binary_op("sub", left, right, loc)
211 }
212
213 pub fn mul_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
214 self.binary_op("mul", left, right, loc)
215 }
216
217 pub fn div_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
218 self.binary_op("div", left, right, loc)
219 }
220
221 pub fn eq_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
222 self.binary_op("eq", left, right, loc)
223 }
224
225 pub fn ne_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
226 self.binary_op("ne", left, right, loc)
227 }
228
229 pub fn lt_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
230 self.binary_op("lt", left, right, loc)
231 }
232
233 pub fn le_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
234 self.binary_op("le", left, right, loc)
235 }
236
237 pub fn gt_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
238 self.binary_op("gt", left, right, loc)
239 }
240
241 pub fn ge_op(&mut self, left: Id, right: Id, loc: Loc) -> Id {
242 self.binary_op("ge", left, right, loc)
243 }
244
245 pub fn neg_op(&mut self, val: Id, loc: Loc) -> Id {
246 self.extension("neg", vec![val], loc)
247 }
248
249 pub fn not_op(&mut self, val: Id, loc: Loc) -> Id {
250 self.extension("not", vec![val], loc)
251 }
252
253 pub fn len_op(&mut self, val: Id, loc: Loc) -> Id {
254 self.extension("len", vec![val], loc)
255 }
256
257 pub fn bit_not_op(&mut self, val: Id, loc: Loc) -> Id {
258 self.extension("bit_not", vec![val], loc)
259 }
260
261 pub fn get_index_ext(&mut self, obj: Id, key: Id, loc: Loc) -> Id {
262 self.extension("get_index", vec![obj, key], loc)
263 }
264
265 pub fn set_index_ext(&mut self, obj: Id, key: Id, val: Id, loc: Loc) -> Id {
266 self.extension("set_index", vec![obj, key, val], loc)
267 }
268
269 pub fn parameter(&mut self, name: &str, _loc: Loc) -> String {
270 name.to_string()
271 }
272
273 pub fn function(&mut self, name: &str, params: Vec<String>, body: Vec<Id>, loc: Loc) -> Id {
274 let body_seq = self.block(body, loc.clone());
275 let lam = self.lambda(params, body_seq, loc.clone());
276 if name == "anonymous" {
277 lam
278 } else {
279 self.assign(name, lam, loc)
280 }
281 }
282
283 pub fn resource_clone(&mut self, target: Id, loc: Loc) -> Id {
286 self.add(IKun::ResourceClone(target), loc)
287 }
288
289 pub fn resource_drop(&mut self, target: Id, loc: Loc) -> Id {
290 self.add(IKun::ResourceDrop(target), loc)
291 }
292
293 pub fn resource_context(&mut self, loc: Loc) -> Id {
294 self.add(IKun::ResourceContext, loc)
295 }
296}