decl.ha (2145B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use hare::lex; 5 6 // A constant declaration. 7 // 8 // def foo: int = 0; 9 export type decl_const = struct { 10 ident: ident, 11 _type: nullable *_type, 12 init: *expr, 13 }; 14 15 // A global declaration. 16 // 17 // let foo: int = 0; 18 // const foo: int = 0; 19 export type decl_global = struct { 20 is_const: bool, 21 is_threadlocal: bool, 22 symbol: str, 23 ident: ident, 24 _type: nullable *_type, 25 init: nullable *expr, 26 }; 27 28 // A type declaration. 29 // 30 // type foo = int; 31 export type decl_type = struct { 32 ident: ident, 33 _type: *_type, 34 }; 35 36 // Attributes applicable to a function declaration. 37 export type fndecl_attr = enum { 38 NONE, 39 FINI, 40 INIT, 41 TEST, 42 }; 43 44 // A function declaration. 45 // 46 // fn main() void = void; 47 export type decl_func = struct { 48 symbol: str, 49 ident: ident, 50 prototype: *_type, 51 body: nullable *expr, 52 attrs: fndecl_attr, 53 }; 54 55 // A Hare declaration. 56 export type decl = struct { 57 exported: bool, 58 start: lex::location, 59 end: lex::location, 60 decl: ([]decl_const | []decl_global | []decl_type | decl_func | 61 assert_expr), 62 63 // Only valid if the lexer has comments enabled 64 docs: str, 65 }; 66 67 // Frees resources associated with a declaration. 68 export fn decl_finish(d: decl) void = { 69 free(d.docs); 70 match (d.decl) { 71 case let g: []decl_global => 72 for (let i = 0z; i < len(g); i += 1) { 73 free(g[i].symbol); 74 ident_free(g[i].ident); 75 type_finish(g[i]._type); 76 free(g[i]._type); 77 expr_finish(g[i].init); 78 free(g[i].init); 79 }; 80 free(g); 81 case let t: []decl_type => 82 for (let i = 0z; i < len(t); i += 1) { 83 ident_free(t[i].ident); 84 type_finish(t[i]._type); 85 free(t[i]._type); 86 }; 87 free(t); 88 case let f: decl_func => 89 free(f.symbol); 90 ident_free(f.ident); 91 type_finish(f.prototype); 92 free(f.prototype); 93 expr_finish(f.body); 94 free(f.body); 95 case let c: []decl_const => 96 for (let i = 0z; i < len(c); i += 1) { 97 ident_free(c[i].ident); 98 type_finish(c[i]._type); 99 free(c[i]._type); 100 expr_finish(c[i].init); 101 free(c[i].init); 102 }; 103 free(c); 104 case let e: assert_expr => 105 expr_finish(e.cond); 106 free(e.cond); 107 expr_finish(e.message); 108 free(e.message); 109 }; 110 };