···1+module debug at "trilogy:debug" use dbg
2+3+rule nums(1)
4+rule nums(2)
5+rule nums(3)
6+7+proc main!() {
8+ for a = 5 and b = 10 {
9+ dbg!(a : b)
10+ }
11+12+ for nums(a) and nums(b) {
13+ dbg!(a : b)
14+ }
15+}
···144 self.bind_temporary(next_iteration);
145 if let Some(value) = self.compile_expression(&expr.value, name) {
146 let next_iteration = self.use_temporary(next_iteration).unwrap();
147- self.call_known_continuation(next_iteration, value);
0148 }
149150 self.become_continuation_point(done_continuation_point);
···144 self.bind_temporary(next_iteration);
145 if let Some(value) = self.compile_expression(&expr.value, name) {
146 let next_iteration = self.use_temporary(next_iteration).unwrap();
147+ self.trilogy_value_destroy(value);
148+ self.void_call_continuation(next_iteration);
149 }
150151 self.become_continuation_point(done_continuation_point);
+67-27
trilogy-llvm/src/query.rs
···181 )?);
182 }
183184- // Wrap the next iteration with our own, as a lookup requires some cleanup
185- // before starting its next internal iteration.
186- let next_iteration_with_cleanup = self.add_continuation("rule_query_cleanup");
187- let (next_iteration_with_cleanup_continuation, next_iteration_with_cleanup_cp) =
188- self.capture_current_continuation(next_iteration_with_cleanup, "pass_next");
189- self.call_known_continuation(
190- self.use_temporary(next_to).unwrap(),
191- next_iteration_with_cleanup_continuation,
192 );
193- // The cleanup: destroy all variables that were unbound on the way in. This uses
194- // very similar detection as with patterns, noting that which variables are bound
195- // at iteration time can be determined statically as we make the pass through the
196- // query's IR.
197- self.become_continuation_point(next_iteration_with_cleanup_cp);
198- self.begin_next_function(next_iteration_with_cleanup);
199- for id in bound_ids[bound_before_lookup..]
200- .iter()
201- .filter(|id| !bound_ids[0..bound_before_lookup].contains(id))
202- {
203- let var = self.get_variable(id).unwrap().ptr();
204- self.trilogy_value_destroy(var);
205- }
206- let next_iteration = self.use_temporary(next_iteration_inner).unwrap();
207- self.call_known_continuation(next_iteration, self.get_continuation(""));
208 }
209- ir::QueryValue::Disjunction(..) => todo!(),
210- ir::QueryValue::Conjunction(..) => todo!(),
00000211 ir::QueryValue::Implication(..) => todo!(),
212 ir::QueryValue::Alternative(..) => todo!(),
213 ir::QueryValue::Direct(unification) => {
214 let rvalue = self.compile_expression(&unification.expression, "rvalue")?;
215- self.compile_pattern_match(&unification.pattern, rvalue, done_to)?;
216- self.next_deterministic(next_to, done_to, "assign_next");
00000217 }
218 ir::QueryValue::Element(..) => todo!(),
219 ir::QueryValue::Not(..) => todo!(),
···237 self.begin_next_function(next_iteration);
238 let done_to = self.use_temporary(done_to).unwrap();
239 self.void_call_continuation(done_to);
00000000000000000000000000000000000240 }
241}
···181 )?);
182 }
183184+ self.next_cleanup(
185+ next_iteration_inner,
186+ next_to,
187+ bound_ids,
188+ bound_before_lookup,
189+ "rule_query_cleanup",
00190 );
191+ }
192+ ir::QueryValue::Disjunction(disj) => {
193+ let disj_second_fn = self.add_continuation("disj.second");
194+ let (disj_second, disj_second_cp) =
195+ self.capture_current_continuation(disj_second_fn, "disj.second");
196+ let next_of_first = self.compile_iterator(&disj.0, disj_second)?;
197+ self.call_known_continuation(self.use_temporary(next_to).unwrap(), next_of_first);
198+199+ self.become_continuation_point(disj_second_cp);
200+ self.begin_next_function(disj_second_fn);
201+ let next_of_second = self.compile_iterator(&disj.1, done_to)?;
202+ self.call_known_continuation(self.use_temporary(next_to).unwrap(), next_of_second);
000203 }
204+ ir::QueryValue::Conjunction(conj) => {
205+ let next_of_first = self.compile_iterator(&conj.0, done_to)?;
206+ self.bind_temporary(next_of_first);
207+ let next_of_second = self.compile_iterator(&conj.1, next_of_first)?;
208+ let next_to = self.use_temporary(next_to).unwrap();
209+ self.call_known_continuation(next_to, next_of_second);
210+ }
211 ir::QueryValue::Implication(..) => todo!(),
212 ir::QueryValue::Alternative(..) => todo!(),
213 ir::QueryValue::Direct(unification) => {
214 let rvalue = self.compile_expression(&unification.expression, "rvalue")?;
215+ let pre_len = bound_ids.len();
216+ bound_ids.extend(self.compile_pattern_match(
217+ &unification.pattern,
218+ rvalue,
219+ done_to,
220+ )?);
221+ self.next_cleanup(done_to, next_to, bound_ids, pre_len, "assign_next");
222 }
223 ir::QueryValue::Element(..) => todo!(),
224 ir::QueryValue::Not(..) => todo!(),
···242 self.begin_next_function(next_iteration);
243 let done_to = self.use_temporary(done_to).unwrap();
244 self.void_call_continuation(done_to);
245+ }
246+247+ fn next_cleanup(
248+ &self,
249+ next_iteration: PointerValue<'ctx>,
250+ next_to: PointerValue<'ctx>,
251+ bound_ids: &[Id],
252+ keep_ids: usize,
253+ name: &str,
254+ ) {
255+ // Wrap the next iteration with our own, as a lookup requires some cleanup
256+ // before starting its next internal iteration.
257+ let next_iteration_with_cleanup = self.add_continuation(name);
258+ let (next_iteration_with_cleanup_continuation, next_iteration_with_cleanup_cp) =
259+ self.capture_current_continuation(next_iteration_with_cleanup, name);
260+ self.call_known_continuation(
261+ self.use_temporary(next_to).unwrap(),
262+ next_iteration_with_cleanup_continuation,
263+ );
264+265+ // The cleanup: destroy all variables that were unbound on the way in. This uses
266+ // very similar detection as with patterns, noting that which variables are bound
267+ // at iteration time can be determined statically as we make the pass through the
268+ // query's IR.
269+ self.become_continuation_point(next_iteration_with_cleanup_cp);
270+ self.begin_next_function(next_iteration_with_cleanup);
271+ for id in bound_ids[keep_ids..]
272+ .iter()
273+ .filter(|id| !bound_ids[0..keep_ids].contains(id))
274+ {
275+ let var = self.get_variable(id).unwrap().ptr();
276+ self.trilogy_value_destroy(var);
277+ }
278+ let next_iteration = self.use_temporary(next_iteration).unwrap();
279+ self.void_call_continuation(next_iteration);
280 }
281}