Appearance
| 1 | namespace IR.Values is | |
| 2 | use System.Reflection.Metadata.ILOpCode | |
| 3 | ||
| 4 | use Semantic.Types.Type | |
| 5 | ||
| 6 | use Ghul.Pipes | |
| 7 | ||
| 8 | // Every one of a list of boolean values, short-circuited: the | |
| 9 | // first that answers false is the answer, and the rest are never | |
| 10 | // evaluated. | |
| 11 | // | |
| 12 | // A synthesized `=~` is a guard followed by one comparison per | |
| 13 | // member followed by whatever the base contributes, and each of | |
| 14 | // those is built as a value of its own. This is the conjunction | |
| 15 | // around them, so that nothing has to build a tree of `/\` | |
| 16 | // expressions to say `and` in. | |
| 17 | // | |
| 18 | // <first> | |
| 19 | // brfalse <false> | |
| 20 | // <second> | |
| 21 | // brfalse <false> | |
| 22 | // ... | |
| 23 | // ldc.i4.1 | |
| 24 | // br <end> | |
| 25 | // <false>: | |
| 26 | // ldc.i4.0 | |
| 27 | // <end>: | |
| 28 | class ALL_OF: Value is | |
| 29 | operands: Collections.LIST[Value] | |
| 30 | _result_type: Type | |
| 31 | ||
| 32 | type: Type => _result_type | |
| 33 | is_lightweight_pure: bool => false | |
| 34 | ||
| 35 | init(operands: Collections.LIST[Value], result_type: Type) is | |
| 36 | super.init() | |
| 37 | ||
| 38 | self.operands = operands | |
| 39 | self._result_type = result_type | |
| 40 | si | |
| 41 | ||
| 42 | gen(context: IR.CONTEXT) is | |
| 43 | let body = context.current_srm_body_emitter! | |
| 44 | ||
| 45 | // Nothing to be false: an empty conjunction is true, which | |
| 46 | // is what a type with no members to compare answers once | |
| 47 | // its guard has passed. | |
| 48 | if operands.count == 0 then | |
| 49 | body.ldc_i4(1) | |
| 50 | ||
| 51 | return | |
| 52 | fi | |
| 53 | ||
| 54 | let false_label = IR.LABEL() | |
| 55 | let end_label = IR.LABEL() | |
| 56 | ||
| 57 | for operand in operands do | |
| 58 | gen(operand, context) | |
| 59 | body.branch(ILOpCode.BRFALSE, false_label) | |
| 60 | od | |
| 61 | ||
| 62 | body.ldc_i4(1) | |
| 63 | body.branch(ILOpCode.BR, end_label) | |
| 64 | ||
| 65 | body.mark_label(false_label) | |
| 66 | body.ldc_i4(0) | |
| 67 | ||
| 68 | body.mark_label(end_label) | |
| 69 | si | |
| 70 | ||
| 71 | to_string() -> string => | |
| 72 | "all-of:[{type}]({operands |> map(o => "{o}") |> join(",")})" | |
| 73 | si | |
| 74 | si |