Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_MVP_Frontend.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
43#ifndef COMPILER_MVP_FRONTEND_H
44#define COMPILER_MVP_FRONTEND_H
45
46#include <sstream>
47#include <string>
48#include <string_view>
49#include <utility>
50
51#include <Compiler_Frontend.H>
55#include <Compiler_Parser.H>
56
57namespace Aleph {
64
67{
75 size_t arena_bytes = 0;
76
86
90
91 void append_error(const std::string &text)
92 {
93 errors_.append(text);
94 }
95
97 const std::string &code,
98 const std::string &message,
99 const std::string &note = "",
100 const std::string &help = "")
101 {
102 auto builder = diagnostics.error(span, message).code(code);
103 if (not note.empty())
104 builder.note(note);
105 if (not help.empty())
106 builder.help(help);
107 builder.emit();
108 }
109
110 void record_text_artifact(const std::string &label, std::string text)
111 {
113 }
114
115 size_t find_source_index(std::string_view name) const noexcept
116 {
117 for (size_t i = 0; i < source_names.size(); ++i)
118 if (source_names.access(i) == name)
119 return i;
120 return static_cast<size_t>(-1);
121 }
122
128
138
140 {
143 for (size_t i = 0; i < result.issues.size(); ++i)
144 {
145 const auto &issue = result.issues.access(i);
148 "DRV001",
149 "cannot resolve import '" + issue.dependency_name + "'",
150 "known sources must match import names exactly");
151 else
153 "DRV002",
154 "cyclic import involving '" + issue.module_name + "' and '"
155 + issue.dependency_name + "'",
156 "imports currently form one acyclic source-order graph");
157 }
158
159 for (size_t i = 0; i < result.order.size(); ++i)
160 merge_order_.append(result.order.access(i));
161
162 return result.valid and not diagnostics.has_errors();
163 }
164
166 {
168 merged_ast_->source_name = "<merged>";
169
172
173 for (size_t i = 0; i < merge_order_.size(); ++i)
174 {
175 const auto module_index = merge_order_.access(i);
176 const auto *module = parsed_modules.access(module_index);
177 if (module == nullptr)
178 continue;
179
180 if (not first_span.is_valid() and module->span.is_valid())
181 first_span = module->span;
182 if (module->span.is_valid())
183 last_span = module->span;
184
185 for (size_t j = 0; j < module->type_declarations.size(); ++j)
186 merged_ast_->type_declarations.append(module->type_declarations.access(j));
187 for (size_t j = 0; j < module->functions.size(); ++j)
188 merged_ast_->functions.append(module->functions.access(j));
189 for (size_t j = 0; j < module->statements.size(); ++j)
190 merged_ast_->statements.append(module->statements.access(j));
191 }
192
193 if (first_span.is_valid())
195 }
196
197public:
209
211 [[nodiscard]] const char *name() const noexcept override
212 {
213 return "mvp";
214 }
215
218 {
219 return arena_bytes;
220 }
221
227
228 void clear() noexcept override
229 {
230 parsed_modules.clear();
231 module_descriptors_.clear();
232 module_metadata_.clear();
236 artifacts_.clear();
237 errors_.clear();
239
240 merged_ast_ = nullptr;
241 hir_module_ = nullptr;
242 ir_module_ = nullptr;
243
244 typed.clear();
246 ast_ctx.reset();
247 hir_ctx.reset();
248 ir_ctx.reset();
250 }
251
253 {
254 if (inputs.is_empty())
255 {
256 append_error("frontend: no input sources were provided");
257 return false;
258 }
259
260 for (size_t i = 0; i < inputs.size(); ++i)
261 {
262 const auto &input = inputs.access(i);
263 if (find_source_index(input.name) != static_cast<size_t>(-1))
264 {
265 append_error("frontend: duplicate input source name '" + input.name + "'");
266 return false;
267 }
270 }
271
272 return true;
273 }
274
275 bool parse() override
276 {
277 parsed_modules.clear();
278 module_descriptors_.clear();
279 module_metadata_.clear();
280
281 for (size_t i = 0; i < source_file_ids.size(); ++i)
282 {
285 auto *module = parser.parse_module();
286 parsed_modules.append(module);
287
292 if (module != nullptr)
293 metadata.span = module->span;
294 if (module != nullptr)
295 for (size_t j = 0; j < module->imports.size(); ++j)
296 {
297 const auto *decl = module->imports.access(j);
298 if (decl == nullptr or decl->kind != Compiler_Import_Decl_Kind::Import)
299 continue;
300 descriptor.imports.append({decl->module_name, decl->module_name_span});
301 }
302
303 if (module != nullptr)
304 {
305 for (size_t j = 0; j < module->type_declarations.size(); ++j)
306 {
307 const auto *decl = module->type_declarations.access(j);
308 if (decl == nullptr)
309 continue;
310 metadata.exports.append(
311 {Compiler_Module_Export_Kind::Type, decl->name, decl->name_span});
312 }
313
314 for (size_t j = 0; j < module->functions.size(); ++j)
315 {
316 const auto *fn = module->functions.access(j);
317 if (fn == nullptr)
318 continue;
319 metadata.exports.append(
320 {Compiler_Module_Export_Kind::Function, fn->name, fn->name_span});
321 }
322
323 for (size_t j = 0; j < module->statements.size(); ++j)
324 {
325 const auto *stmt = module->statements.access(j);
326 if (stmt == nullptr or stmt->kind != Compiler_Stmt_Kind::Let)
327 continue;
328 const auto *let_stmt = static_cast<const Compiler_Let_Stmt *>(stmt);
329 metadata.exports.append(
331 }
332 }
333
334 module_descriptors_.append(std::move(descriptor));
335 module_metadata_.append(std::move(metadata));
336 }
337
339 {
341 for (size_t i = 0; i < parsed_modules.size(); ++i)
343 }
344
347 return not diagnostics.has_errors();
348 }
349
350 bool analyze() override
351 {
354 return not diagnostics.has_errors();
355 }
356
364
365 bool lower_ir() override
366 {
368 ir_module_ = lowering.lower_module(hir_module_);
370
371 if (ir_module_ == nullptr)
372 {
373 append_error("ir: null IR module produced by lowering");
374 return false;
375 }
376
377 const auto report = validate_ir_module(*ir_module_);
379 }
380
382 {
383 return &diagnostics;
384 }
385
387 {
388 return &diagnostics;
389 }
390
392 {
393 return &typed.type_context();
394 }
395
400
405
407 {
408 return hir_module_;
409 }
410
412 {
413 return ir_module_;
414 }
415
420
422 {
423 return merge_order_;
424 }
425
430
432 {
433 return artifacts_;
434 }
435
436 [[nodiscard]] const Compiler_Driver_Artifact *find_artifact(std::string_view label) const noexcept override
437 {
438 for (size_t i = artifacts_.size(); i > 0; --i)
439 if (artifacts_.access(i - 1).label == label)
440 return &artifacts_.access(i - 1);
441 return nullptr;
442 }
443
445 {
446 return errors_;
447 }
448
450 {
451 return warnings_;
452 }
453
455 [[nodiscard]] std::string diagnostics_text() const
456 {
457 std::ostringstream out;
459 return out.str();
460 }
461};
462} // namespace Aleph
463
464#endif
Reusable interface for language frontends that plug into common drivers.
Lowering from the current MVP typed AST into the reusable HIR model.
Lowering from the current MVP HIR into the reusable explicit IR model.
Reusable source-name module dependency resolution helpers.
Recursive-descent parser for the compiler-support MVP grammar.
size_t size_t int32_t * out
Definition ca-c-api.h:120
Arena-backed ownership context for AST nodes.
T * make(Args &&...args)
Allocates and constructs an AST node of type T.
void reset() noexcept
Reclaims all memory and destroys managed nodes.
Abstract language frontend that can feed reusable drivers.
Arena-backed ownership context for HIR nodes.
void reset() noexcept
Destroys all tracked objects and rewinds the arena.
Lowers the MVP typed AST into HIR.
Arena-backed ownership context for IR nodes.
void reset() noexcept
Destroys all tracked objects and rewinds the arena.
Lowers typed HIR into explicit-value IR.
Compiler_Frontend implementation backed by the current MVP language stack.
DynArray< std::string > errors_
std::string diagnostics_text() const
Renders accumulated diagnostics as plain text.
DynArray< std::string > warnings_
bool lower_hir() override
Lowers the analyzed program into common HIR.
const DynArray< Compiler_Module_Descriptor > & module_descriptors() const noexcept override
Returns parsed module descriptors for reusable import orchestration.
DynArray< Compiler_Module_Descriptor > module_descriptors_
Compiler_MVP_Frontend_Options config
bool parse() override
Parses all previously loaded sources.
bool lower_ir() override
Lowers the analyzed program into common IR.
const Compiler_MVP_Frontend_Options & options() const noexcept
Returns the immutable frontend configuration.
const Compiler_Type_Context * type_context() const noexcept override
Returns the optional shared type context for dumps and backends.
Diagnostic_Engine * diagnostic_engine() noexcept override
Returns the diagnostic engine populated by the frontend.
bool load_sources(const DynArray< Compiler_Driver_Source > &inputs) override
Registers the ordered input sources for the next run.
DynArray< std::string > source_names
DynArray< Compiler_Module_Metadata > module_metadata_
size_t arena_size() const noexcept
Returns the configured shared arena size.
const DynArray< Compiler_Module * > & parsed_ast_modules() const noexcept
const Compiler_HIR_Module * hir_module() const noexcept override
Returns the lowered HIR module from the last run, when available.
const DynArray< std::string > & warnings() const noexcept override
Returns non-fatal frontend-level warnings.
bool analyze() override
Runs semantic analysis on the parsed program.
const Compiler_Driver_Artifact * find_artifact(std::string_view label) const noexcept override
Finds one frontend artifact by exact label.
const Compiler_IR_Module * ir_module() const noexcept override
Returns the lowered IR module from the last run, when available.
const DynArray< std::string > & errors() const noexcept override
Returns hard frontend-level errors outside the diagnostic engine.
void clear() noexcept override
Clears all frontend-owned state from the previous run.
Compiler_Typed_Semantic_Analyzer typed
const Compiler_Module * merged_ast_module() const noexcept
const Diagnostic_Engine * diagnostic_engine() const noexcept override
Returns the diagnostic engine populated by the frontend.
DynArray< Compiler_Driver_Artifact > artifacts_
void append_error(const std::string &text)
const DynArray< size_t > & module_merge_order() const noexcept override
Returns the dependency-first merge order from the last parse.
size_t find_source_index(std::string_view name) const noexcept
void record_text_artifact(const std::string &label, std::string text)
void emit_driver_diagnostic(const Source_Span &span, const std::string &code, const std::string &message, const std::string &note="", const std::string &help="")
DynArray< Compiler_Module * > parsed_modules
const char * name() const noexcept override
Returns the stable frontend name.
const DynArray< Compiler_Driver_Artifact > & artifacts() const noexcept override
Returns all frontend-produced artifacts from the last run.
DynArray< Source_File_Id > source_file_ids
Compiler_MVP_Frontend(const Compiler_MVP_Frontend_Options &options={}, const size_t arena_size=1<< 20)
Constructs the reference MVP frontend.
const DynArray< Compiler_Module_Metadata > & module_metadata() const noexcept override
Returns reusable metadata for the top-level surface of each module.
Recursive-descent parser that produces an AST in Compiler_Ast_Context.
Context owning all compiler type nodes.
Inference-oriented semantic pass for the MVP compiler front-end.
void analyze_module(const Compiler_Module *module)
Runs the typed semantic analysis for module.
void clear() noexcept
Clears all inferred state and substitutions.
std::string dump_inference() const
Dumps inferred function, parameter, and binding types.
const Compiler_Type_Context & type_context() const noexcept
Returns the internal type context.
Diagnostic_Builder & code(const std::string &value)
Sets the stable diagnostic code.
size_t emit() const noexcept
Finalizes the builder and returns the diagnostic index.
Diagnostic_Builder & help(const std::string &msg)
Appends a help line.
Diagnostic_Builder & note(const std::string &msg)
Appends a note line.
Diagnostic accumulator and renderer.
void clear() noexcept
Removes all accumulated diagnostics and resets counters.
void render_plain(std::ostream &out) const
Renders all diagnostics as deterministic plain text.
bool has_errors() const noexcept
Returns whether any error or fatal diagnostic was emitted.
Diagnostic_Builder error(const Source_Span &span, const std::string &msg)
Starts an error diagnostic.
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.
Stores source files and resolves offsets into human-readable data.
Definition ah-source.H:184
Source_File_Id add_virtual_file(const std::string &name, const std::string &text)
Registers an in-memory source file.
Definition ah-source.H:258
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 artifact_label(const std::string &prefix, const size_t index, const std::string &name)
bool merge_report(const std::string &stage, const Report &report, DynArray< std::string > &errors, DynArray< std::string > &warnings)
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
std::string compiler_dump_module(const Compiler_Module *module)
Dumps a parsed module in a deterministic text format.
Source_Span compiler_merge_spans(const Source_Span &lhs, const Source_Span &rhs) noexcept
Merges two spans from the same source file.
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_dump_ir_module(const Compiler_IR_Module *module, const Compiler_Type_Context *types=nullptr)
Dumps all lowered IR in one module deterministically.
@ Import
One concrete import "name"; declaration.
@ Let
Variable declaration and optional initialization.
Compiler_IR_Validation_Report validate_ir_module(const Compiler_IR_Module &module)
Validates all functions in one lowered IR module.
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_Resolution_Result compiler_resolve_module_order(const DynArray< Compiler_Module_Descriptor > &modules)
Resolves one dependency-first order for exact-name module imports.
std::string code(Node *root)
Compute a string with the Lukasiewicz`s word of a tree.
std::string compiler_dump_hir_module(const Compiler_HIR_Module *module, const Compiler_Type_Context &types)
Dumps one HIR module in a deterministic text format.
Source_Span span
Source region covered by this node.
Stable text artifact produced during one pipeline run.
Lowered IR module with shared global slots and functions.
Node representing a local variable binding.
Options used by the MVP frontend adapter.
Compiler_Parser_Options parser_options
Parser configuration used for every parsed file.
Compiler_Typed_Semantic_Options typed_semantic_options
Typed semantic options shared by the frontend.
One module descriptor consumed by the reusable resolver.
std::string name
Stable module/source name.
Reusable metadata describing one parsed or analyzed module surface.
std::string name
Stable module/source name.
Node representing a complete translation unit or module.
std::string source_name
User-facing source name that produced the module.
DynArray< Compiler_Type_Decl * > type_declarations
Top-level type declarations.
DynArray< Compiler_Stmt * > statements
Optional top-level code.
DynArray< Compiler_Function_Decl * > functions
Top-level function definitions.
Parser configuration knobs for the MVP grammar.
Options controlling the typed semantic pass.
Half-open byte range inside a source file.
Definition ah-source.H:100