harn_kernel/compiler/
entry.rs1use std::sync::Arc;
2
3use harn_parser::{Node, SNode, TypedParam};
4
5use crate::chunk::{CompiledFunction, Op};
6
7use super::error::CompileError;
8use super::yield_scan::body_contains_yield;
9use super::Compiler;
10
11impl Compiler {
12 pub(super) fn compile_top_level_declarations(
13 &mut self,
14 program: &[SNode],
15 ) -> Result<(), CompileError> {
16 for node in program {
20 if !harn_parser::lexical::is_deferred_module_declaration(node) {
21 self.compile_discarded_stmt(node)?;
22 }
23 }
24 for node in program {
25 let inner_kind = match &node.node {
26 Node::AttributedDecl { inner, .. } => &inner.node,
27 other => other,
28 };
29 match inner_kind {
30 Node::EvalPackDecl {
31 binding_name,
32 pack_id,
33 fields,
34 body,
35 summarize,
36 ..
37 } => self.compile_eval_pack_decl(
38 binding_name,
39 pack_id,
40 fields,
41 body,
42 summarize,
43 false,
44 )?,
45 Node::FnDecl { .. }
46 | Node::ToolDecl { .. }
47 | Node::SkillDecl { .. }
48 | Node::ImplBlock { .. }
49 | Node::StructDecl { .. }
50 | Node::EnumDecl { .. }
51 | Node::InterfaceDecl { .. } => self.compile_node(node)?,
52 Node::TypeDecl { .. } => {}
53 _ => {}
54 }
55 }
56 Ok(())
57 }
58
59 pub fn compile_fn_body(
62 &mut self,
63 type_params: &[harn_parser::TypeParam],
64 params: &[TypedParam],
65 body: &[SNode],
66 source_file: Option<String>,
67 ) -> Result<CompiledFunction, CompileError> {
68 let mut compiler = self.nested_body();
69 compiler.enum_names = self.enum_names.clone();
70 compiler.enum_variant_owners = self.enum_variant_owners.clone();
71 compiler.imported_enum_candidates = self.imported_enum_candidates.clone();
72 compiler.imported_enum_candidates_authoritative =
73 self.imported_enum_candidates_authoritative;
74 compiler.interface_methods = self.interface_methods.clone();
75 compiler.type_aliases = self.type_aliases.clone();
76 compiler.struct_layouts = self.struct_layouts.clone();
77 compiler.declare_param_slots(params);
78 compiler.record_param_types(params);
79 compiler.emit_default_preamble(params)?;
80 compiler.emit_type_checks(params);
81 let is_generator = body_contains_yield(body);
82 compiler.seed_captured_idents(body);
83 compiler.compile_block(body)?;
84 compiler.chunk.emit(Op::Nil, 0);
85 compiler.chunk.emit(Op::Return, 0);
86 compiler.chunk.source_file = source_file;
87 let param_slots = compiler.compile_param_slots(params);
88 let has_runtime_type_checks =
89 CompiledFunction::has_runtime_type_checks_for_params(¶m_slots);
90 super::ensure_chunk_addressable(&compiler.chunk, "function body", self.line)?;
91 Ok(CompiledFunction {
92 name: String::new(),
93 type_params: type_params.iter().map(|param| param.name.clone()).collect(),
94 nominal_type_names: compiler.nominal_type_names(),
95 params: param_slots,
96 default_start: TypedParam::default_start(params),
97 chunk: Arc::new(compiler.chunk),
98 is_generator,
99 is_stream: false,
100 has_rest_param: false,
101 has_runtime_type_checks,
102 })
103 }
104}