1use crate::chunk::{Chunk, CompiledFunction};
4
5pub use harn_kernel::compiler::HARN_DISABLE_OPTIMIZATIONS_ENV;
6pub use harn_kernel::{CompileError, CompilerOptions};
7
8#[derive(Clone)]
9pub struct CompiledCallableEntry {
10 pub(crate) bootstrap: Chunk,
11 pub(crate) has_fixture: bool,
12 pub(crate) fixture_expects_harness: bool,
13 pub(crate) expects_harness: bool,
14}
15
16pub struct Compiler {
17 inner: harn_kernel::Compiler,
18}
19
20impl Compiler {
21 pub fn new() -> Self {
22 install_native_builtin_contracts();
23 Self {
24 inner: harn_kernel::Compiler::new(),
25 }
26 }
27
28 pub fn new_trusted_host_dispatch() -> Self {
29 install_native_builtin_contracts();
30 Self {
31 inner: harn_kernel::Compiler::new_trusted_host_dispatch(),
32 }
33 }
34
35 pub fn with_options(options: CompilerOptions) -> Self {
36 install_native_builtin_contracts();
37 Self {
38 inner: harn_kernel::Compiler::with_options(options),
39 }
40 }
41
42 pub fn with_imported_enum_candidates(
43 self,
44 candidates: impl IntoIterator<Item = String>,
45 ) -> Self {
46 Self {
47 inner: self.inner.with_imported_enum_candidates(candidates),
48 }
49 }
50
51 pub fn compile(self, program: &[harn_parser::SNode]) -> Result<Chunk, CompileError> {
52 self.inner.compile(program).map(Chunk::from_portable)
53 }
54
55 pub fn compile_named(
56 self,
57 program: &[harn_parser::SNode],
58 name: &str,
59 ) -> Result<Chunk, CompileError> {
60 self.inner
61 .compile_named(program, name)
62 .map(Chunk::from_portable)
63 }
64
65 pub fn compile_named_pipeline_entry(
66 self,
67 program: &[harn_parser::SNode],
68 name: &str,
69 fixture: Option<&str>,
70 ) -> Result<CompiledCallableEntry, CompileError> {
71 self.inner
72 .compile_named_pipeline_entry(program, name, fixture)
73 .map(convert_entry)
74 }
75
76 pub fn compile_named_function_entry(
77 self,
78 program: &[harn_parser::SNode],
79 name: &str,
80 ) -> Result<CompiledCallableEntry, CompileError> {
81 self.inner
82 .compile_named_function_entry(program, name)
83 .map(convert_entry)
84 }
85
86 pub fn prepare_module_context(&mut self, program: &[harn_parser::SNode]) {
87 self.inner.prepare_module_context(program);
88 }
89
90 pub fn add_imported_enum_candidates(&mut self, candidates: impl IntoIterator<Item = String>) {
91 self.inner.add_imported_enum_candidates(candidates);
92 }
93
94 pub fn compile_module_init(
95 self,
96 context: &[harn_parser::SNode],
97 init_nodes: &[harn_parser::SNode],
98 imported_enums: &[String],
99 ) -> Result<Chunk, CompileError> {
100 self.inner
101 .compile_module_init(context, init_nodes, imported_enums)
102 .map(Chunk::from_portable)
103 }
104
105 pub fn compile_struct_constructor(
106 &self,
107 name: &str,
108 fields: &[harn_parser::StructField],
109 ) -> Result<CompiledFunction, CompileError> {
110 self.inner
111 .compile_struct_constructor(name, fields)
112 .map(CompiledFunction::from_portable)
113 }
114
115 pub fn compile_pipeline_callable(
116 &self,
117 program: &[harn_parser::SNode],
118 name: &str,
119 params: &[harn_parser::TypedParam],
120 body: &[harn_parser::SNode],
121 extends: Option<&str>,
122 ) -> Result<CompiledFunction, CompileError> {
123 self.inner
124 .compile_pipeline_callable(program, name, params, body, extends)
125 .map(CompiledFunction::from_portable)
126 }
127
128 pub fn compile_fn_body(
129 &mut self,
130 type_params: &[harn_parser::TypeParam],
131 params: &[harn_parser::TypedParam],
132 body: &[harn_parser::SNode],
133 source_file: Option<String>,
134 ) -> Result<CompiledFunction, CompileError> {
135 self.inner
136 .compile_fn_body(type_params, params, body, source_file)
137 .map(CompiledFunction::from_portable)
138 }
139
140 pub fn compile_public_type_schema_initializers(
141 program: &[harn_parser::SNode],
142 source_file: Option<String>,
143 ) -> Result<Option<Chunk>, CompileError> {
144 harn_kernel::Compiler::compile_public_type_schema_initializers(program, source_file)
145 .map(|chunk| chunk.map(Chunk::from_portable))
146 }
147
148 pub fn collect_type_aliases(&mut self, program: &[harn_parser::SNode]) {
149 self.inner.collect_type_aliases(program);
150 }
151
152 pub fn expand_alias(&self, ty: &harn_parser::TypeExpr) -> harn_parser::TypeExpr {
153 self.inner.expand_alias(ty)
154 }
155
156 pub fn type_expr_to_schema_value(type_expr: &harn_parser::TypeExpr) -> Option<crate::VmValue> {
157 harn_kernel::Compiler::type_expr_to_schema_value(type_expr).map(portable_value_to_vm)
158 }
159}
160
161fn install_native_builtin_contracts() {
162 harn_builtin_registry::install_builtin_manifest(crate::stdlib::all_builtin_manifest());
163}
164
165impl Default for Compiler {
166 fn default() -> Self {
167 Self::new()
168 }
169}
170
171fn convert_entry(entry: harn_kernel::CompiledCallableEntry) -> CompiledCallableEntry {
172 CompiledCallableEntry {
173 bootstrap: Chunk::from_portable(entry.bootstrap),
174 has_fixture: entry.has_fixture,
175 fixture_expects_harness: entry.fixture_expects_harness,
176 expects_harness: entry.expects_harness,
177 }
178}
179
180fn portable_value_to_vm(value: harn_kernel::value::VmValue) -> crate::VmValue {
181 match value {
182 harn_kernel::value::VmValue::Int(value) => crate::VmValue::Int(value),
183 harn_kernel::value::VmValue::Float(value) => crate::VmValue::Float(value),
184 harn_kernel::value::VmValue::String(value) => crate::VmValue::string(value),
185 harn_kernel::value::VmValue::Bool(value) => crate::VmValue::Bool(value),
186 harn_kernel::value::VmValue::Nil => crate::VmValue::Nil,
187 harn_kernel::value::VmValue::Duration(value) => crate::VmValue::Duration(value),
188 harn_kernel::value::VmValue::List(values) => crate::VmValue::List(std::sync::Arc::new(
189 values.iter().cloned().map(portable_value_to_vm).collect(),
190 )),
191 harn_kernel::value::VmValue::Dict(entries) => crate::VmValue::dict(
192 entries
193 .iter()
194 .map(|(key, value)| (key.clone(), portable_value_to_vm(value.clone()))),
195 ),
196 }
197}