Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_Generic_Driver.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
47#ifndef COMPILER_GENERIC_DRIVER_H
48#define COMPILER_GENERIC_DRIVER_H
49
50#include <fstream>
51#include <sstream>
52#include <string>
53
54#include <Bytecode.H>
55#include <Compiler_Backend_C.H>
56#include <Compiler_Frontend.H>
61
62namespace Aleph {
69
72{
77 size_t arena_bytes_ = 0;
78
82
87
88 void append_error(const std::string &text)
89 {
90 errors_.append(text);
91 }
92
93 void record_text_artifact(const std::string &label, std::string text)
94 {
96 }
97
99 {
100 const auto &frontend_errors = frontend_->errors();
101 for (size_t i = 0; i < frontend_errors.size(); ++i)
102 errors_.append(frontend_errors.access(i));
103
104 const auto &frontend_warnings = frontend_->warnings();
105 for (size_t i = 0; i < frontend_warnings.size(); ++i)
107
108 const auto &frontend_artifacts = frontend_->artifacts();
109 for (size_t i = 0; i < frontend_artifacts.size(); ++i)
110 artifacts_.append(frontend_artifacts.access(i));
111 }
112
114 {
115 const auto *dx = frontend_->diagnostic_engine();
116 if (dx == nullptr)
117 return;
118
119 std::ostringstream out;
120 dx->render_plain(out);
121 record_text_artifact("diagnostics", out.str());
122 }
123
125 {
126 if (frontend_->find_artifact("imports.order") != nullptr)
127 return;
128
129 const auto &modules = frontend_->module_descriptors();
130 const auto &order = frontend_->module_merge_order();
131 if (modules.is_empty() or order.is_empty())
132 return;
133
134 record_text_artifact("imports.order", compiler_render_module_order(order, modules));
135 }
136
138 {
139 if (frontend_->find_artifact("modules.surface") != nullptr)
140 return;
141
142 const auto &metadata = frontend_->module_metadata();
143 if (metadata.is_empty())
144 return;
145
147 }
148
150 {
151 if (frontend_->find_artifact("modules.linkage") != nullptr)
152 return;
153
155 const auto &metadata = frontend_->module_metadata();
156 const auto &order = frontend_->module_merge_order();
157 if (descriptors.is_empty() or metadata.is_empty() or order.is_empty())
158 return;
159
162 }
163
165 {
166 if (frontend_->find_artifact("modules.binding") != nullptr)
167 return;
168
170 const auto &metadata = frontend_->module_metadata();
171 const auto &order = frontend_->module_merge_order();
172 if (descriptors.is_empty() or metadata.is_empty() or order.is_empty())
173 return;
174
176 const auto bindings = compiler_bind_module_surfaces(linkage);
177 record_text_artifact("modules.binding", compiler_render_module_bindings(bindings));
178 }
179
181 {
182 if (frontend_->find_artifact("modules.names") != nullptr)
183 return;
184
186 const auto &metadata = frontend_->module_metadata();
187 const auto &order = frontend_->module_merge_order();
188 if (descriptors.is_empty() or metadata.is_empty() or order.is_empty())
189 return;
190
192 const auto bindings = compiler_bind_module_surfaces(linkage);
193 const auto table = compiler_build_module_name_table(bindings);
195 }
196
198 {
199 if (frontend_->find_artifact("modules.semantic") != nullptr)
200 return;
201
203 const auto &metadata = frontend_->module_metadata();
204 const auto &order = frontend_->module_merge_order();
205 if (descriptors.is_empty() or metadata.is_empty() or order.is_empty())
206 return;
207
209 const auto bindings = compiler_bind_module_surfaces(linkage);
210 const auto table = compiler_build_module_name_table(bindings);
213 }
214
220
222 {
224 bytecode_module_ = lowering.lower_module(frontend_->ir_module());
225 record_text_artifact("bytecode",
227
228 if (bytecode_module_ == nullptr)
229 {
230 append_error("bytecode: null bytecode module produced by lowering");
231 return false;
232 }
233
236 }
237
244
260
262 {
263 if (run_output_.result.ok())
264 return;
265
266 std::string message = "run: HIR runtime execution failed";
268 {
269 message += ":";
270 if (not run_output_.result.error.code.empty())
272 if (not run_output_.result.error.message.empty())
273 {
274 if (not run_output_.result.error.code.empty())
275 message += " ";
277 }
278 }
280 }
281
296
297 static bool read_file_text(const std::string &path, std::string &out_text)
298 {
299 std::ifstream in(path);
300 if (not in)
301 return false;
302
303 std::ostringstream out;
304 out << in.rdbuf();
305 out_text = out.str();
306 return true;
307 }
308
309public:
322
325
331
334 {
335 return arena_bytes_;
336 }
337
354
356 bool bind_host_function(const std::string &name,
357 const Interpreter_Host_Function callback,
358 void *user_data = nullptr)
359 {
360 return runtime_.bind_host_function(name, callback, user_data);
361 }
362
366 {
367 clear();
369 return finalize(action);
370 if (not frontend_->parse())
371 return finalize(action);
373 return finalize(action);
374
375 if (not frontend_->analyze())
376 return finalize(action);
378 return finalize(action);
379
380 if (not frontend_->lower_hir())
381 {
382 append_error("hir: failed to lower frontend program to HIR");
383 return finalize(action);
384 }
386 return finalize(action);
387
389 {
392 return finalize(action);
393 }
394
395 if (not frontend_->lower_ir())
396 return finalize(action);
398 return finalize(action);
399
400 switch (action)
401 {
404 return finalize(action);
405
407 (void) emit_c();
408 return finalize(action);
409
415 return finalize(action);
416 }
417
418 append_error("driver: reached unreachable action dispatch");
419 return finalize(action);
420 }
421
425 {
427 for (size_t i = 0; i < paths.size(); ++i)
428 {
429 std::string text;
430 if (not read_file_text(paths.access(i), text))
431 {
432 clear();
433 append_error("driver: unable to read input file '" + paths.access(i) + "'");
434 return finalize(action);
435 }
436 inputs.append({paths.access(i), std::move(text)});
437 }
439 }
440
442 bool execute_source(const std::string &name,
443 const std::string &text,
445 {
447 inputs.append({name, text});
449 }
450
453 {
454 const auto *dx = frontend_->diagnostic_engine();
455 return errors_.is_empty() and (dx == nullptr or not dx->has_errors());
456 }
457
460 {
461 return *frontend_;
462 }
463
469
475
481
487
490 {
491 return errors_;
492 }
493
496 {
497 return warnings_;
498 }
499
505
507 [[nodiscard]] const Compiler_Driver_Artifact *find_artifact(std::string_view label) const noexcept
508 {
509 for (size_t i = artifacts_.size(); i > 0; --i)
510 if (artifacts_.access(i - 1).label == label)
511 return &artifacts_.access(i - 1);
512 return nullptr;
513 }
514
516 [[nodiscard]] std::string diagnostics_text() const
517 {
518 std::ostringstream out;
519 const auto *dx = frontend_->diagnostic_engine();
520 if (dx != nullptr)
521 dx->render_plain(out);
522 return out.str();
523 }
524};
525} // namespace Aleph
526
527#endif
Reusable bytecode format and lowering from Compiler_IR_Model.H.
Portable C backend that emits standalone C from Compiler_IR_Model.H.
Reusable interface for language frontends that plug into common drivers.
Reusable binding helpers for linked module surfaces.
Reusable linking helpers for module surfaces and direct imports.
Reusable per-module cache for top-level name resolution.
Reusable namespace-separated semantic environment for modules.
size_t size_t int32_t * out
Definition ca-c-api.h:120
Arena-backed ownership context for bytecode functions and modules.
Definition Bytecode.H:254
void reset() noexcept
Resets the arena and destroys all tracked objects.
Definition Bytecode.H:298
Lowers explicit IR into register-based bytecode.
Definition Bytecode.H:581
Abstract language frontend that can feed reusable drivers.
virtual bool analyze()=0
Runs semantic analysis on the parsed program.
virtual const Compiler_Type_Context * type_context() const noexcept=0
Returns the optional shared type context for dumps and backends.
virtual bool lower_hir()=0
Lowers the analyzed program into common HIR.
virtual const DynArray< std::string > & errors() const noexcept=0
Returns hard frontend-level errors outside the diagnostic engine.
virtual const Compiler_Driver_Artifact * find_artifact(std::string_view label) const noexcept=0
Finds one frontend artifact by exact label.
virtual const DynArray< Compiler_Driver_Artifact > & artifacts() const noexcept=0
Returns all frontend-produced artifacts from the last run.
virtual const DynArray< Compiler_Module_Descriptor > & module_descriptors() const noexcept
Returns parsed module descriptors for reusable import orchestration.
virtual void clear() noexcept=0
Clears all frontend-owned state from the previous run.
virtual bool load_sources(const DynArray< Compiler_Driver_Source > &inputs)=0
Registers the ordered input sources for the next run.
virtual const DynArray< size_t > & module_merge_order() const noexcept
Returns the dependency-first merge order from the last parse.
virtual const Compiler_IR_Module * ir_module() const noexcept=0
Returns the lowered IR module from the last run, when available.
virtual const Compiler_HIR_Module * hir_module() const noexcept=0
Returns the lowered HIR module from the last run, when available.
virtual const DynArray< Compiler_Module_Metadata > & module_metadata() const noexcept
Returns reusable metadata for the top-level surface of each module.
virtual bool lower_ir()=0
Lowers the analyzed program into common IR.
virtual const DynArray< std::string > & warnings() const noexcept=0
Returns non-fatal frontend-level warnings.
virtual Diagnostic_Engine * diagnostic_engine() noexcept=0
Returns the diagnostic engine populated by the frontend.
virtual bool parse()=0
Parses all previously loaded sources.
Reusable orchestration object built on top of Compiler_Frontend.
bool execute_sources(const DynArray< Compiler_Driver_Source > &inputs, const Compiler_Driver_Action action=Compiler_Driver_Action::Run)
Runs the pipeline over in-memory sources.
bool execute_files(const DynArray< std::string > &paths, const Compiler_Driver_Action action=Compiler_Driver_Action::Run)
Runs the pipeline over source files loaded from disk.
std::string diagnostics_text() const
Renders diagnostics from the frontend as plain text.
const Compiler_Frontend & frontend_impl() const noexcept
Returns the frontend used by this driver.
Compiler_Generic_Driver & operator=(const Compiler_Generic_Driver &)=delete
Compiler_Bytecode_Context bytecode_ctx_
const Compiler_Generic_Driver_Options & options() const noexcept
Returns the immutable driver configuration.
Compiler_Driver_Run_Output run_output_
const DynArray< Compiler_Driver_Artifact > & artifacts() const noexcept
Returns all recorded artifacts from the last run.
const DynArray< std::string > & errors() const noexcept
Returns non-diagnostic driver-level hard errors.
const DynArray< std::string > & warnings() const noexcept
Returns non-fatal driver-level warnings.
const Compiler_Driver_Artifact * find_artifact(std::string_view label) const noexcept
Finds one artifact by exact label.
void record_text_artifact(const std::string &label, std::string text)
Compiler_Bytecode_Module * bytecode_module_
bool bind_host_function(const std::string &name, const Interpreter_Host_Function callback, void *user_data=nullptr)
Binds one host function into the persistent runtime prelude.
const Compiler_Bytecode_Module * bytecode_module() const noexcept
Returns the lowered bytecode module from the last run, when available.
bool ok() const noexcept
Returns whether the last driver action finished successfully.
Compiler_C_Backend_Emission c_emission_
bool finalize(const Compiler_Driver_Action action)
const Compiler_C_Backend_Emission & c_emission() const noexcept
Returns the C emission payload from the last emit-c action.
void clear() noexcept
Clears all driver and frontend state while preserving host bindings.
DynArray< Compiler_Driver_Artifact > artifacts_
Compiler_Generic_Driver(const Compiler_Generic_Driver &)=delete
Compiler_Driver_Action last_action() const noexcept
Returns the last requested action.
void append_error(const std::string &text)
size_t arena_size() const noexcept
Returns the configured bytecode arena size.
Compiler_Generic_Driver_Options config_
static bool read_file_text(const std::string &path, std::string &out_text)
const Compiler_Driver_Run_Output & run_output() const noexcept
Returns the run summary from the last run action.
bool execute_source(const std::string &name, const std::string &text, const Compiler_Driver_Action action=Compiler_Driver_Action::Run)
Convenience overload for a single in-memory source.
Compiler_Generic_Driver(Compiler_Frontend &frontend_impl, const Compiler_Generic_Driver_Options &options={}, const size_t arena_size=1<< 20)
Builds one generic driver over a concrete frontend implementation.
void render_plain(std::ostream &out) const
Renders all diagnostics as deterministic plain text.
void clear() noexcept
Empties the container.
size_t size() const noexcept
Return the current dimension of array.
T & access(const size_t i) const noexcept
Fast access without checking allocation and bound_min_clock checking.
T & append()
Allocate a new entry to the end of array.
bool is_empty() const noexcept
Return true if the array is empty.
Structured runtime for executing typed HIR.
void set_diagnostics(Diagnostic_Engine *dx) noexcept
Sets the optional diagnostic sink for runtime failures.
bool bind_host_function(const std::string &name, const Interpreter_Host_Function callback, void *user_data=nullptr)
Defines one host function in the persistent prelude.
void reset() noexcept
Clears globals and the call stack while preserving host bindings.
Interpreter_Execution_Result evaluate_module(const Compiler_HIR_Module *module)
Evaluates one HIR module and leaves its globals installed.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::string render_messages(const DynArray< std::string > &errors, const DynArray< std::string > &warnings)
bool merge_report(const std::string &stage, const Report &report, DynArray< std::string > &errors, DynArray< std::string > &warnings)
std::string render_run_result(const Compiler_Driver_Run_Output &output)
void append_artifact(DynArray< Compiler_Driver_Artifact > &artifacts, const std::string &label, std::string text)
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Compiler_Driver_Action
High-level actions supported by compiler pipeline drivers.
@ Emit_C
Lower to IR and emit portable C.
@ IR
Stop after lowering to explicit IR.
@ Parse_Only
Stop after parsing and publish AST/frontend artifacts.
@ Run
Execute the lowered HIR module with Interpreter_Runtime.
@ Emit_Bytecode
Lower to IR and emit reusable bytecode.
@ Sema_Only
Stop after semantic analysis.
@ HIR
Stop after lowering to typed HIR.
Compiler_Module_Semantic_Environment compiler_build_module_semantic_environment(const Compiler_Module_Name_Table &table)
Builds one namespace-separated semantic environment from a name table.
void message(const char *file, int line, const char *format,...)
Print an informational message with file and line info.
Definition ahDefs.C:95
std::string compiler_render_module_metadata(const DynArray< Compiler_Module_Metadata > &modules)
Renders one deterministic text artifact for module metadata.
std::string compiler_render_module_semantic_environment(const Compiler_Module_Semantic_Environment &env)
Renders one deterministic text artifact for semantic environments.
and
Check uniqueness with explicit hash + equality functors.
std::string compiler_render_module_order(const DynArray< size_t > &order, const DynArray< Compiler_Module_Descriptor > &modules)
Renders one deterministic text artifact for a module order.
Compiler_Module_Name_Table compiler_build_module_name_table(const Compiler_Module_Binding_Result &bindings)
Builds one reusable per-module name table from bindings.
std::string compiler_dump_bytecode_module(const Compiler_Bytecode_Module *module, const Compiler_Type_Context *types=nullptr)
Dumps all lowered bytecode in one module deterministically.
Definition Bytecode.H:1081
std::string compiler_render_module_bindings(const Compiler_Module_Binding_Result &result)
Renders one deterministic text artifact for bound module names.
Compiler_Bytecode_Validation_Report validate_bytecode_module(const Compiler_Bytecode_Module &module)
Validates all bytecode functions in one module.
Definition Bytecode.H:900
Compiler_Module_Link_Result compiler_link_module_surfaces(const DynArray< Compiler_Module_Descriptor > &descriptors, const DynArray< Compiler_Module_Metadata > &metadata, const DynArray< size_t > &order)
Links direct-import module surfaces into visible top-level views.
Compiler_Module_Binding_Result compiler_bind_module_surfaces(const Compiler_Module_Link_Result &linkage)
Binds linked module surfaces into one deterministic name view.
std::string compiler_render_module_linkage(const Compiler_Module_Link_Result &result)
Renders one deterministic text artifact for linked module surfaces.
bool(*)(void *user_data, const DynArray< Interpreter_Value > &arguments, Interpreter_Value &result, Interpreter_Runtime_Error &error) Interpreter_Host_Function
Host callback signature used by runtime built-ins or embeddings.
std::string compiler_render_module_name_table(const Compiler_Module_Name_Table &table)
Renders one deterministic text artifact for cached module names.
std::string interpreter_dump_globals(const Interpreter_Runtime &runtime)
Dumps the globals currently installed in one runtime.
std::string interpreter_value_to_string(const Interpreter_Value &value)
Formats one runtime value deterministically for dumps and tests.
Compiler_C_Backend_Emission compiler_emit_c_module(const Compiler_IR_Module *module, const Compiler_C_Backend_Options &options={}, const Compiler_Type_Context *types=nullptr)
Convenience wrapper that emits one IR module to portable C.
Bytecode module sharing global slot layout with the source IR module.
Definition Bytecode.H:246
Result of one C backend emission request.
std::string source
Final generated C translation unit.
Options that control one C backend emission request.
Stable text artifact produced during one pipeline run.
Structured output of a run action.
std::string value_text
Stable rendering of the produced value.
std::string globals_text
Stable dump of the final globals environment.
Interpreter_Execution_Result result
Raw runtime result.
bool executed
Whether the current driver action actually executed code.
Configuration shared by all runs of Compiler_Generic_Driver.
Compiler_C_Backend_Options c_backend_options
Backend-C emission options used by emit-c.
Interpreter_Runtime_Options runtime_options
Runtime limits used by run.
Interpreter_Runtime_Error error
Structured runtime failure when flow == Runtime_Error.
Interpreter_Value value
Produced runtime value when relevant.
bool ok() const noexcept
Returns whether this result represents a runtime failure.
std::string code
Stable runtime code such as RUN004.
std::string message
Human-readable runtime message.
Runtime options for the HIR evaluator.