|
| 1 | +const SIX = 6 |
| 2 | + |
| 3 | +enum EEmpty {} |
| 4 | + |
| 5 | +enum Color { |
| 6 | + Red, |
| 7 | + Green, |
| 8 | + Blue |
| 9 | +} |
| 10 | + |
| 11 | +type ColorAlias = Color |
| 12 | + |
| 13 | +struct WithColor { |
| 14 | + c1: Color |
| 15 | + c2: Color = Color.Green |
| 16 | +} |
| 17 | + |
| 18 | +enum EPartialAssigned { |
| 19 | + M100 = -100, |
| 20 | + M99, |
| 21 | + P1 = (1 + 0) << 0; |
| 22 | + P2 = ((+1 + 1) << 1) / 2; |
| 23 | + P3 |
| 24 | + P4 |
| 25 | + P5 = 0b101, |
| 26 | + P6 = SIX; |
| 27 | + Max = 0x7FFFFFFF, |
| 28 | +} |
| 29 | + |
| 30 | +enum Err { |
| 31 | + TooLowId = 0x100, |
| 32 | + TooHighId, |
| 33 | + DisabledId, |
| 34 | +} |
| 35 | + |
| 36 | +struct Box<T> { |
| 37 | + value: T |
| 38 | +} |
| 39 | + |
| 40 | +fun checkIsBlue(c: Color) { |
| 41 | + return c == Color.Blue |
| 42 | +} |
| 43 | + |
| 44 | +fun Color.isBlue(self) { |
| 45 | + return self == Color.Blue |
| 46 | +} |
| 47 | + |
| 48 | +fun Color.createBlue() { |
| 49 | + return Color.Blue |
| 50 | +} |
| 51 | + |
| 52 | +const C_BLUE = Color.Blue |
| 53 | +const C_TEN = 5 * (Color.Green as int) * 2 |
| 54 | + |
| 55 | +// these methods do not bother Color.Red and other |
| 56 | +fun T.Red() { return 123 } |
| 57 | +fun T.Max() { return -C_TEN } |
| 58 | +fun int.Max(self) { return self } |
| 59 | +fun Color.Max(): EPartialAssigned { return ((EPartialAssigned.Max as int) + 1) as EPartialAssigned } |
| 60 | + |
| 61 | +@noinline |
| 62 | +fun checkIsColor<T>(obj: Color | T) { return obj is Color } |
| 63 | + |
| 64 | +@inline_ref |
| 65 | +fun Color.mapToNumber(self) { |
| 66 | + // match over enum is exhaustive, it's like "if Red {} else if Green {} else {}" |
| 67 | + return match (self) { |
| 68 | + Color.Red => 100, |
| 69 | + Color.Green => 200, |
| 70 | + Color.Blue => 300, // this works like `else` and handles invalid values at runtime also |
| 71 | + } |
| 72 | +} |
| 73 | + |
| 74 | + |
| 75 | +@method_id(101) |
| 76 | +fun test1() { |
| 77 | + var c = Color.Red; |
| 78 | + |
| 79 | + return ( |
| 80 | + checkIsBlue(Color.Blue), checkIsBlue(c), checkIsBlue(Color.createBlue()), |
| 81 | + Color.Blue.isBlue(), Color.Red.isBlue(), Color.createBlue()!!.isBlue(), C_BLUE.isBlue(), |
| 82 | + Color.createBlue() |
| 83 | + ); |
| 84 | +} |
| 85 | + |
| 86 | +@method_id(102) |
| 87 | +fun test2(c: Color) { |
| 88 | + return (c is Color, c !is Color, c is EPartialAssigned, c is EEmpty, c is int, c is int8); |
| 89 | +} |
| 90 | + |
| 91 | +@method_id(103) |
| 92 | +fun test3() { |
| 93 | + assert (EPartialAssigned.P4 as int == 4) throw 123; |
| 94 | + assert (EPartialAssigned.M99 as int <= 0) throw 123; |
| 95 | + assert (EPartialAssigned.P3 == (3 as EPartialAssigned)) throw 123; |
| 96 | + assert (EPartialAssigned.P3 != (4 as EPartialAssigned)) throw 123; |
| 97 | + return ( |
| 98 | + EPartialAssigned.M100, |
| 99 | + EPartialAssigned.M99, |
| 100 | + EPartialAssigned.P1, |
| 101 | + EPartialAssigned.P2, |
| 102 | + EPartialAssigned.P3, |
| 103 | + EPartialAssigned.P4, |
| 104 | + EPartialAssigned.P5, |
| 105 | + EPartialAssigned.P6, |
| 106 | + EPartialAssigned.Max, |
| 107 | + ) |
| 108 | +} |
| 109 | + |
| 110 | +@method_id(104) |
| 111 | +fun test4(chooseGreen: bool) { |
| 112 | + var c: ColorAlias = chooseGreen ? Color.Green : ColorAlias.Blue; |
| 113 | + return (c is Color, (c!) is ColorAlias, ColorAlias.Blue, ColorAlias.createBlue().isBlue(), c); |
| 114 | +} |
| 115 | + |
| 116 | +@method_id(105) |
| 117 | +fun test5() { |
| 118 | + return (int.Red(), int8.Max(), 456.Max(), EPartialAssigned.Max, Color.Max()); |
| 119 | +} |
| 120 | + |
| 121 | +@method_id(106) |
| 122 | +fun test6(c: Color) { |
| 123 | + val p = c as EPartialAssigned; |
| 124 | + val e = c as EEmpty; |
| 125 | + match (e) { EEmpty => {} } |
| 126 | + return (p, e, c as int, c as int?, 100 as Color, -100 as EEmpty); |
| 127 | +} |
| 128 | + |
| 129 | +@method_id(107) |
| 130 | +fun test7() { |
| 131 | + return ( |
| 132 | + WithColor{c1: Color.Red}, |
| 133 | + WithColor{c1: -100 as Color, c2: Color.createBlue()} |
| 134 | + ) |
| 135 | +} |
| 136 | + |
| 137 | +@method_id(108) |
| 138 | +fun test8() { |
| 139 | + var (c0: Color | int, c1: Color | int) = (Color.Red, 123); |
| 140 | + var (u1, u2) = (Color.Red as Color | int, 0 as Color | int); |
| 141 | + var (b1, b2, b3) = (Color.Red as Color | EPartialAssigned | builder, EPartialAssigned.Max as ColorAlias | builder | EPartialAssigned, beginCell() as builder | Color | EPartialAssigned); |
| 142 | + return ( |
| 143 | + checkIsColor(u1), checkIsColor(u2), |
| 144 | + checkIsColor(b1), checkIsColor(b2), checkIsColor(b3), |
| 145 | + b2 is EPartialAssigned, |
| 146 | + u1, |
| 147 | + match (u1) { int => -100, Color => -200 } |
| 148 | + ) |
| 149 | +} |
| 150 | + |
| 151 | +@method_id(109) |
| 152 | +fun test9() { |
| 153 | + return ( |
| 154 | + Color.Red.mapToNumber(), Color.Green.mapToNumber(), Color.Blue.mapToNumber(), |
| 155 | + // this is UB, the compiler may do any optimizations |
| 156 | + (100 as Color).mapToNumber(), (-99 as Color).mapToNumber(), |
| 157 | + ); |
| 158 | +} |
| 159 | + |
| 160 | +@method_id(110) |
| 161 | +fun test10(c: Color) { |
| 162 | + var t = createEmptyTuple(); |
| 163 | + match (c) { |
| 164 | + Color.Red => { t.push(1) } |
| 165 | + else => { t.push(-100) } |
| 166 | + } |
| 167 | + match (c) { |
| 168 | + Color.Green => { t.push(2) } |
| 169 | + Color.Blue => { t.push(3) } |
| 170 | + Color.Red => { t.push(1) } |
| 171 | + } |
| 172 | + match (c is Color) { |
| 173 | + true => { t.push(-100) } |
| 174 | + } |
| 175 | + match (c) { |
| 176 | + Color => { t.push(88) } |
| 177 | + } |
| 178 | + match (c) { |
| 179 | + Color.Blue => { t.push(3) } |
| 180 | + Color.Green => { t.push(2) } |
| 181 | + else => { t.push(-100) } |
| 182 | + } |
| 183 | + match (c) { |
| 184 | + Color.Red => { t.push(1) } |
| 185 | + Color.Blue => { t.push(3) } |
| 186 | + Color.Green => { t.push(2) } |
| 187 | + } |
| 188 | + return t; |
| 189 | +} |
| 190 | + |
| 191 | +@method_id(111) |
| 192 | +fun test11(b1Value: Color) { |
| 193 | + var b1: Box<Color> = { value: b1Value }; |
| 194 | + var b2 = Box<Color> { value: Color.Green }; |
| 195 | + var b3 = Box { value: Color.Blue }; |
| 196 | + return (b1.value == b2.value, b1.value != b2.value, b1.value == b3.value, b1.value != b3.value) |
| 197 | +} |
| 198 | + |
| 199 | +@method_id(112) |
| 200 | +fun test12(c1: Color, c2: Color) { |
| 201 | + var t = createEmptyTuple(); |
| 202 | + |
| 203 | + match (c1) { |
| 204 | + Color.Red => { t.push(10 + c2.mapToNumber()) } |
| 205 | + Color.Green => { t.push(20 + c2.mapToNumber()) } |
| 206 | + Color.Blue => { t.push(30 + c2.mapToNumber()) } |
| 207 | + } |
| 208 | + |
| 209 | + match (c2) { |
| 210 | + Color.Red => { |
| 211 | + match (c1) { |
| 212 | + Color.Red => t.push(100), |
| 213 | + Color.Blue => t.push(300), |
| 214 | + Color.Green => t.push(200), |
| 215 | + } |
| 216 | + } |
| 217 | + Color.Blue => match (c1) { |
| 218 | + Color.Green => t.push(210), |
| 219 | + Color.Red => t.push(110), |
| 220 | + Color.Blue => t.push(310), |
| 221 | + }, |
| 222 | + Color.Green => match (c1) { |
| 223 | + Color.Green => t.push(220), |
| 224 | + Color.Red => t.push(120), |
| 225 | + Color.Blue => t.push(320), |
| 226 | + } |
| 227 | + } |
| 228 | + |
| 229 | + t.push((999 as Color).mapToNumber()); |
| 230 | + return t; |
| 231 | +} |
| 232 | + |
| 233 | +@method_id(113) |
| 234 | +fun test13(x: int) { |
| 235 | + try { |
| 236 | + if (x < 0) { throw Err.TooLowId } |
| 237 | + assert (x < 100) throw Err.TooHighId; |
| 238 | + assert (x != 10, Err.DisabledId); |
| 239 | + return (0, false); |
| 240 | + } catch (excno) { |
| 241 | + return (excno, excno as Err == Err.TooLowId); |
| 242 | + } |
| 243 | +} |
| 244 | + |
| 245 | + |
| 246 | +fun main(c: Color) { |
| 247 | + __expect_type(c, "Color"); |
| 248 | + __expect_type(C_BLUE, "Color"); |
| 249 | + __expect_type(Color.createBlue(), "Color"); |
| 250 | + __expect_type(ColorAlias.Red, "Color"); |
| 251 | + __expect_type(EPartialAssigned.Max, "EPartialAssigned"); |
| 252 | + __expect_type(Box{value:Color.Red}, "Box<Color>"); |
| 253 | + return c; |
| 254 | +} |
| 255 | + |
| 256 | + |
| 257 | +/** |
| 258 | +@testcase | 0 | 123 | 123 |
| 259 | +@testcase | 101 | | -1 0 -1 -1 0 -1 -1 2 |
| 260 | +@testcase | 102 | 1 | -1 0 0 0 0 0 |
| 261 | +@testcase | 103 | | -100 -99 1 2 3 4 5 6 2147483647 |
| 262 | +@testcase | 104 | -1 | -1 -1 2 -1 1 |
| 263 | +@testcase | 105 | | 123 -10 456 2147483647 2147483648 |
| 264 | +@testcase | 106 | 1 | 1 1 1 1 100 -100 |
| 265 | +@testcase | 107 | | 0 1 -100 2 |
| 266 | +@testcase | 108 | | -1 0 -1 0 0 -1 0 typeid-1 -200 |
| 267 | +@testcase | 109 | | 100 200 300 300 300 |
| 268 | +@testcase | 110 | 0 | [ 1 1 -100 88 -100 1 ] |
| 269 | +@testcase | 110 | 1 | [ -100 2 -100 88 2 2 ] |
| 270 | +@testcase | 110 | 2 | [ -100 3 -100 88 3 3 ] |
| 271 | +@testcase | 110 | 44 | [ -100 1 -100 88 -100 2 ] |
| 272 | +@testcase | 111 | 2 | 0 -1 -1 0 |
| 273 | +@testcase | 112 | 0 1 | [ 210 120 300 ] |
| 274 | +@testcase | 112 | 2 4 | [ 330 320 300 ] |
| 275 | +@testcase | 113 | -8 | 256 -1 |
| 276 | +@testcase | 113 | 111 | 257 0 |
| 277 | +@testcase | 113 | 10 | 258 0 |
| 278 | +@testcase | 113 | 50 | 0 0 |
| 279 | + |
| 280 | +@fif_codegen |
| 281 | +""" |
| 282 | + test1() PROC:<{ |
| 283 | + TRUE |
| 284 | + FALSE |
| 285 | + TRUE |
| 286 | + TRUE |
| 287 | + FALSE |
| 288 | + TRUE |
| 289 | + TRUE |
| 290 | + 2 PUSHINT |
| 291 | + }> |
| 292 | +""" |
| 293 | + |
| 294 | +@fif_codegen |
| 295 | +""" |
| 296 | + test2() PROC:<{ // c |
| 297 | + DROP // |
| 298 | + -1 PUSHINT // '1=-1 |
| 299 | + 0 PUSHINT // '1=-1 '2 |
| 300 | + 0 PUSHINT // '1=-1 '2 '3=0 |
| 301 | + s0 s0 s0 PUSH3 // '1=-1 '2 '3=0 '4=0 '5=0 '6=0 |
| 302 | + }> |
| 303 | +""" |
| 304 | + |
| 305 | +@fif_codegen DECLPROC checkIsColor<EPartialAssigned|builder>() |
| 306 | + |
| 307 | +*/ |
0 commit comments