···11+module debug at "trilogy:debug" use dbg
22+33+rule nums(1)
44+rule nums(2)
55+rule nums(3)
66+77+proc main!() {
88+ for a = 5 and b = 10 {
99+ dbg!(a : b)
1010+ }
1111+1212+ for nums(a) and nums(b) {
1313+ dbg!(a : b)
1414+ }
1515+}
···144144 self.bind_temporary(next_iteration);
145145 if let Some(value) = self.compile_expression(&expr.value, name) {
146146 let next_iteration = self.use_temporary(next_iteration).unwrap();
147147- self.call_known_continuation(next_iteration, value);
147147+ self.trilogy_value_destroy(value);
148148+ self.void_call_continuation(next_iteration);
148149 }
149150150151 self.become_continuation_point(done_continuation_point);
+67-27
trilogy-llvm/src/query.rs
···181181 )?);
182182 }
183183184184- // Wrap the next iteration with our own, as a lookup requires some cleanup
185185- // before starting its next internal iteration.
186186- let next_iteration_with_cleanup = self.add_continuation("rule_query_cleanup");
187187- let (next_iteration_with_cleanup_continuation, next_iteration_with_cleanup_cp) =
188188- self.capture_current_continuation(next_iteration_with_cleanup, "pass_next");
189189- self.call_known_continuation(
190190- self.use_temporary(next_to).unwrap(),
191191- next_iteration_with_cleanup_continuation,
184184+ self.next_cleanup(
185185+ next_iteration_inner,
186186+ next_to,
187187+ bound_ids,
188188+ bound_before_lookup,
189189+ "rule_query_cleanup",
192190 );
193193- // The cleanup: destroy all variables that were unbound on the way in. This uses
194194- // very similar detection as with patterns, noting that which variables are bound
195195- // at iteration time can be determined statically as we make the pass through the
196196- // query's IR.
197197- self.become_continuation_point(next_iteration_with_cleanup_cp);
198198- self.begin_next_function(next_iteration_with_cleanup);
199199- for id in bound_ids[bound_before_lookup..]
200200- .iter()
201201- .filter(|id| !bound_ids[0..bound_before_lookup].contains(id))
202202- {
203203- let var = self.get_variable(id).unwrap().ptr();
204204- self.trilogy_value_destroy(var);
205205- }
206206- let next_iteration = self.use_temporary(next_iteration_inner).unwrap();
207207- self.call_known_continuation(next_iteration, self.get_continuation(""));
191191+ }
192192+ ir::QueryValue::Disjunction(disj) => {
193193+ let disj_second_fn = self.add_continuation("disj.second");
194194+ let (disj_second, disj_second_cp) =
195195+ self.capture_current_continuation(disj_second_fn, "disj.second");
196196+ let next_of_first = self.compile_iterator(&disj.0, disj_second)?;
197197+ self.call_known_continuation(self.use_temporary(next_to).unwrap(), next_of_first);
198198+199199+ self.become_continuation_point(disj_second_cp);
200200+ self.begin_next_function(disj_second_fn);
201201+ let next_of_second = self.compile_iterator(&disj.1, done_to)?;
202202+ self.call_known_continuation(self.use_temporary(next_to).unwrap(), next_of_second);
208203 }
209209- ir::QueryValue::Disjunction(..) => todo!(),
210210- ir::QueryValue::Conjunction(..) => todo!(),
204204+ ir::QueryValue::Conjunction(conj) => {
205205+ let next_of_first = self.compile_iterator(&conj.0, done_to)?;
206206+ self.bind_temporary(next_of_first);
207207+ let next_of_second = self.compile_iterator(&conj.1, next_of_first)?;
208208+ let next_to = self.use_temporary(next_to).unwrap();
209209+ self.call_known_continuation(next_to, next_of_second);
210210+ }
211211 ir::QueryValue::Implication(..) => todo!(),
212212 ir::QueryValue::Alternative(..) => todo!(),
213213 ir::QueryValue::Direct(unification) => {
214214 let rvalue = self.compile_expression(&unification.expression, "rvalue")?;
215215- self.compile_pattern_match(&unification.pattern, rvalue, done_to)?;
216216- self.next_deterministic(next_to, done_to, "assign_next");
215215+ let pre_len = bound_ids.len();
216216+ bound_ids.extend(self.compile_pattern_match(
217217+ &unification.pattern,
218218+ rvalue,
219219+ done_to,
220220+ )?);
221221+ self.next_cleanup(done_to, next_to, bound_ids, pre_len, "assign_next");
217222 }
218223 ir::QueryValue::Element(..) => todo!(),
219224 ir::QueryValue::Not(..) => todo!(),
···237242 self.begin_next_function(next_iteration);
238243 let done_to = self.use_temporary(done_to).unwrap();
239244 self.void_call_continuation(done_to);
245245+ }
246246+247247+ fn next_cleanup(
248248+ &self,
249249+ next_iteration: PointerValue<'ctx>,
250250+ next_to: PointerValue<'ctx>,
251251+ bound_ids: &[Id],
252252+ keep_ids: usize,
253253+ name: &str,
254254+ ) {
255255+ // Wrap the next iteration with our own, as a lookup requires some cleanup
256256+ // before starting its next internal iteration.
257257+ let next_iteration_with_cleanup = self.add_continuation(name);
258258+ let (next_iteration_with_cleanup_continuation, next_iteration_with_cleanup_cp) =
259259+ self.capture_current_continuation(next_iteration_with_cleanup, name);
260260+ self.call_known_continuation(
261261+ self.use_temporary(next_to).unwrap(),
262262+ next_iteration_with_cleanup_continuation,
263263+ );
264264+265265+ // The cleanup: destroy all variables that were unbound on the way in. This uses
266266+ // very similar detection as with patterns, noting that which variables are bound
267267+ // at iteration time can be determined statically as we make the pass through the
268268+ // query's IR.
269269+ self.become_continuation_point(next_iteration_with_cleanup_cp);
270270+ self.begin_next_function(next_iteration_with_cleanup);
271271+ for id in bound_ids[keep_ids..]
272272+ .iter()
273273+ .filter(|id| !bound_ids[0..keep_ids].contains(id))
274274+ {
275275+ let var = self.get_variable(id).unwrap().ptr();
276276+ self.trilogy_value_destroy(var);
277277+ }
278278+ let next_iteration = self.use_temporary(next_iteration).unwrap();
279279+ self.void_call_continuation(next_iteration);
240280 }
241281}