Actually just three programming languages in a trenchcoat
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

partially implement fully unbound handling

+28 -7
+28 -7
trilogy-llvm/src/rule.rs
··· 2 2 use inkwell::values::FunctionValue; 3 3 use source_span::Span; 4 4 use std::borrow::Borrow; 5 - use trilogy_ir::{Id, ir}; 5 + use trilogy_ir::{Id, ir, visitor::HasCanEvaluate}; 6 6 7 7 impl<'ctx> Codegen<'ctx> { 8 8 fn write_rule_accessor( ··· 126 126 self.begin_next_function(next_parameter_function); 127 127 } 128 128 } 129 + // The rule runs the iterator, resulting in new bindings being set. 129 130 let Some(next_iteration) = self.compile_iterator(&overload.body, go_to_next_overload) 130 131 else { 131 132 break 'outer; ··· 134 135 135 136 let mut arguments = Vec::with_capacity(arity + 1); 136 137 arguments.push(next_iteration); 137 - for param in &overload.parameters { 138 - let Some(param_value) = self.compile_expression(param, "") else { 139 - break 'outer; 140 - }; 141 - self.bind_temporary(param_value); 142 - arguments.push(param_value); 138 + // Then each parameter pattern is evaluated to create the values for the output arguments. 139 + // If the parameter cannot be evaluated (e.g. `rule always(_)`) 140 + // * Re-use the input parameter value if available; but 141 + // * if the input parameter was also not set (e.g. `for always(a)`), then consider this a failed 142 + // overload and go next. 143 + for (i, param) in overload.parameters.iter().enumerate() { 144 + if param.can_evaluate() { 145 + let Some(param_value) = self.compile_expression(param, "") else { 146 + break 'outer; 147 + }; 148 + self.bind_temporary(param_value); 149 + arguments.push(param_value); 150 + } else { 151 + let input_param = self.function_params.borrow()[i]; 152 + let input_param = self.use_temporary(input_param).unwrap(); 153 + let here = self.get_function(); 154 + let fully_unbound = self.context.append_basic_block(here, "fully_unbound"); 155 + let rebind_input = self.context.append_basic_block(here, "rebind_input"); 156 + self.branch_undefined(input_param, fully_unbound, rebind_input); 157 + self.builder.position_at_end(fully_unbound); 158 + let next_overload = self.use_temporary(go_to_next_overload).unwrap(); 159 + self.void_call_continuation(next_overload); 160 + 161 + self.builder.position_at_end(rebind_input); 162 + arguments.push(input_param); 163 + } 143 164 } 144 165 let next = self.get_next(""); 145 166 for arg in arguments.iter_mut() {