| 83 | //========================================================================== |
| 84 | |
| 85 | static FxExpression *CustomTypeCast(FxTypeCast *func, FCompileContext &ctx) |
| 86 | { |
| 87 | if (func->ValueType == TypeStateLabel) |
| 88 | { |
| 89 | auto& basex = func->basex; |
| 90 | auto& ScriptPosition = func->ScriptPosition; |
| 91 | if (basex->ValueType == TypeNullPtr) |
| 92 | { |
| 93 | auto x = new FxConstant(0, ScriptPosition); |
| 94 | x->ValueType = TypeStateLabel; |
| 95 | delete func; |
| 96 | return x; |
| 97 | } |
| 98 | // Right now this only supports string constants. There should be an option to pass a string variable, too. |
| 99 | if (basex->isConstant() && (basex->ValueType == TypeString || basex->ValueType == TypeName)) |
| 100 | { |
| 101 | FString s= static_cast<FxConstant *>(basex)->GetValue().GetString(); |
| 102 | if (s.Len() == 0 && !ctx.FromDecorate) // DECORATE should never get here at all, but let's better be safe. |
| 103 | { |
| 104 | ScriptPosition.Message(MSG_ERROR, "State jump to empty label."); |
| 105 | delete func; |
| 106 | return nullptr; |
| 107 | } |
| 108 | FxExpression *x = new FxMultiNameState(s.GetChars(), basex->ScriptPosition); |
| 109 | x = x->Resolve(ctx); |
| 110 | basex = nullptr; |
| 111 | delete func; |
| 112 | return x; |
| 113 | } |
| 114 | else if (basex->IsNumeric() && basex->ValueType != TypeSound && basex->ValueType != TypeColor) |
| 115 | { |
| 116 | if (ctx.StateIndex < 0) |
| 117 | { |
| 118 | ScriptPosition.Message(MSG_ERROR, "State jumps with index can only be used in anonymous state functions."); |
| 119 | delete func; |
| 120 | return nullptr; |
| 121 | } |
| 122 | if (ctx.StateCount != 1) |
| 123 | { |
| 124 | ScriptPosition.Message(MSG_ERROR, "State jumps with index cannot be used on multistate definitions"); |
| 125 | delete func; |
| 126 | return nullptr; |
| 127 | } |
| 128 | if (basex->isConstant()) |
| 129 | { |
| 130 | int i = static_cast<FxConstant *>(basex)->GetValue().GetInt(); |
| 131 | if (i <= 0) |
| 132 | { |
| 133 | ScriptPosition.Message(MSG_ERROR, "State index must be positive"); |
| 134 | delete func; |
| 135 | return nullptr; |
| 136 | } |
| 137 | FxExpression *x = new FxStateByIndex(ctx.StateIndex + i, ScriptPosition); |
| 138 | x = x->Resolve(ctx); |
| 139 | basex = nullptr; |
| 140 | delete func; |
| 141 | return x; |
| 142 | } |