Appearance
| 1 | namespace Syntax.Trees.Expressions is | |
| 2 | ||
| 3 | use Source | |
| 4 | ||
| 5 | // Which reading of `cast (X)(args)` is meant. Every other cast is | |
| 6 | // `TYPED` from the start. | |
| 7 | enum CastReading is | |
| 8 | UNDECIDED, | |
| 9 | TYPED, | |
| 10 | CALLED, | |
| 11 | si | |
| 12 | ||
| 13 | // `type_expression` is the target type: `cast T(v)`. Null for | |
| 14 | // `cast(v)`, whose target type is supplied by the context. | |
| 15 | // | |
| 16 | // `is_checked` is true for a cast the program wrote, which faults when | |
| 17 | // it fails, and false for one the compiler synthesises, which declines. | |
| 18 | // See IR.Values.CAST. | |
| 19 | class CAST( | |
| 20 | location: LOCATION, | |
| 21 | type_expression: TypeExpressions.TypeExpression?, | |
| 22 | right: Expression, | |
| 23 | is_checked: bool | |
| 24 | ): Expression is | |
| 25 | super(location) | |
| 26 | ||
| 27 | // `cast (X)(args)` reads two ways and the parser cannot tell | |
| 28 | // them apart: a cast to the parenthesised type `X` taking | |
| 29 | // `args` as its value, or a cast of the value `X` whose result | |
| 30 | // is then called with `args`. Both readings are carried until | |
| 31 | // resolve-type-expressions can ask the scope whether `X` names | |
| 32 | // a type. `called_form` is the second reading written out; | |
| 33 | // `call_arguments` is the list it shares with the first, whose | |
| 34 | // single element is `right`. | |
| 35 | called_form: CALL? public | |
| 36 | call_arguments: LIST? public | |
| 37 | ||
| 38 | reading: CastReading public | |
| 39 | ||
| 40 | is_ambiguous: bool => called_form? | |
| 41 | ||
| 42 | awaits_context_type: bool => !type_expression? | |
| 43 | ||
| 44 | set_ambiguous_readings(called_form: CALL, call_arguments: LIST) is | |
| 45 | self.called_form = called_form | |
| 46 | self.call_arguments = call_arguments | |
| 47 | si | |
| 48 | ||
| 49 | set_reading(reading: CastReading) is | |
| 50 | self.reading = reading | |
| 51 | si | |
| 52 | ||
| 53 | set_expected_type(expected_type: Semantic.Types.Type?, error_message: string?) is | |
| 54 | compile_expressions_state.set_expected_type(expected_type, error_message) | |
| 55 | ||
| 56 | // Under the called reading this node is the call, so the | |
| 57 | // context's type is the call's result type rather than | |
| 58 | // anything the cast targets. | |
| 59 | if reading == CastReading.CALLED then | |
| 60 | called_form!.set_expected_type(expected_type, error_message) | |
| 61 | fi | |
| 62 | si | |
| 63 | ||
| 64 | accept(visitor: Visitor) is | |
| 65 | visitor.visit(self) | |
| 66 | si | |
| 67 | ||
| 68 | walk(visitor: Visitor) is | |
| 69 | if !visitor.pre(self) then | |
| 70 | // Until the reading is settled both branches are | |
| 71 | // walked, so a pass running ahead of the decision sees | |
| 72 | // every subtree exactly once. Afterwards only the | |
| 73 | // branch that won is walked: resolving the loser would | |
| 74 | // report a type name as an undefined value, or an | |
| 75 | // undefined value as a missing type. | |
| 76 | case reading | |
| 77 | when CastReading.TYPED then | |
| 78 | type_expression!.walk(visitor) | |
| 79 | call_arguments!.walk(visitor) | |
| 80 | ||
| 81 | when CastReading.CALLED then | |
| 82 | called_form!.walk(visitor) | |
| 83 | ||
| 84 | else | |
| 85 | if type_expression? then | |
| 86 | type_expression.walk(visitor) | |
| 87 | fi | |
| 88 | ||
| 89 | if let form = called_form then | |
| 90 | form.walk(visitor) | |
| 91 | else | |
| 92 | right.walk(visitor) | |
| 93 | fi | |
| 94 | esac | |
| 95 | fi | |
| 96 | accept(visitor) | |
| 97 | si | |
| 98 | si | |
| 99 | si |