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