expr.ha (13878B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use hare::lex; 5 6 // An identifier access expression. 7 // 8 // foo 9 export type access_identifier = ident; 10 11 // An index access expression. 12 // 13 // foo[0] 14 export type access_index = struct { 15 object: *expr, 16 index: *expr, 17 }; 18 19 // A struct field access expression. 20 // 21 // foo.bar 22 export type access_field = struct { 23 object: *expr, 24 field: str, 25 }; 26 27 // A tuple field access expression. 28 // 29 // foo.1 30 export type access_tuple = struct { 31 object: *expr, 32 value: *expr, 33 }; 34 35 // An access expression. 36 export type access_expr = (access_identifier | access_index | access_field 37 | access_tuple); 38 39 // An align expression. 40 // 41 // align(int) 42 export type align_expr = *_type; 43 44 // The form of an allocation expression. 45 // 46 // alloc(foo) // OBJECT 47 // alloc(foo...) // COPY 48 export type alloc_form = enum { 49 OBJECT, 50 COPY, 51 }; 52 53 // An allocation expression. 54 // 55 // alloc(foo) 56 // alloc(foo...) 57 // alloc(foo, bar) 58 export type alloc_expr = struct { 59 init: *expr, 60 form: alloc_form, 61 capacity: nullable *expr, 62 }; 63 64 // An append expression. 65 // 66 // append(foo, bar); 67 // append(foo, bar...); 68 // append(foo, [0...], bar); 69 export type append_expr = struct { 70 object: *expr, 71 value: *expr, 72 length: nullable *expr, 73 variadic: bool, 74 is_static: bool, 75 }; 76 77 // An assertion expression. 78 // 79 // assert(foo) 80 // assert(foo, "error") 81 // abort() 82 // abort("error") 83 export type assert_expr = struct { 84 cond: nullable *expr, 85 message: nullable *expr, 86 is_static: bool, 87 }; 88 89 // An assignment expression. 90 // 91 // foo = bar 92 export type assign_expr = struct { 93 op: (binarithm_op | void), 94 object: *expr, 95 value: *expr, 96 }; 97 98 // A binary arithmetic operator 99 export type binarithm_op = enum { 100 // TODO: Rehome this with the checked AST? 101 102 BAND, // & 103 BOR, // | 104 DIV, // / 105 GT, // > 106 GTEQ, // >= 107 LAND, // && 108 LEQUAL, // == 109 LESS, // < 110 LESSEQ, // <= 111 LOR, // || 112 LSHIFT, // << 113 LXOR, // ^^ 114 MINUS, // - 115 MODULO, // % 116 NEQUAL, // != 117 PLUS, // + 118 RSHIFT, // >> 119 TIMES, // * 120 BXOR, // ^ 121 }; 122 123 // A binary arithmetic expression. 124 // 125 // foo * bar 126 export type binarithm_expr = struct { 127 op: binarithm_op, 128 lvalue: *expr, 129 rvalue: *expr, 130 }; 131 132 // A single variable biding. 133 // 134 // foo: int = bar 135 // (foo, foo2): int = bar 136 export type binding = struct { 137 name: (str | binding_unpack), 138 _type: nullable *_type, 139 init: *expr, 140 }; 141 142 // Tuple unpacking binding. 143 // 144 // (foo, _, bar) 145 export type binding_unpack = [](str | void); 146 147 // The kind of binding expression being used. 148 export type binding_kind = enum { 149 CONST, 150 DEF, 151 LET, 152 }; 153 154 // A variable binding expression. 155 // 156 // let foo: int = bar, ... 157 export type binding_expr = struct { 158 is_static: bool, 159 kind: binding_kind, 160 bindings: []binding, 161 }; 162 163 // A break expression. The label is set to empty string if absent. 164 // 165 // break :label 166 export type break_expr = label; 167 168 // A function call expression. 169 // 170 // foo(bar) 171 export type call_expr = struct { 172 lvalue: *expr, 173 variadic: bool, 174 args: []*expr, 175 }; 176 177 // The kind of cast expression being used. 178 export type cast_kind = enum { 179 // TODO: Should this be rehomed with the checked AST? 180 181 CAST, 182 ASSERTION, 183 TEST, 184 }; 185 186 // A cast expression. 187 // 188 // foo: int 189 // foo as int 190 // foo is int 191 export type cast_expr = struct { 192 kind: cast_kind, 193 value: *expr, 194 _type: *_type, 195 }; 196 197 // A compound expression. 198 // 199 // { 200 // foo; 201 // bar; 202 // // ... 203 // } 204 export type compound_expr = struct { 205 exprs: []*expr, 206 label: label, 207 }; 208 209 // An array literal. 210 // 211 // [foo, bar, ...] 212 export type array_literal = struct { 213 expand: bool, 214 values: []*expr, 215 }; 216 217 // A single struct field and value. 218 // 219 // foo: int = 10 220 export type struct_value = struct { 221 name: str, 222 _type: nullable *_type, 223 init: *expr, 224 }; 225 226 // A struct literal. 227 // 228 // struct { foo: int = bar, struct { baz = quux }, ... } 229 export type struct_literal = struct { 230 autofill: bool, 231 alias: ident, // [] for anonymous 232 fields: [](struct_value | *struct_literal), 233 }; 234 235 // A tuple literal. 236 // 237 // (foo, bar, ...) 238 export type tuple_literal = []*expr; 239 240 // The value "null". 241 export type _null = void; 242 243 // A scalar value. 244 export type value = (bool | done | nomem |_null | str | rune | void); 245 246 // An integer or float literal. 247 export type number_literal = struct { 248 suff: lex::ltok, 249 value: (i64 | u64 | f64), 250 sign: bool, // true if negative, false otherwise 251 }; 252 253 // A literal expression. 254 export type literal_expr = (value | array_literal | number_literal | 255 struct_literal | tuple_literal); 256 257 // A continue expression. The label is set to empty string if absent. 258 // 259 // continue :label 260 export type continue_expr = label; 261 262 // A deferred expression. 263 // 264 // defer foo 265 export type defer_expr = *expr; 266 267 // A delete expression. 268 // 269 // delete(foo[10]) 270 // delete(foo[4..42]) 271 export type delete_expr = struct { 272 object: *expr, 273 is_static: bool, 274 }; 275 276 // The kind of for expression being used. 277 export type for_kind = enum { 278 ACCUMULATOR, 279 EACH_VALUE, 280 EACH_POINTER, 281 ITERATOR, 282 }; 283 284 // A for loop. 285 // 286 // for (let foo = 0; foo < bar; baz) quux 287 // for (let line => next_line()) quux 288 // for (let number .. [1, 2, 3]) quux 289 // for (let ptr &.. [1, 2, 3]) quux 290 export type for_expr = struct { 291 kind: for_kind, 292 bindings: nullable *expr, 293 cond: nullable *expr, 294 afterthought: nullable *expr, 295 body: *expr, 296 label: label, 297 }; 298 299 // A free expression. 300 // 301 // free(foo) 302 export type free_expr = *expr; 303 304 // An if or if..else expression. 305 // 306 // if (foo) bar else baz 307 export type if_expr = struct { 308 cond: *expr, 309 tbranch: *expr, 310 fbranch: nullable *expr, 311 }; 312 313 // An insert expression. 314 // 315 // insert(foo[0], bar); 316 // insert(foo[0], bar...); 317 // insert(foo[0], [0...], bar); 318 export type insert_expr = append_expr; 319 320 // :label. The ":" character is not included. 321 export type label = str; 322 323 // A length expression. 324 // 325 // len(foo) 326 export type len_expr = *expr; 327 328 // A match case. 329 // 330 // case type => exprs 331 // case let name: type => exprs 332 export type match_case = struct { 333 name: str, 334 _type: nullable *_type, // null for default case 335 exprs: []*expr, 336 }; 337 338 // A match expression. 339 // 340 // match (foo) { case int => bar; ... } 341 export type match_expr = struct { 342 value: *expr, 343 cases: []match_case, 344 label: label, 345 }; 346 347 // An offset expression. 348 // 349 // offset(foo.bar) 350 export type offset_expr = *expr; 351 352 // An error propagation expression. 353 // 354 // foo? 355 export type propagate_expr = *expr; 356 357 // An error assertion expression. 358 // 359 // foo! 360 export type error_assert_expr = *expr; 361 362 // A return statement. 363 // 364 // return foo 365 export type return_expr = nullable *expr; 366 367 // A size expression. 368 // 369 // size(int) 370 export type size_expr = *_type; 371 372 // A slicing expression. 373 // 374 // foo[bar..baz] 375 export type slice_expr = struct { 376 object: *expr, 377 start: nullable *expr, 378 end: nullable *expr, 379 }; 380 381 // A switch case. 382 // 383 // case value => exprs 384 export type switch_case = struct { 385 options: []*expr, // [] for default case 386 exprs: []*expr, 387 }; 388 389 // A switch expression. 390 // 391 // switch (foo) { case bar => baz; ... } 392 export type switch_expr = struct { 393 value: *expr, 394 cases: []switch_case, 395 label: label, 396 }; 397 398 // A unary operator 399 export type unarithm_op = enum { 400 // TODO: Should this be rehomed with the checked AST? 401 402 ADDR, // & 403 BNOT, // ~ 404 DEREF, // * 405 LNOT, // ! 406 MINUS, // - 407 }; 408 409 // A unary arithmetic expression. 410 // 411 // !example 412 export type unarithm_expr = struct { 413 op: unarithm_op, 414 operand: *expr, 415 }; 416 417 // A vastart expression. 418 // 419 // vastart() 420 export type vastart_expr = void; 421 422 // A vaarg expression. 423 // 424 // vaarg(ap, int) 425 export type vaarg_expr = struct { 426 ap: *expr, 427 _type: *_type, 428 }; 429 430 // A vaend expression. 431 // 432 // vaend(ap) 433 export type vaend_expr = *expr; 434 435 // A C-style variadic expression. 436 export type variadic_expr = (vastart_expr | vaarg_expr | vaend_expr); 437 438 // A yield expression. 439 // 440 // yield foo 441 export type yield_expr = struct { 442 label: label, 443 value: nullable *expr, 444 }; 445 446 // A Hare expression. 447 export type expr = struct { 448 start: lex::location, 449 end: lex::location, 450 expr: (access_expr | align_expr | alloc_expr | append_expr | 451 assert_expr | assign_expr | binarithm_expr | binding_expr | 452 break_expr | call_expr | cast_expr | literal_expr | 453 continue_expr | defer_expr | delete_expr | for_expr | 454 free_expr | error_assert_expr | if_expr | insert_expr | 455 compound_expr | match_expr | len_expr | size_expr | 456 offset_expr | propagate_expr | return_expr | slice_expr | 457 switch_expr | unarithm_expr | variadic_expr | yield_expr), 458 }; 459 460 // Frees resources associated with a Hare [[expr]]ession. 461 export fn expr_finish(e: nullable *expr) void = match (e) { 462 case null => void; 463 case let e: *expr => 464 match (e.expr) { 465 case let a: access_expr => 466 match (a) { 467 case let i: access_identifier => 468 ident_free(i); 469 case let i: access_index => 470 expr_finish(i.object); 471 free(i.object); 472 expr_finish(i.index); 473 free(i.index); 474 case let f: access_field => 475 expr_finish(f.object); 476 free(f.object); 477 free(f.field); 478 case let t: access_tuple => 479 expr_finish(t.object); 480 free(t.object); 481 expr_finish(t.value); 482 free(t.value); 483 }; 484 case let a: align_expr => 485 type_finish(a); 486 free(a); 487 case let a: alloc_expr => 488 expr_finish(a.init); 489 free(a.init); 490 expr_finish(a.capacity); 491 free(a.capacity); 492 case let a: append_expr => 493 expr_finish(a.object); 494 free(a.object); 495 expr_finish(a.value); 496 free(a.value); 497 expr_finish(a.length); 498 free(a.length); 499 case let a: assert_expr => 500 expr_finish(a.cond); 501 free(a.cond); 502 expr_finish(a.message); 503 free(a.message); 504 case let a: assign_expr => 505 expr_finish(a.object); 506 free(a.object); 507 expr_finish(a.value); 508 free(a.value); 509 case let b: binarithm_expr => 510 expr_finish(b.lvalue); 511 free(b.lvalue); 512 expr_finish(b.rvalue); 513 free(b.rvalue); 514 case let b: binding_expr => 515 for (let i = 0z; i < len(b.bindings); i += 1) { 516 match (b.bindings[i].name) { 517 case let s: str => 518 free(s); 519 case let u: binding_unpack => 520 for (let i = 0z; i < len(u); i += 1) { 521 match (u[i]) { 522 case let s: str => 523 free(s); 524 case => void; 525 }; 526 }; 527 free(u); 528 }; 529 type_finish(b.bindings[i]._type); 530 free(b.bindings[i]._type); 531 expr_finish(b.bindings[i].init); 532 free(b.bindings[i].init); 533 }; 534 free(b.bindings); 535 case let b: break_expr => 536 free(b); 537 case let c: call_expr => 538 expr_finish(c.lvalue); 539 free(c.lvalue); 540 for (let i = 0z; i < len(c.args); i += 1) { 541 expr_finish(c.args[i]); 542 free(c.args[i]); 543 }; 544 free(c.args); 545 case let c: cast_expr => 546 expr_finish(c.value); 547 free(c.value); 548 type_finish(c._type); 549 free(c._type); 550 case let c: compound_expr => 551 for (let i = 0z; i < len(c.exprs); i += 1) { 552 expr_finish(c.exprs[i]); 553 free(c.exprs[i]); 554 }; 555 free(c.exprs); 556 free(c.label); 557 case let c: literal_expr => 558 match (c) { 559 case let a: array_literal => 560 for (let i = 0z; i < len(a.values); i += 1) { 561 expr_finish(a.values[i]); 562 free(a.values[i]); 563 }; 564 free(a.values); 565 case let s: struct_literal => 566 struct_literal_finish(&s); 567 case let t: tuple_literal => 568 for (let i = 0z; i < len(t); i += 1) { 569 expr_finish(t[i]); 570 free(t[i]); 571 }; 572 free(t); 573 case (value | number_literal) => void; 574 }; 575 case let c: continue_expr => 576 free(c); 577 case let d: defer_expr => 578 expr_finish(d); 579 free(d); 580 case let d: delete_expr => 581 expr_finish(d.object); 582 free(d.object); 583 case let e: error_assert_expr => 584 expr_finish(e); 585 free(e); 586 case let f: for_expr => 587 expr_finish(f.bindings); 588 free(f.bindings); 589 expr_finish(f.cond); 590 free(f.cond); 591 expr_finish(f.afterthought); 592 free(f.afterthought); 593 expr_finish(f.body); 594 free(f.body); 595 case let f: free_expr => 596 expr_finish(f); 597 free(f); 598 case let i: if_expr => 599 expr_finish(i.cond); 600 free(i.cond); 601 expr_finish(i.tbranch); 602 free(i.tbranch); 603 expr_finish(i.fbranch); 604 free(i.fbranch); 605 case let e: insert_expr => 606 expr_finish(e.object); 607 free(e.object); 608 expr_finish(e.value); 609 free(e.value); 610 expr_finish(e.length); 611 free(e.length); 612 case let l: len_expr => 613 expr_finish(l); 614 free(l); 615 case let m: match_expr => 616 free(m.label); 617 expr_finish(m.value); 618 free(m.value); 619 for (let i = 0z; i < len(m.cases); i += 1) { 620 free(m.cases[i].name); 621 type_finish(m.cases[i]._type); 622 free(m.cases[i]._type); 623 const exprs = m.cases[i].exprs; 624 for (let i = 0z; i < len(exprs); i += 1) { 625 expr_finish(exprs[i]); 626 free(exprs[i]); 627 }; 628 free(exprs); 629 }; 630 free(m.cases); 631 case let o: offset_expr => 632 expr_finish(o); 633 free(o); 634 case let p: propagate_expr => 635 expr_finish(p); 636 free(p); 637 case let r: return_expr => 638 expr_finish(r); 639 free(r); 640 case let s: size_expr => 641 type_finish(s); 642 free(s); 643 case let s: slice_expr => 644 expr_finish(s.object); 645 free(s.object); 646 expr_finish(s.start); 647 free(s.start); 648 expr_finish(s.end); 649 free(s.end); 650 case let s: switch_expr => 651 free(s.label); 652 expr_finish(s.value); 653 free(s.value); 654 for (let i = 0z; i < len(s.cases); i += 1) { 655 let opts = s.cases[i].options; 656 for (let j = 0z; j < len(opts); j += 1) { 657 expr_finish(opts[j]); 658 free(opts[j]); 659 }; 660 free(opts); 661 662 let exprs = s.cases[i].exprs; 663 for (let j = 0z; j < len(exprs); j += 1) { 664 expr_finish(exprs[j]); 665 free(exprs[j]); 666 }; 667 free(exprs); 668 }; 669 free(s.cases); 670 case let u: unarithm_expr => 671 expr_finish(u.operand); 672 free(u.operand); 673 case let v: variadic_expr => 674 match (v) { 675 case vastart_expr => void; 676 case let v: vaarg_expr => 677 expr_finish(v.ap); 678 free(v.ap); 679 type_finish(v._type); 680 free(v._type); 681 case let v: vaend_expr => 682 expr_finish(v); 683 free(v); 684 }; 685 case let y: yield_expr => 686 free(y.label); 687 expr_finish(y.value); 688 free(y.value); 689 }; 690 }; 691 692 fn struct_literal_finish(s: *struct_literal) void = { 693 ident_free(s.alias); 694 for (let i = 0z; i < len(s.fields); i += 1) { 695 match (s.fields[i]) { 696 case let v: struct_value => 697 free(v.name); 698 type_finish(v._type); 699 free(v._type); 700 expr_finish(v.init); 701 free(v.init); 702 case let c: *struct_literal => 703 struct_literal_finish(c); 704 free(c); 705 }; 706 }; 707 free(s.fields); 708 };