Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_HIR_Lowering_MVP.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
41#ifndef COMPILER_HIR_LOWERING_MVP_H
42#define COMPILER_HIR_LOWERING_MVP_H
43
44#include <Compiler_HIR_Model.H>
45#include <Compiler_Typed_Sema.H>
46
47namespace Aleph {
50{
53
55 {
56 return typed != nullptr ? typed->type_context().invalid_type() : 0;
57 }
58
59 Compiler_Type_Id expr_type(const Compiler_Expr *expr) const noexcept
60 {
61 if (typed == nullptr or expr == nullptr)
62 return invalid_type();
63
64 const auto ty = typed->inferred_type(expr);
65 return ty != 0 ? ty : invalid_type();
66 }
67
69 {
70 if (typed == nullptr or function == nullptr)
71 return invalid_type();
72
73 const auto ty = typed->function_type(function);
74 return ty != 0 ? ty : invalid_type();
75 }
76
78 {
79 if (expr == nullptr)
81
82 switch (expr->kind)
83 {
85 return hir->make<Compiler_HIR_Invalid_Expr>(expr_type(expr), expr->span);
86
88 return lower_expr(static_cast<const Compiler_Grouping_Expr *>(expr)->inner);
89
91 {
92 const auto *node = static_cast<const Compiler_Identifier_Expr *>(expr);
93 return hir->make<Compiler_HIR_Variable_Expr>(node->name, expr_type(expr), node->name_span);
94 }
95
97 {
98 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
100 expr_type(expr),
101 node->lexeme,
102 node->span);
103 }
104
106 {
107 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
109 expr_type(expr),
110 node->lexeme,
111 node->span);
112 }
113
115 {
116 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
118 expr_type(expr),
119 node->lexeme,
120 node->span);
121 }
122
124 {
125 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
127 expr_type(expr),
128 node->bool_value ? "true" : "false",
129 node->span,
130 node->bool_value);
131 }
132
134 {
135 const auto *node = static_cast<const Compiler_Unary_Expr *>(expr);
137 expr_type(expr),
138 node->operator_span,
139 lower_expr(node->operand));
140 }
141
143 {
144 const auto *node = static_cast<const Compiler_Binary_Expr *>(expr);
145 return hir->make<Compiler_HIR_Binary_Expr>(lower_expr(node->left),
147 expr_type(expr),
148 node->operator_span,
149 lower_expr(node->right));
150 }
151
153 {
154 const auto *node = static_cast<const Compiler_Call_Expr *>(expr);
155 auto *call = hir->make<Compiler_HIR_Call_Expr>(lower_expr(node->callee),
156 expr_type(expr),
157 node->lparen_span,
158 node->rparen_span);
159 for (size_t i = 0; i < node->arguments.size(); ++i)
160 call->arguments.append(lower_expr(node->arguments.access(i)));
161 return call;
162 }
163 }
164
166 }
167
169 {
170 if (stmt == nullptr)
172
173 switch (stmt->kind)
174 {
176 return hir->make<Compiler_HIR_Invalid_Stmt>(stmt->span);
177
180 lower_expr(static_cast<const Compiler_Expr_Stmt *>(stmt)->expr), stmt->span);
181
183 {
184 const auto *node = static_cast<const Compiler_Let_Stmt *>(stmt);
185 Compiler_Type_Id binding_type = invalid_type();
186 if (typed != nullptr)
187 {
188 const auto ty = typed->let_type(node);
189 binding_type = ty != 0 ? ty : invalid_type();
190 }
191 return hir->make<Compiler_HIR_Let_Stmt>(node->name,
192 binding_type,
193 node->name_span,
194 node->initializer != nullptr
195 ? lower_expr(node->initializer)
196 : nullptr,
197 node->span);
198 }
199
201 {
202 const auto *node = static_cast<const Compiler_Return_Stmt *>(stmt);
203 return hir->make<Compiler_HIR_Return_Stmt>(node->value != nullptr ? lower_expr(node->value)
204 : nullptr,
205 node->span);
206 }
207
209 {
210 const auto *node = static_cast<const Compiler_Block_Stmt *>(stmt);
211 auto *block = hir->make<Compiler_HIR_Block_Stmt>(node->lbrace_span, node->rbrace_span);
212 for (size_t i = 0; i < node->statements.size(); ++i)
213 block->statements.append(lower_stmt(node->statements.access(i)));
214 block->span = node->span;
215 return block;
216 }
217
219 {
220 const auto *node = static_cast<const Compiler_If_Stmt *>(stmt);
221 return hir->make<Compiler_HIR_If_Stmt>(lower_expr(node->condition),
222 lower_stmt(node->then_branch),
223 lower_stmt(node->else_branch),
224 node->if_span,
225 node->else_span);
226 }
227
229 {
230 const auto *node = static_cast<const Compiler_While_Stmt *>(stmt);
231 return hir->make<Compiler_HIR_While_Stmt>(lower_expr(node->condition),
232 lower_stmt(node->body),
233 node->keyword_span);
234 }
235
237 return hir->make<Compiler_HIR_Break_Stmt>(stmt->span);
238
240 return hir->make<Compiler_HIR_Continue_Stmt>(stmt->span);
241 }
242
243 return hir->make<Compiler_HIR_Invalid_Stmt>(stmt->span);
244 }
245
246public:
256
259 {
260 if (function == nullptr)
261 return nullptr;
262
264 function->name, function_type(function), function->name_span, nullptr, function->span);
265 for (size_t i = 0; i < function->parameters.size(); ++i)
266 {
267 const auto &param = function->parameters.access(i);
268 Compiler_Type_Id type_id = invalid_type();
269 if (typed != nullptr)
270 {
271 const auto ty = typed->parameter_type(function, i);
272 type_id = ty != 0 ? ty : invalid_type();
273 }
274 hir_function->parameters.append({param.name, param.span, type_id});
275 }
276
277 auto *lowered_body = lower_stmt(function->body);
279 hir_function->body = static_cast<Compiler_HIR_Block_Stmt *>(lowered_body);
280 else
281 hir_function->body = nullptr;
282 hir_function->span = function->span;
283 return hir_function;
284 }
285
288 {
289 if (module == nullptr)
290 return nullptr;
291
292 auto *hir_module = hir->make<Compiler_HIR_Module>(module->span);
293 for (size_t i = 0; i < module->functions.size(); ++i)
294 hir_module->functions.append(lower_function(module->functions.access(i)));
295 for (size_t i = 0; i < module->statements.size(); ++i)
296 hir_module->statements.append(lower_stmt(module->statements.access(i)));
297 return hir_module;
298 }
299};
300} // namespace Aleph
301
302#endif
Reusable typed high-level IR model independent from any concrete frontend.
Typed semantic pass connecting the AST, the name pass, and type constraints.
Arena-backed ownership context for HIR nodes.
T * make(Args &&...args)
Allocates and constructs one HIR object.
Lowers the MVP typed AST into HIR.
Compiler_HIR_Function * lower_function(const Compiler_Function_Decl *function)
Lowers one function declaration into HIR.
Compiler_HIR_Stmt * lower_stmt(const Compiler_Stmt *stmt)
Compiler_HIR_Module * lower_module(const Compiler_Module *module)
Lowers one module into HIR.
Compiler_HIR_Lowering(Compiler_HIR_Context &context, const Compiler_Typed_Semantic_Analyzer &analysis) noexcept
Constructs a lowering helper.
Compiler_Type_Id invalid_type() const noexcept
Compiler_HIR_Expr * lower_expr(const Compiler_Expr *expr)
const Compiler_Typed_Semantic_Analyzer * typed
Compiler_Type_Id function_type(const Compiler_Function_Decl *function) const noexcept
Compiler_Type_Id expr_type(const Compiler_Expr *expr) const noexcept
Compiler_Type_Id invalid_type() const noexcept
Returns the preloaded Invalid type id.
Inference-oriented semantic pass for the MVP compiler front-end.
Compiler_Type_Id let_type(const Compiler_Let_Stmt *stmt) const noexcept
Returns the inferred type of one let binding, or 0 if unknown.
Compiler_Type_Id inferred_type(const Compiler_Expr *expr) const noexcept
Returns the inferred type of one expression, or 0 if unknown.
Compiler_Type_Id function_type(const Compiler_Function_Decl *function) const noexcept
Returns the inferred type of one function, or 0 if unknown.
Compiler_Type_Id parameter_type(const Compiler_Function_Decl *function, const size_t index) const noexcept
Returns the inferred type of one parameter, or 0 if unknown.
const Compiler_Type_Context & type_context() const noexcept
Returns the internal type context.
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
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
@ Grouping
Parenthesized expression.
@ Unary
Prefix unary operation (e.g., -x, !p).
@ Identifier
Variable or function name reference.
@ Integer_Literal
Numeric integer constant.
@ Invalid
Placeholder for malformed expressions.
@ Char_Literal
Character constant.
@ Binary
Infix binary operation (e.g., x + y).
@ Call
Function or method call.
@ String_Literal
String constant.
@ Bool_Literal
Boolean constant (true/false).
@ While
Loop while a condition is true.
@ Invalid
Placeholder for malformed statements.
@ Expr
Expression evaluated for side effects (e.g., assignment, call).
@ If
Conditional execution.
@ Return
Exit current function with an optional value.
@ Continue
Skip to the next iteration of the innermost loop.
@ Let
Variable declaration and optional initialization.
@ Block
Scoped sequence of statements.
@ Break
Immediate exit from the innermost loop.
and
Check uniqueness with explicit hash + equality functors.
size_t Compiler_Type_Id
Compiler_Operator_Kind compiler_operator_from_token_kind(const Compiler_Token_Kind kind) noexcept
Maps one reference-frontend token kind into a reusable operator kind.
Source_Span span
Source region covered by this node.
Node representing an infix binary operation.
Node representing a braced sequence of statements.
Node representing a function or method call.
Node representing an expression evaluated as a statement.
Abstract base class for expression nodes.
Compiler_Expr_Kind kind
Specific expression type.
Node representing a top-level function declaration.
Source_Span name_span
Location of the function name token.
std::string name
Function name.
DynArray< Compiler_Param > parameters
Ordered list of parameters.
Compiler_Block_Stmt * body
Scoped body of the function.
Node representing an expression explicitly wrapped in parentheses.
Structured block statement.
Typed function call expression.
DynArray< Compiler_HIR_Expr * > arguments
Call arguments.
Expression statement in HIR.
Base class for HIR expressions.
Structured conditional statement.
Invalid HIR expression placeholder.
Invalid HIR statement placeholder.
Typed lexical binding statement.
Source_Span span
Source region associated with the HIR node.
Base class for HIR statements.
Typed variable reference expression.
Structured while-loop statement.
Node representing a named identifier reference.
Node representing a conditional branch.
Node representing a local variable binding.
Node representing a literal value.
Node representing a complete translation unit or module.
DynArray< Compiler_Stmt * > statements
Optional top-level code.
DynArray< Compiler_Function_Decl * > functions
Top-level function definitions.
Node representing a return from the current function.
Source_Span span
Aggregate source span.
Definition SSA.H:166
Abstract base class for statement nodes.
Compiler_Stmt_Kind kind
Specific statement type.
Node representing a prefix unary operation.
Node representing a while-loop.