hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };