hare

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

scan.ha (1794B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use hare::ast;
      5 use hare::types;
      6 
      7 // The scan phase determines the types of all declarations in the unit, and
      8 // handles forward references, so that the next phase (validate) is simplified.
      9 fn scan(ctx: *context, subunits: const []ast::subunit) (void | error) = {
     10 	for (let i = 0z; i < len(subunits); i += 1) {
     11 		let subunit = &subunits[i];
     12 		assert(len(subunit.imports) == 0); // TODO
     13 
     14 		scope_push(ctx, scope_class::SUBUNIT);
     15 		for (let j = 0z; j < len(subunit.decls); j += 1) {
     16 			let decl = &subunit.decls[j];
     17 			match (scan_decl(ctx, decl)) {
     18 			case void => void;
     19 			case types::deferred =>
     20 				abort(); // TODO
     21 			case error =>
     22 				abort(); // TODO
     23 			};
     24 		};
     25 		scope_pop(ctx);
     26 	};
     27 };
     28 
     29 fn scan_decl(
     30 	ctx: *context,
     31 	decl: *ast::decl,
     32 ) (void | types::deferred | error) = {
     33 	// TODO: match on &decl.decl
     34 	match (decl.decl) {
     35 	case let co: []ast::decl_const =>
     36 		abort(); // TODO
     37 	case let gl: []ast::decl_global =>
     38 		abort(); // TODO
     39 	case let ty: []ast::decl_type =>
     40 		abort(); // TODO
     41 	case let fu: ast::decl_func =>
     42 		return scan_func(ctx, decl, &fu);
     43 	case let ex: ast::assert_expr =>
     44 		abort(); // TODO
     45 	};
     46 };
     47 
     48 fn scan_func(
     49 	ctx: *context,
     50 	decl: *ast::decl,
     51 	func: *ast::decl_func,
     52 ) (void | types::deferred | error) = {
     53 	assert(func.attrs & ast::fndecl_attr::TEST == 0); // TODO
     54 	const fntype = match (types::lookup(ctx.store, func.prototype)) {
     55 	case let err: types::error =>
     56 		return err;
     57 	case types::deferred =>
     58 		return types::deferred;
     59 	case let fntype: const *types::_type =>
     60 		yield fntype;
     61 	};
     62 	scope_insert(ctx, object {
     63 		kind = object_kind::DECL,
     64 		// TODO: Add namespace to ident
     65 		ident = ast::ident_dup(func.ident),
     66 		name = ast::ident_dup(func.ident),
     67 		_type = fntype,
     68 		...
     69 	});
     70 };