Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_Types.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
52#ifndef COMPILER_TYPES_H
53#define COMPILER_TYPES_H
54
55#include <initializer_list>
56#include <sstream>
57#include <string>
58#include <utility>
59
60#include <ah-errors.H>
61#include <tpl_dynArray.H>
62
63namespace Aleph {
64using Compiler_Type_Id = size_t;
65
68{
69 Builtin,
70 Tuple,
72 Struct,
73 Enum,
75};
76
79{
80 Invalid,
81 Unit,
82 Bool,
83 Integer,
84 String,
86};
87
89inline const char *compiler_type_kind_name(const Compiler_Type_Kind kind) noexcept
90{
91 switch (kind)
92 {
94 return "Builtin";
96 return "Tuple";
98 return "Function";
100 return "Struct";
102 return "Enum";
104 return "Type_Variable";
105 }
106
107 return "Unknown";
108}
109
111inline const char *compiler_builtin_type_name(const Compiler_Builtin_Type builtin) noexcept
112{
113 switch (builtin)
114 {
116 return "Invalid";
118 return "Unit";
120 return "Bool";
122 return "Int";
124 return "String";
126 return "Char";
127 }
128
129 return "Unknown";
130}
131
183
193{
197
204
206 {
207 type.id = types.size() + 1;
208 types.append(std::move(type));
209 return types.size();
210 }
211
213 {
214 ah_out_of_range_error_unless(id > 0 and id <= types.size())
215 << "Compiler_Type_Context::mutable_type(): invalid id " << id;
216 return types.access(id - 1);
217 }
218
237
238 static DynArray<Compiler_Type_Id> list_to_array(const std::initializer_list<Compiler_Type_Id> ids)
239 {
241 for (const auto id : ids)
242 result.append(id);
243 return result;
244 }
245
246 void append_type_text(std::ostream &out, const Compiler_Type_Id id) const
247 {
248 const auto &ty = type(id);
249 switch (ty.kind)
250 {
253 return;
254
256 out << ty.label;
257 if (ty.rigid)
258 out << '!';
259 return;
260
262 out << '(';
263 for (size_t i = 0; i < ty.components.size(); ++i)
264 {
265 if (i > 0)
266 out << ", ";
267 append_type_text(out, ty.components.access(i));
268 }
269 out << ')';
270 return;
271
273 out << "fn(";
274 for (size_t i = 0; i < ty.components.size(); ++i)
275 {
276 if (i > 0)
277 out << ", ";
278 append_type_text(out, ty.components.access(i));
279 }
280 out << ") -> ";
281 append_type_text(out, ty.result_type);
282 return;
283
286 out << ty.label;
287 return;
288 }
289 }
290
291public:
297
303 {
304 types.clear();
307 invalid_id = 0;
308 unit_id = 0;
309 bool_id = 0;
310 integer_id = 0;
311 string_id = 0;
312 character_id = 0;
314 }
315
318 {
319 return types.size();
320 }
321
324 {
325 return builtin_type_count;
326 }
327
333
339
345
351
357
363
370 const Compiler_Type &type(const Compiler_Type_Id id) const
371 {
372 ah_out_of_range_error_unless(id > 0 and id <= types.size())
373 << "Compiler_Type_Context::type(): invalid id " << id;
374 return types.access(id - 1);
375 }
376
379 {
381 }
382
384 bool is_builtin(const Compiler_Type_Id id) const
385 {
387 }
388
390 bool is_struct(const Compiler_Type_Id id) const
391 {
393 }
394
396 bool is_enum(const Compiler_Type_Id id) const
397 {
398 return type(id).kind == Compiler_Type_Kind::Enum;
399 }
400
408 Compiler_Type_Id make_type_variable(std::string label = "", const bool rigid = false)
409 {
412 ty.rigid = rigid;
413 ty.label = label.empty() ? ("T" + std::to_string(next_type_variable_index++)) : std::move(label);
414 return append_type(std::move(ty));
415 }
416
423 {
426 ty.components = members;
427 return append_type(std::move(ty));
428 }
429
435 Compiler_Type_Id make_tuple_type(const std::initializer_list<Compiler_Type_Id> members)
436 {
437 return make_tuple_type(list_to_array(members));
438 }
439
447 const Compiler_Type_Id result)
448 {
451 ty.components = parameters;
452 ty.result_type = result;
453 return append_type(std::move(ty));
454 }
455
462 Compiler_Type_Id make_function_type(const std::initializer_list<Compiler_Type_Id> parameters,
463 const Compiler_Type_Id result)
464 {
465 return make_function_type(list_to_array(parameters), result);
466 }
467
478 {
481 ty.label = std::move(name);
482 return append_type(std::move(ty));
483 }
484
494 const DynArray<Compiler_Type_Id> &field_types) const
495 {
496 auto &ty = mutable_type(id);
498 << "Compiler_Type_Context::set_struct_fields(): id " << id << " is not a struct";
499 ah_invalid_argument_unless(field_names.size() == field_types.size())
500 << "Compiler_Type_Context::set_struct_fields(): mismatched field name/type arity";
501 ty.member_names = field_names;
502 ty.components = field_types;
503 }
504
515 {
518 ty.label = std::move(name);
519 return append_type(std::move(ty));
520 }
521
529 {
530 auto &ty = mutable_type(id);
532 << "Compiler_Type_Context::set_enum_variants(): id " << id << " is not an enum";
533 ty.member_names = variant_names;
534 }
535
541 std::string to_string(const Compiler_Type_Id id) const
542 {
543 std::ostringstream out;
545 return out.str();
546 }
547
549 std::string dump_types() const
550 {
551 std::ostringstream out;
552 out << "Types\n";
553 for (size_t i = 0; i < types.size(); ++i)
554 {
555 const auto &ty = types.access(i);
556 out << " #" << ty.id << " " << compiler_type_kind_name(ty.kind) << " " << to_string(ty.id)
557 << '\n';
558 }
559 return out.str();
560 }
561};
562} // namespace Aleph
563
564#endif // COMPILER_TYPES_H
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_unless(C)
Throws std::out_of_range if condition does NOT hold.
Definition ah-errors.H:600
#define ah_invalid_argument_unless(C)
Throws std::invalid_argument if condition does NOT hold.
Definition ah-errors.H:660
size_t size_t int32_t * out
Definition ca-c-api.h:120
Context owning all compiler type nodes.
void set_struct_fields(const Compiler_Type_Id id, const DynArray< std::string > &field_names, const DynArray< Compiler_Type_Id > &field_types) const
Assigns field metadata to a previously created struct type.
bool is_type_variable(const Compiler_Type_Id id) const
Returns whether id names a type variable.
void append_type_text(std::ostream &out, const Compiler_Type_Id id) const
bool is_builtin(const Compiler_Type_Id id) const
Returns whether id names a built-in type.
Compiler_Type_Id string_type() const noexcept
Returns the preloaded String type id.
size_t builtin_count() const noexcept
Returns the number of eager built-in types.
size_t size() const noexcept
Returns the total number of stored types.
std::string to_string(const Compiler_Type_Id id) const
Renders one type to a deterministic human-readable string.
Compiler_Type & mutable_type(const Compiler_Type_Id id) const
bool is_struct(const Compiler_Type_Id id) const
Returns whether id names a nominal struct type.
Compiler_Type_Id make_enum_type(std::string name)
Creates a nominal enum type placeholder.
Compiler_Type_Id make_function_type(const std::initializer_list< Compiler_Type_Id > parameters, const Compiler_Type_Id result)
Creates a function type from a small literal list.
const Compiler_Type & type(const Compiler_Type_Id id) const
Returns type id.
std::string dump_types() const
Dumps all known types in allocation order.
Compiler_Type_Id invalid_type() const noexcept
Returns the preloaded Invalid type id.
static DynArray< Compiler_Type_Id > list_to_array(const std::initializer_list< Compiler_Type_Id > ids)
Compiler_Type_Id append_type(Compiler_Type type)
Compiler_Type_Context()
Builds a fresh type context with the built-ins preloaded.
void set_enum_variants(const Compiler_Type_Id id, const DynArray< std::string > &variant_names) const
Assigns variant metadata to a previously created enum type.
Compiler_Type_Id make_tuple_type(const std::initializer_list< Compiler_Type_Id > members)
Creates a tuple type from a small literal list.
DynArray< Compiler_Type > types
Compiler_Type_Id make_type_variable(std::string label="", const bool rigid=false)
Creates a fresh type variable.
Compiler_Type_Id make_tuple_type(const DynArray< Compiler_Type_Id > &members)
Creates a tuple type.
Compiler_Type_Id make_function_type(const DynArray< Compiler_Type_Id > &parameters, const Compiler_Type_Id result)
Creates a function type.
Compiler_Type_Id character_type() const noexcept
Returns the preloaded Char type id.
void clear() noexcept
Drops user-created types and keeps the built-ins.
Compiler_Type_Id unit_type() const noexcept
Returns the preloaded Unit type id.
bool is_enum(const Compiler_Type_Id id) const
Returns whether id names a nominal enum type.
Compiler_Type_Id bool_type() const noexcept
Returns the preloaded Bool type id.
Compiler_Type_Id integer_type() const noexcept
Returns the preloaded Int type id.
Compiler_Type_Id make_struct_type(std::string name)
Creates a nominal struct type placeholder.
size_t size() const noexcept
Return the current dimension of array.
T & append()
Allocate a new entry to the end of array.
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
const char * compiler_builtin_type_name(const Compiler_Builtin_Type builtin) noexcept
Returns a stable debug name for a built-in type.
@ String
String literal payload.
@ Character
Character literal payload.
@ Invalid
Uninitialized register/slot or explicit invalid placeholder.
Compiler_Type_Kind
Category of one stored type node.
@ Struct
Nominal struct declaration.
@ Enum
Nominal enum declaration.
Compiler_Builtin_Type
Built-in scalar types available in the MVP type graph.
and
Check uniqueness with explicit hash + equality functors.
size_t Compiler_Type_Id
const char * compiler_type_kind_name(const Compiler_Type_Kind kind) noexcept
Returns a stable debug name for a type kind.
Field< int > Integer
Definition ahField.H:136
@ Function
Function type such as fn(Int) -> Bool.
@ Tuple
Tuple type such as (Int, Bool).
One node inside the type graph.
DynArray< Compiler_Type_Id > components
Tuple members, function parameters, or struct field types.
Compiler_Type_Id id
Stable 1-based identifier.
bool rigid
Whether the type variable is rigid.
bool is_struct() const noexcept
Returns whether this node represents a nominal struct type.
Compiler_Type_Id result_type
Function return type, or 0.
Compiler_Builtin_Type builtin
Built-in tag.
Compiler_Type_Kind kind
Node category.
bool is_type_variable() const noexcept
Returns whether this node represents a type variable.
DynArray< std::string > member_names
Struct field names or enum variant names.
bool is_enum() const noexcept
Returns whether this node represents a nominal enum type.
std::string label
Display label for type variables or nominal type names.
bool is_builtin() const noexcept
Returns whether this node represents a built-in type.
Lazy and scalable dynamic array implementation.