Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_AST.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_AST_H
48#define COMPILER_AST_H
49
50#include <sstream>
51#include <string>
52#include <string_view>
53#include <utility>
54
55#include <Compiler_Token.H>
56#include <ah-arena.H>
57#include <ah-errors.H>
58#include <tpl_dynArray.H>
59
60namespace Aleph {
61
62// Forward declarations
63struct Compiler_Expr;
64struct Compiler_Stmt;
67struct Compiler_Module;
71
83inline Source_Span compiler_merge_spans(const Source_Span &lhs, const Source_Span &rhs) noexcept
84{
85 if (not lhs.is_valid())
86 return rhs;
87 if (not rhs.is_valid())
88 return lhs;
89 if (lhs.file_id != rhs.file_id)
90 return lhs;
91 return {lhs.file_id,
92 lhs.begin < rhs.begin ? lhs.begin : rhs.begin,
93 lhs.end > rhs.end ? lhs.end : rhs.end};
94}
95
105{
106 Invalid,
107 Identifier,
112 Grouping,
113 Unary,
114 Binary,
115 Call
116};
117
127{
128 Invalid,
129 Expr,
130 Let,
131 Return,
132 Block,
133 If,
134 While,
135 Break,
136 Continue
137};
138
148{
149 Invalid,
150 Named,
151 Tuple,
152 Function
153};
154
164{
165 Invalid,
166 Alias,
167 Struct,
168 Enum
169};
170
180{
181 Invalid,
182 Import
183};
184
192inline const char *compiler_expr_kind_name(const Compiler_Expr_Kind kind) noexcept
193{
194 switch (kind)
195 {
197 return "Invalid";
199 return "Identifier";
201 return "Integer_Literal";
203 return "String_Literal";
205 return "Char_Literal";
207 return "Bool_Literal";
209 return "Grouping";
211 return "Unary";
213 return "Binary";
215 return "Call";
216 }
217
218 return "Unknown";
219}
220
228inline const char *compiler_stmt_kind_name(const Compiler_Stmt_Kind kind) noexcept
229{
230 switch (kind)
231 {
233 return "Invalid";
235 return "Expr";
237 return "Let";
239 return "Return";
241 return "Block";
243 return "If";
245 return "While";
247 return "Break";
249 return "Continue";
250 }
251
252 return "Unknown";
253}
254
262inline const char *compiler_type_expr_kind_name(const Compiler_Type_Expr_Kind kind) noexcept
263{
264 switch (kind)
265 {
267 return "Invalid";
269 return "Named";
271 return "Tuple";
273 return "Function";
274 }
275
276 return "Unknown";
277}
278
286inline const char *compiler_type_decl_kind_name(const Compiler_Type_Decl_Kind kind) noexcept
287{
288 switch (kind)
289 {
291 return "Invalid";
293 return "Alias";
295 return "Struct";
297 return "Enum";
298 }
299
300 return "Unknown";
301}
302
308{
310
312 explicit Compiler_Ast_Node(const Source_Span &sp = {}) noexcept : span(sp) {}
313
316};
317
329{
332 {
333 void *ptr = nullptr;
334 void (*destroy)(void *) noexcept = nullptr;
335 };
336
339
340public:
348 explicit Compiler_Ast_Context(const size_t arena_size = AhArenaAllocator::DEFAULT_SIZE)
349 : arena_(arena_size)
350 {}
351
352 // Contexts cannot be copied to avoid double-free of the arena.
355
362 {
363 reset();
364 }
365
379 template <typename T, typename... Args>
381 {
382 T *ptr = allocate<T>(arena_, std::forward<Args>(args)...);
383 ah_runtime_error_unless(ptr != nullptr) << "Compiler_Ast_Context: arena allocation failed";
384
385 owned_.append({ptr,
386 [](void *raw) noexcept
387 {
388 static_cast<T *>(raw)->~T();
389 }});
390 return ptr;
391 }
392
402 {
403 for (size_t i = owned_.size(); i > 0; --i)
404 {
405 auto &[ptr, destroy] = owned_.access(i - 1);
406 if (destroy != nullptr and ptr != nullptr)
407 destroy(ptr);
408 }
409 owned_.clear();
410 arena_.reset();
411 }
412
420 {
421 return arena_.allocated_size();
422 }
423
431 {
432 return arena_.capacity();
433 }
434};
435
444{
445 Compiler_Expr_Kind kind = Compiler_Expr_Kind::Invalid;
446
448 Compiler_Expr(const Compiler_Expr_Kind k = Compiler_Expr_Kind::Invalid,
449 const Source_Span &sp = {}) noexcept
450 : Compiler_Ast_Node(sp), kind(k)
451 {}
452};
453
462{
463 Compiler_Stmt_Kind kind = Compiler_Stmt_Kind::Invalid;
464
466 Compiler_Stmt(const Compiler_Stmt_Kind k = Compiler_Stmt_Kind::Invalid,
467 const Source_Span &sp = {}) noexcept
468 : Compiler_Ast_Node(sp), kind(k)
469 {}
470};
471
482{
483 Compiler_Type_Expr_Kind kind = Compiler_Type_Expr_Kind::Invalid;
484
486 Compiler_Type_Expr(const Compiler_Type_Expr_Kind k = Compiler_Type_Expr_Kind::Invalid,
487 const Source_Span &sp = {}) noexcept
488 : Compiler_Ast_Node(sp), kind(k)
489 {}
490};
491
500
503{
504 std::string name;
506
509 const Source_Span &sp = {}) noexcept
511 name_span(sp)
512 {}
513};
514
530
533{
539 Compiler_Type_Expr *result = nullptr;
540
543 const Source_Span &lparen = {},
544 const Source_Span &rparen = {},
545 const Source_Span &arrow = {},
546 Compiler_Type_Expr *res = nullptr) noexcept
549 res != nullptr ? res->span
551 arrow))),
552 keyword_span(kw), parameters(), lparen_span(lparen), rparen_span(rparen),
553 arrow_span(arrow), result(res)
554 {}
555};
556
559{
560 Compiler_Import_Decl_Kind kind = Compiler_Import_Decl_Kind::Invalid;
562 std::string module_name;
565
567 Compiler_Import_Decl(const Compiler_Import_Decl_Kind k = Compiler_Import_Decl_Kind::Invalid,
568 const Source_Span &kw = {},
569 std::string imported = "",
570 const Source_Span &module_sp = {},
571 const Source_Span &semi_sp = {},
572 const Source_Span &sp = {}) noexcept
573 : Compiler_Ast_Node(sp), kind(k), keyword_span(kw), module_name(std::move(imported)),
574 module_name_span(module_sp), semicolon_span(semi_sp)
575 {}
576};
577
586
589{
592 std::string imported = "",
593 const Source_Span &module_sp = {},
594 const Source_Span &semi_sp = {}) noexcept
596 kw,
597 std::move(imported),
598 module_sp,
599 semi_sp,
601 semi_sp.is_valid() ? semi_sp
602 : module_sp))
603 {}
604};
605
615
622
625{
626 Compiler_Type_Decl_Kind kind = Compiler_Type_Decl_Kind::Invalid;
628 std::string name;
630
632 Compiler_Type_Decl(const Compiler_Type_Decl_Kind k = Compiler_Type_Decl_Kind::Invalid,
633 const Source_Span &kw = {},
634 std::string value = "",
635 const Source_Span &name_sp = {},
636 const Source_Span &sp = {}) noexcept
637 : Compiler_Ast_Node(sp), kind(k), keyword_span(kw), name(std::move(value)), name_span(name_sp)
638 {}
639};
640
649
652{
654 Compiler_Type_Expr *aliased_type = nullptr;
656
659 std::string value = "",
660 const Source_Span &name_sp = {},
661 const Source_Span &eq_sp = {},
662 Compiler_Type_Expr *target = nullptr,
663 const Source_Span &semi_sp = {}) noexcept
665 kw,
666 std::move(value),
667 name_sp,
669 semi_sp.is_valid() ? semi_sp
670 : (target != nullptr ? target->span
671 : name_sp))),
672 equal_span(eq_sp), aliased_type(target), semicolon_span(semi_sp)
673 {}
674};
675
678{
682
685 std::string value = "",
686 const Source_Span &name_sp = {},
687 const Source_Span &lbrace_sp = {},
688 const Source_Span &rbrace_sp = {}) noexcept
690 kw,
691 std::move(value),
692 name_sp,
694 rbrace_sp.is_valid() ? rbrace_sp
695 : (lbrace_sp.is_valid() ? lbrace_sp
696 : name_sp))), lbrace_span(lbrace_sp), rbrace_span(rbrace_sp)
697 {}
698};
699
702{
706
709 std::string value = "",
710 const Source_Span &name_sp = {},
711 const Source_Span &lbrace_sp = {},
712 const Source_Span &rbrace_sp = {}) noexcept
714 kw,
715 std::move(value),
716 name_sp,
718 rbrace_sp.is_valid() ? rbrace_sp
719 : (lbrace_sp.is_valid() ? lbrace_sp
720 : name_sp))), lbrace_span(lbrace_sp), rbrace_span(rbrace_sp)
721 {}
722};
723
730{
732 explicit Compiler_Invalid_Expr(const Source_Span &sp = {}) noexcept
734 {}
735};
736
742{
743 std::string name;
745
747 Compiler_Identifier_Expr(std::string value = "", const Source_Span &sp = {}) noexcept
748 : Compiler_Expr(Compiler_Expr_Kind::Identifier, sp), name(std::move(value)), name_span(sp)
749 {}
750};
751
757{
758 std::string lexeme;
759 bool bool_value = false;
760
762 Compiler_Literal_Expr(const Compiler_Expr_Kind k = Compiler_Expr_Kind::Invalid,
763 std::string value = "",
764 const Source_Span &sp = {},
765 const bool bool_val = false) noexcept
766 : Compiler_Expr(k, sp), lexeme(std::move(value)), bool_value(bool_val)
767 {}
768};
769
776{
777 Compiler_Expr *inner = nullptr;
780
783 const Source_Span &lparen = {},
784 const Source_Span &rparen = {}) noexcept
787 expr != nullptr ? compiler_merge_spans(expr->span, rparen)
788 : rparen)),
789 inner(expr), lparen_span(lparen), rparen_span(rparen)
790 {}
791};
792
798{
799 Compiler_Token_Kind op = Compiler_Token_Kind::Invalid;
801 Compiler_Expr *operand = nullptr;
802
804 Compiler_Unary_Expr(const Compiler_Token_Kind op_kind = Compiler_Token_Kind::Invalid,
805 const Source_Span &op_sp = {},
806 Compiler_Expr *expr = nullptr) noexcept
808 compiler_merge_spans(op_sp, expr != nullptr ? expr->span : Source_Span())),
809 op(op_kind), operator_span(op_sp), operand(expr)
810 {}
811};
812
818{
819 Compiler_Token_Kind op = Compiler_Token_Kind::Invalid;
821 Compiler_Expr *left = nullptr;
822 Compiler_Expr *right = nullptr;
823
826 const Compiler_Token_Kind op_kind = Compiler_Token_Kind::Invalid,
827 const Source_Span &op_sp = {},
828 Compiler_Expr *rhs = nullptr) noexcept
830 lhs != nullptr
831 ? compiler_merge_spans(lhs->span, rhs != nullptr ? rhs->span : op_sp)
832 : compiler_merge_spans(op_sp, rhs != nullptr ? rhs->span : Source_Span())),
833 op(op_kind), operator_span(op_sp), left(lhs), right(rhs)
834 {}
835};
836
842{
843 Compiler_Expr *callee = nullptr;
847
850 const Source_Span &lparen = {},
851 const Source_Span &rparen = {}) noexcept
853 func != nullptr ? compiler_merge_spans(func->span, rparen)
855 callee(func), lparen_span(lparen), rparen_span(rparen)
856 {}
857};
858
861{
863 explicit Compiler_Invalid_Stmt(const Source_Span &sp = {}) noexcept
865 {}
866};
867
873{
874 Compiler_Expr *expr = nullptr;
876
878 Compiler_Expr_Stmt(Compiler_Expr *value = nullptr, const Source_Span &semi = {}) noexcept
880 value != nullptr ? compiler_merge_spans(value->span, semi) : semi),
881 expr(value), semicolon_span(semi)
882 {}
883};
884
890{
892 std::string name;
895 Compiler_Type_Expr *annotation = nullptr;
896 Compiler_Expr *initializer = nullptr;
898
901 std::string value = "",
902 const Source_Span &name_sp = {},
903 const Source_Span &colon_sp = {},
904 Compiler_Type_Expr *annot = nullptr,
905 Compiler_Expr *init = nullptr,
906 const Source_Span &semi = {}) noexcept
910 semi.is_valid() ? semi
911 : (init != nullptr ? init->span
912 : (annot != nullptr ? annot->span
913 : name_sp)))),
914 keyword_span(kw), name(std::move(value)), name_span(name_sp), colon_span(colon_sp),
915 annotation(annot), initializer(init),
916 semicolon_span(semi)
917 {}
918};
919
925{
927 Compiler_Expr *value = nullptr;
929
932 Compiler_Expr *expr = nullptr,
933 const Source_Span &semi = {}) noexcept
936 kw, semi.is_valid() ? semi : (expr != nullptr ? expr->span : Source_Span()))),
937 keyword_span(kw), value(expr), semicolon_span(semi)
938 {}
939};
940
957
963{
965 Compiler_Expr *condition = nullptr;
966 Compiler_Stmt *then_branch = nullptr;
968 Compiler_Stmt *else_branch = nullptr;
969
972 Compiler_Expr *cond = nullptr,
973 Compiler_Stmt *then_stmt = nullptr,
974 const Source_Span &else_kw = {},
975 Compiler_Stmt *else_stmt = nullptr) noexcept
978 else_stmt != nullptr
979 ? else_stmt->span
980 : (then_stmt != nullptr
981 ? then_stmt->span
982 : (cond != nullptr ? cond->span : else_kw)))),
983 if_span(if_kw), condition(cond), then_branch(then_stmt), else_span(else_kw),
984 else_branch(else_stmt)
985 {}
986};
987
993{
995 Compiler_Expr *condition = nullptr;
996 Compiler_Stmt *body = nullptr;
997
1000 Compiler_Expr *cond = nullptr,
1001 Compiler_Stmt *stmt = nullptr) noexcept
1004 stmt != nullptr
1005 ? stmt->span
1006 : (cond != nullptr ? cond->span : Source_Span()))),
1007 keyword_span(kw), condition(cond), body(stmt)
1008 {}
1009};
1010
1016{
1019
1021 Compiler_Break_Stmt(const Source_Span &kw = {}, const Source_Span &semi = {}) noexcept
1023 semicolon_span(semi)
1024 {}
1025};
1026
1032{
1035
1037 Compiler_Continue_Stmt(const Source_Span &kw = {}, const Source_Span &semi = {}) noexcept
1039 semicolon_span(semi)
1040 {}
1041};
1042
1045{
1046 std::string name;
1049 Compiler_Type_Expr *annotation = nullptr;
1050};
1051
1057{
1059 std::string name;
1063 Compiler_Type_Expr *return_annotation = nullptr;
1064 Compiler_Block_Stmt *body = nullptr;
1065
1068 std::string value = "",
1069 const Source_Span &name_sp = {},
1070 const Source_Span &arrow_sp = {},
1072 Compiler_Block_Stmt *block = nullptr) noexcept
1074 block != nullptr ? block->span
1075 : (result_annot != nullptr
1076 ? result_annot->span
1077 : name_sp))),
1078 keyword_span(kw), name(std::move(value)), name_span(name_sp), arrow_span(arrow_sp),
1079 return_annotation(result_annot), body(block)
1080 {}
1081};
1082
1099
1100namespace Compiler_Ast_Detail {
1101
1103inline std::string escape_text(std::string_view text)
1104{
1105 std::string escaped;
1106 escaped.reserve(text.size());
1107 for (const char ch : text)
1108 switch (ch)
1109 {
1110 case '\\':
1111 escaped += "\\\\";
1112 break;
1113 case '"':
1114 escaped += "\\\"";
1115 break;
1116 case '\n':
1117 escaped += "\\n";
1118 break;
1119 case '\r':
1120 escaped += "\\r";
1121 break;
1122 case '\t':
1123 escaped += "\\t";
1124 break;
1125 default:
1126 escaped.push_back(ch);
1127 }
1128 return escaped;
1129}
1130
1132inline void dump_type_expr(const Compiler_Type_Expr *type,
1133 std::ostream &out)
1134{
1135 if (type == nullptr)
1136 {
1137 out << "<null-type>";
1138 return;
1139 }
1140
1141 switch (type->kind)
1142 {
1143 case Compiler_Type_Expr_Kind::Invalid:
1144 out << "InvalidType";
1145 return;
1146
1147 case Compiler_Type_Expr_Kind::Named:
1149 return;
1150
1151 case Compiler_Type_Expr_Kind::Tuple:
1152 {
1153 const auto *node = static_cast<const Compiler_Tuple_Type_Expr *>(type);
1154 out << '(';
1155 for (size_t i = 0; i < node->members.size(); ++i)
1156 {
1157 if (i > 0)
1158 out << ", ";
1159 dump_type_expr(node->members.access(i), out);
1160 }
1161 out << ')';
1162 return;
1163 }
1164
1165 case Compiler_Type_Expr_Kind::Function:
1166 {
1167 const auto *node = static_cast<const Compiler_Function_Type_Expr *>(type);
1168 out << "fn(";
1169 for (size_t i = 0; i < node->parameters.size(); ++i)
1170 {
1171 if (i > 0)
1172 out << ", ";
1173 dump_type_expr(node->parameters.access(i), out);
1174 }
1175 out << ") -> ";
1176 dump_type_expr(node->result, out);
1177 return;
1178 }
1179 }
1180
1181 out << "<unknown-type>";
1182}
1183
1185inline void append_indent(std::ostream &out, const size_t indent)
1186{
1187 out << std::string(indent, ' ');
1188}
1189
1191inline void dump_type_decl(const Compiler_Type_Decl *decl, std::ostream &out, const size_t indent);
1192
1194inline void dump_expr(const Compiler_Expr *expr, std::ostream &out, const size_t indent);
1195
1197inline void dump_stmt(const Compiler_Stmt *stmt, std::ostream &out, const size_t indent);
1198
1199inline void dump_expr(const Compiler_Expr *expr, std::ostream &out, const size_t indent)
1200{
1201 append_indent(out, indent);
1202 if (expr == nullptr)
1203 {
1204 out << "<null-expr>\n";
1205 return;
1206 }
1207
1208 switch (expr->kind)
1209 {
1210 case Compiler_Expr_Kind::Invalid:
1211 out << "InvalidExpr\n";
1212 break;
1213 case Compiler_Expr_Kind::Identifier:
1214 {
1215 const auto *node = static_cast<const Compiler_Identifier_Expr *>(expr);
1216 out << "Identifier(" << node->name << ")\n";
1217 break;
1218 }
1219 case Compiler_Expr_Kind::Integer_Literal:
1220 {
1221 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
1222 out << "Integer(" << node->lexeme << ")\n";
1223 break;
1224 }
1225 case Compiler_Expr_Kind::String_Literal:
1226 {
1227 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
1228 out << "String(\"" << escape_text(node->lexeme) << "\")\n";
1229 break;
1230 }
1231 case Compiler_Expr_Kind::Char_Literal:
1232 {
1233 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
1234 out << "Char(\"" << escape_text(node->lexeme) << "\")\n";
1235 break;
1236 }
1237 case Compiler_Expr_Kind::Bool_Literal:
1238 {
1239 const auto *node = static_cast<const Compiler_Literal_Expr *>(expr);
1240 out << "Bool(" << (node->bool_value ? "true" : "false") << ")\n";
1241 break;
1242 }
1243 case Compiler_Expr_Kind::Grouping:
1244 {
1245 const auto *node = static_cast<const Compiler_Grouping_Expr *>(expr);
1246 out << "Grouping\n";
1247 dump_expr(node->inner, out, indent + 2);
1248 break;
1249 }
1250 case Compiler_Expr_Kind::Unary:
1251 {
1252 const auto *node = static_cast<const Compiler_Unary_Expr *>(expr);
1253 out << "Unary(" << compiler_token_kind_name(node->op) << ")\n";
1254 dump_expr(node->operand, out, indent + 2);
1255 break;
1256 }
1257 case Compiler_Expr_Kind::Binary:
1258 {
1259 const auto *node = static_cast<const Compiler_Binary_Expr *>(expr);
1260 out << "Binary(" << compiler_token_kind_name(node->op) << ")\n";
1261 dump_expr(node->left, out, indent + 2);
1262 dump_expr(node->right, out, indent + 2);
1263 break;
1264 }
1265 case Compiler_Expr_Kind::Call:
1266 {
1267 const auto *node = static_cast<const Compiler_Call_Expr *>(expr);
1268 out << "Call\n";
1269 append_indent(out, indent + 2);
1270 out << "Callee:\n";
1271 dump_expr(node->callee, out, indent + 4);
1272 append_indent(out, indent + 2);
1273 out << "Args:\n";
1274 for (size_t i = 0; i < node->arguments.size(); ++i)
1275 dump_expr(node->arguments.access(i), out, indent + 4);
1276 break;
1277 }
1278 }
1279}
1280
1281inline void dump_stmt(const Compiler_Stmt *stmt, std::ostream &out, const size_t indent)
1282{
1283 append_indent(out, indent);
1284 if (stmt == nullptr)
1285 {
1286 out << "<null-stmt>\n";
1287 return;
1288 }
1289
1290 switch (stmt->kind)
1291 {
1292 case Compiler_Stmt_Kind::Invalid:
1293 out << "InvalidStmt\n";
1294 break;
1295 case Compiler_Stmt_Kind::Expr:
1296 {
1297 const auto *node = static_cast<const Compiler_Expr_Stmt *>(stmt);
1298 out << "ExprStmt\n";
1299 dump_expr(node->expr, out, indent + 2);
1300 break;
1301 }
1302 case Compiler_Stmt_Kind::Let:
1303 {
1304 const auto *node = static_cast<const Compiler_Let_Stmt *>(stmt);
1305 out << "Let(" << node->name << ")";
1306 if (node->annotation != nullptr)
1307 {
1308 out << ": ";
1309 dump_type_expr(node->annotation, out);
1310 }
1311 out << '\n';
1312 if (node->initializer != nullptr)
1313 dump_expr(node->initializer, out, indent + 2);
1314 break;
1315 }
1316 case Compiler_Stmt_Kind::Return:
1317 {
1318 const auto *node = static_cast<const Compiler_Return_Stmt *>(stmt);
1319 out << "Return\n";
1320 if (node->value != nullptr)
1321 dump_expr(node->value, out, indent + 2);
1322 break;
1323 }
1324 case Compiler_Stmt_Kind::Block:
1325 {
1326 const auto *node = static_cast<const Compiler_Block_Stmt *>(stmt);
1327 out << "Block\n";
1328 for (size_t i = 0; i < node->statements.size(); ++i)
1329 dump_stmt(node->statements.access(i), out, indent + 2);
1330 break;
1331 }
1332 case Compiler_Stmt_Kind::If:
1333 {
1334 const auto *node = static_cast<const Compiler_If_Stmt *>(stmt);
1335 out << "If\n";
1336 append_indent(out, indent + 2);
1337 out << "Condition:\n";
1338 dump_expr(node->condition, out, indent + 4);
1339 append_indent(out, indent + 2);
1340 out << "Then:\n";
1341 dump_stmt(node->then_branch, out, indent + 4);
1342 if (node->else_branch != nullptr)
1343 {
1344 append_indent(out, indent + 2);
1345 out << "Else:\n";
1346 dump_stmt(node->else_branch, out, indent + 4);
1347 }
1348 break;
1349 }
1350 case Compiler_Stmt_Kind::While:
1351 {
1352 const auto *node = static_cast<const Compiler_While_Stmt *>(stmt);
1353 out << "While\n";
1354 append_indent(out, indent + 2);
1355 out << "Condition:\n";
1356 dump_expr(node->condition, out, indent + 4);
1357 append_indent(out, indent + 2);
1358 out << "Body:\n";
1359 dump_stmt(node->body, out, indent + 4);
1360 break;
1361 }
1362 case Compiler_Stmt_Kind::Break:
1363 out << "Break\n";
1364 break;
1365 case Compiler_Stmt_Kind::Continue:
1366 out << "Continue\n";
1367 break;
1368 }
1369}
1370
1372 std::ostream &out,
1373 const size_t indent)
1374{
1375 append_indent(out, indent);
1376 if (decl == nullptr)
1377 {
1378 out << "<null-import-decl>\n";
1379 return;
1380 }
1381
1382 switch (decl->kind)
1383 {
1384 case Compiler_Import_Decl_Kind::Invalid:
1385 out << "InvalidImportDecl\n";
1386 return;
1387
1388 case Compiler_Import_Decl_Kind::Import:
1389 {
1390 const auto *node = static_cast<const Compiler_Source_Import_Decl *>(decl);
1391 out << "Import(\"" << escape_text(node->module_name) << "\")\n";
1392 return;
1393 }
1394 }
1395}
1396
1397inline void dump_type_decl(const Compiler_Type_Decl *decl, std::ostream &out, const size_t indent)
1398{
1399 append_indent(out, indent);
1400 if (decl == nullptr)
1401 {
1402 out << "<null-type-decl>\n";
1403 return;
1404 }
1405
1406 switch (decl->kind)
1407 {
1408 case Compiler_Type_Decl_Kind::Invalid:
1409 out << "InvalidTypeDecl\n";
1410 return;
1411
1412 case Compiler_Type_Decl_Kind::Alias:
1413 {
1414 const auto *node = static_cast<const Compiler_Type_Alias_Decl *>(decl);
1415 out << "TypeAlias(" << node->name << ") = ";
1416 dump_type_expr(node->aliased_type, out);
1417 out << '\n';
1418 return;
1419 }
1420
1421 case Compiler_Type_Decl_Kind::Struct:
1422 {
1423 const auto *node = static_cast<const Compiler_Struct_Decl *>(decl);
1424 out << "Struct(" << node->name << ")\n";
1425 for (size_t i = 0; i < node->fields.size(); ++i)
1426 {
1427 append_indent(out, indent + 2);
1428 out << "Field(" << node->fields.access(i).name << "): ";
1429 dump_type_expr(node->fields.access(i).annotation, out);
1430 out << '\n';
1431 }
1432 return;
1433 }
1434
1435 case Compiler_Type_Decl_Kind::Enum:
1436 {
1437 const auto *node = static_cast<const Compiler_Enum_Decl *>(decl);
1438 out << "Enum(" << node->name << ")\n";
1439 for (size_t i = 0; i < node->variants.size(); ++i)
1440 {
1441 append_indent(out, indent + 2);
1442 out << "Variant(" << node->variants.access(i).name << ")\n";
1443 }
1444 return;
1445 }
1446 }
1447}
1448} // namespace Compiler_Ast_Detail
1449
1457inline std::string compiler_dump_expr(const Compiler_Expr *expr)
1458{
1459 std::ostringstream out;
1461 return out.str();
1462}
1463
1471inline std::string compiler_dump_stmt(const Compiler_Stmt *stmt)
1472{
1473 std::ostringstream out;
1475 return out.str();
1476}
1477
1486{
1487 std::ostringstream out;
1489 return out.str();
1490}
1491
1500{
1501 std::ostringstream out;
1503 return out.str();
1504}
1505
1514{
1515 std::ostringstream out;
1516 if (fn == nullptr)
1517 return "<null-function>\n";
1518
1519 out << "Function(" << fn->name << ")\n";
1520 if (fn->parameters.size() > 0)
1521 {
1522 out << " Params:";
1523 for (size_t i = 0; i < fn->parameters.size(); ++i)
1524 {
1525 if (i > 0)
1526 out << ",";
1527 out << " " << fn->parameters.access(i).name;
1528 if (fn->parameters.access(i).annotation != nullptr)
1529 {
1530 out << ": ";
1531 Compiler_Ast_Detail::dump_type_expr(fn->parameters.access(i).annotation, out);
1532 }
1533 }
1534 out << '\n';
1535 }
1536 else
1537 out << " Params:\n";
1538
1539 if (fn->return_annotation != nullptr)
1540 {
1541 out << " Return: ";
1542 Compiler_Ast_Detail::dump_type_expr(fn->return_annotation, out);
1543 out << '\n';
1544 }
1545
1546 out << " Body:\n";
1548 return out.str();
1549}
1550
1558inline std::string compiler_dump_module(const Compiler_Module *module)
1559{
1560 std::ostringstream out;
1561 if (module == nullptr)
1562 return "<null-module>\n";
1563
1564 out << "Module\n";
1565 for (size_t i = 0; i < module->imports.size(); ++i)
1566 Compiler_Ast_Detail::dump_import_decl(module->imports.access(i), out, 2);
1567
1568 for (size_t i = 0; i < module->type_declarations.size(); ++i)
1570
1571 for (size_t i = 0; i < module->functions.size(); ++i)
1572 {
1573 const auto *fn = module->functions.access(i);
1575 if (fn == nullptr)
1576 {
1577 out << "Function(null)\n";
1578 continue;
1579 }
1580 out << "Function(" << fn->name << ")\n";
1581 if (fn->parameters.size() > 0)
1582 {
1584 out << "Params:";
1585 for (size_t j = 0; j < fn->parameters.size(); ++j)
1586 {
1587 if (j > 0)
1588 out << ",";
1589 out << " " << fn->parameters.access(j).name;
1590 if (fn->parameters.access(j).annotation != nullptr)
1591 {
1592 out << ": ";
1593 Compiler_Ast_Detail::dump_type_expr(fn->parameters.access(j).annotation, out);
1594 }
1595 }
1596 out << '\n';
1597 }
1598 else
1599 {
1601 out << "Params:\n";
1602 }
1603
1604 if (fn->return_annotation != nullptr)
1605 {
1607 out << "Return: ";
1608 Compiler_Ast_Detail::dump_type_expr(fn->return_annotation, out);
1609 out << '\n';
1610 }
1611
1613 out << "Body:\n";
1615 }
1616
1617 for (size_t i = 0; i < module->statements.size(); ++i)
1618 Compiler_Ast_Detail::dump_stmt(module->statements.access(i), out, 2);
1619
1620 return out.str();
1621}
1622
1623} // namespace Aleph
1624
1625#endif // COMPILER_AST_H
Token model and parser-facing metadata for compiler front-ends.
Memory arena for fast bulk allocations.
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
Definition ah-errors.H:255
size_t size_t int32_t value
Definition ca-c-api.h:116
size_t size_t int32_t * out
Definition ca-c-api.h:120
Arena allocator for fast bump-pointer allocation.
Definition ah-arena.H:122
void reset() noexcept
Reset arena, making all memory available again.
Definition ah-arena.H:256
size_t capacity() const noexcept
Get total arena capacity.
Definition ah-arena.H:407
size_t allocated_size() const noexcept
Get total bytes currently allocated.
Definition ah-arena.H:395
static constexpr size_t DEFAULT_SIZE
Default arena size (1 MB).
Definition ah-arena.H:133
Arena-backed ownership context for AST nodes.
size_t capacity() const noexcept
Returns the total capacity of the arena.
size_t allocated_size() const noexcept
Returns the total bytes currently used in the arena.
Compiler_Ast_Context(const size_t arena_size=AhArenaAllocator::DEFAULT_SIZE)
Constructs a context with the specified arena capacity.
Compiler_Ast_Context & operator=(const Compiler_Ast_Context &)=delete
T * make(Args &&...args)
Allocates and constructs an AST node of type T.
void reset() noexcept
Reclaims all memory and destroys managed nodes.
DynArray< Owned_Object > owned_
Tracked objects for destruction.
~Compiler_Ast_Context() noexcept
Destroys the context and all managed nodes.
AhArenaAllocator arena_
Underlying memory arena.
Compiler_Ast_Context(const Compiler_Ast_Context &)=delete
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.
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
void append_indent(std::ostream &out, const size_t indent)
Utility to append spaces to a stream for indentation.
void dump_type_decl(const Compiler_Type_Decl *decl, std::ostream &out, const size_t indent)
Recursive type-declaration printer for internal use.
void dump_type_expr(const Compiler_Type_Expr *type, std::ostream &out)
Dumps one parsed type-expression in a compact stable form.
void dump_expr(const Compiler_Expr *expr, std::ostream &out, const size_t indent)
Recursive expression printer for internal use.
std::string escape_text(std::string_view text)
Escapes control characters in a string for safe text output.
void dump_stmt(const Compiler_Stmt *stmt, std::ostream &out, const size_t indent)
Recursive statement printer for internal use.
void dump_import_decl(const Compiler_Import_Decl *decl, std::ostream &out, const size_t indent)
Compiler_SSA_Block & block(Compiler_SSA_Function &function, const Compiler_SSA_Block_Id id)
Definition SSA.H:636
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.
Compiler_Expr_Kind
Enumeration of expression node kinds.
@ 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).
const char * compiler_token_kind_name(Compiler_Token_Kind kind)
Returns a human-readable name for a token kind.
@ Binary
dst <- op(lhs, rhs)
@ Return
Return one register value.
@ Call
dst <- callee(args...)
Source_Span compiler_merge_spans(const Source_Span &lhs, const Source_Span &rhs) noexcept
Merges two spans from the same source file.
std::string compiler_dump_type_decl(const Compiler_Type_Decl *decl)
Dumps a type declaration subtree in a deterministic text format.
@ Invalid
Uninitialized register/slot or explicit invalid placeholder.
Compiler_Import_Decl_Kind
Enumeration of top-level import declaration node kinds.
@ Import
One concrete import "name"; declaration.
std::string compiler_dump_expr(const Compiler_Expr *expr)
Dumps an expression subtree in a deterministic text format.
Compiler_Stmt_Kind
Enumeration of statement node kinds.
@ 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.
Compiler_Type_Decl_Kind
Enumeration of top-level type declaration node kinds.
@ Invalid
Placeholder for malformed type declarations.
@ Struct
Nominal struct declaration.
@ Enum
Nominal enum declaration.
@ Alias
Transparent type alias declaration.
std::string compiler_dump_function(const Compiler_Function_Decl *fn)
Dumps a function declaration in a deterministic text format.
const char * compiler_type_decl_kind_name(const Compiler_Type_Decl_Kind kind) noexcept
Returns a stable debug name for a type-declaration kind.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
const char * compiler_stmt_kind_name(const Compiler_Stmt_Kind kind) noexcept
Returns a stable debug name for a statement kind.
const char * compiler_expr_kind_name(const Compiler_Expr_Kind kind) noexcept
Returns a stable debug name for an expression kind.
Compiler_Token_Kind
Token kinds supported by the compiler MVP.
std::string compiler_dump_stmt(const Compiler_Stmt *stmt)
Dumps a statement subtree in a deterministic text format.
static std::atomic< bool > init
Definition hash-fct.C:54
Compiler_Type_Expr_Kind
Enumeration of parsed type-expression node kinds.
@ Named
Named type such as Int or T.
@ Invalid
Placeholder for malformed type syntax.
@ Function
Function type such as fn(Int) -> Bool.
@ Tuple
Tuple type such as (Int, Bool).
std::string compiler_dump_import_decl(const Compiler_Import_Decl *decl)
Dumps an import declaration subtree in a deterministic text format.
const char * compiler_type_expr_kind_name(const Compiler_Type_Expr_Kind kind) noexcept
Returns a stable debug name for a type-expression kind.
STL namespace.
Internal tracking for objects with destructors.
Abstract base class for all AST nodes.
Compiler_Ast_Node(const Source_Span &sp={}) noexcept
Constructs a node with an optional span.
Source_Span span
Source region covered by this node.
virtual ~Compiler_Ast_Node() noexcept=default
Virtual destructor to ensure proper cleanup of derived nodes.
Node representing an infix binary operation.
Source_Span operator_span
Location of the operator token.
Compiler_Binary_Expr(Compiler_Expr *lhs=nullptr, const Compiler_Token_Kind op_kind=Compiler_Token_Kind::Invalid, const Source_Span &op_sp={}, Compiler_Expr *rhs=nullptr) noexcept
Constructs a binary expression.
Node representing a braced sequence of statements.
Source_Span rbrace_span
Location of the closing ‘’}'`.
Source_Span lbrace_span
Location of the opening ‘’{'`.
Compiler_Block_Stmt(const Source_Span &lbrace={}, const Source_Span &rbrace={}) noexcept
Constructs a block statement.
DynArray< Compiler_Stmt * > statements
Sequential statements in the block.
Node representing a loop break.
Compiler_Break_Stmt(const Source_Span &kw={}, const Source_Span &semi={}) noexcept
Constructs a break statement.
Source_Span semicolon_span
Location of the trailing ‘’;'`.
Source_Span keyword_span
Location of the break keyword.
Node representing a function or method call.
DynArray< Compiler_Expr * > arguments
list of call arguments.
Compiler_Call_Expr(Compiler_Expr *func=nullptr, const Source_Span &lparen={}, const Source_Span &rparen={}) noexcept
Constructs a call expression.
Source_Span lparen_span
Location of ‘’('`.
Source_Span rparen_span
Location of ‘’)'`.
Node representing a loop continuation.
Source_Span keyword_span
Location of the continue keyword.
Source_Span semicolon_span
Location of the trailing ‘’;'`.
Compiler_Continue_Stmt(const Source_Span &kw={}, const Source_Span &semi={}) noexcept
Constructs a continue statement.
Nominal top-level enum declaration with unit variants.
DynArray< Compiler_Enum_Variant > variants
Declared unit variants in source order.
Source_Span lbrace_span
Span of the opening {.
Source_Span rbrace_span
Span of the closing }.
Compiler_Enum_Decl(const Source_Span &kw={}, std::string value="", const Source_Span &name_sp={}, const Source_Span &lbrace_sp={}, const Source_Span &rbrace_sp={}) noexcept
Constructs one enum declaration.
One named variant inside a parsed enum declaration.
std::string name
Variant name.
Source_Span name_span
Span of the variant name.
Node representing an expression evaluated as a statement.
Source_Span semicolon_span
Location of the trailing ‘’;'`.
Compiler_Expr_Stmt(Compiler_Expr *value=nullptr, const Source_Span &semi={}) noexcept
Constructs an expression statement.
Abstract base class for expression nodes.
Compiler_Expr_Kind kind
Specific expression type.
Compiler_Expr(const Compiler_Expr_Kind k=Compiler_Expr_Kind::Invalid, const Source_Span &sp={}) noexcept
Constructs an expression base.
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_Function_Decl(const Source_Span &kw={}, std::string value="", const Source_Span &name_sp={}, const Source_Span &arrow_sp={}, Compiler_Type_Expr *result_annot=nullptr, Compiler_Block_Stmt *block=nullptr) noexcept
Constructs a function declaration.
Source_Span keyword_span
Location of the fn keyword.
Source_Span arrow_span
Location of the optional -> before the result annotation.
Function type syntax such as fn(Int, T) -> Bool.
Source_Span arrow_span
Span of the -> token.
Source_Span rparen_span
Span of the closing ).
Compiler_Function_Type_Expr(const Source_Span &kw={}, const Source_Span &lparen={}, const Source_Span &rparen={}, const Source_Span &arrow={}, Compiler_Type_Expr *res=nullptr) noexcept
Constructs a function type-expression node.
Source_Span lparen_span
Span of the opening (.
DynArray< Compiler_Type_Expr * > parameters
Parameter types in declaration order.
Source_Span keyword_span
Span of the fn keyword.
Node representing an expression explicitly wrapped in parentheses.
Source_Span rparen_span
Location of the closing ‘’)'`.
Compiler_Grouping_Expr(Compiler_Expr *expr=nullptr, const Source_Span &lparen={}, const Source_Span &rparen={}) noexcept
Constructs a grouping expression.
Source_Span lparen_span
Location of the opening ‘’('`.
Node representing a named identifier reference.
std::string name
Name of the identifier.
Compiler_Identifier_Expr(std::string value="", const Source_Span &sp={}) noexcept
Constructs an identifier reference.
Source_Span name_span
Span covering only the name lexeme.
Node representing a conditional branch.
Source_Span else_span
Location of the else keyword (if present).
Source_Span if_span
Location of the if keyword.
Compiler_If_Stmt(const Source_Span &if_kw={}, Compiler_Expr *cond=nullptr, Compiler_Stmt *then_stmt=nullptr, const Source_Span &else_kw={}, Compiler_Stmt *else_stmt=nullptr) noexcept
Constructs an if-else statement.
Abstract base class for top-level import declarations.
Source_Span module_name_span
Span of the imported string literal.
Source_Span keyword_span
Span of the introducing import keyword.
Compiler_Import_Decl(const Compiler_Import_Decl_Kind k=Compiler_Import_Decl_Kind::Invalid, const Source_Span &kw={}, std::string imported="", const Source_Span &module_sp={}, const Source_Span &semi_sp={}, const Source_Span &sp={}) noexcept
Constructs an import-declaration base node.
Source_Span semicolon_span
Span of the trailing ;.
std::string module_name
Imported source name without surrounding quotes.
Placeholder node for expressions that failed to parse.
Compiler_Invalid_Expr(const Source_Span &sp={}) noexcept
Constructs an invalid expression sentinel.
Placeholder node for malformed import declarations.
Compiler_Invalid_Import_Decl(const Source_Span &sp={}) noexcept
Constructs an invalid import-declaration sentinel.
Placeholder node for statements that failed to parse.
Compiler_Invalid_Stmt(const Source_Span &sp={}) noexcept
Constructs an invalid statement sentinel.
Placeholder node for malformed type declarations.
Compiler_Invalid_Type_Decl(const Source_Span &sp={}) noexcept
Constructs an invalid type-declaration sentinel.
Placeholder node for type syntax that failed to parse.
Compiler_Invalid_Type_Expr(const Source_Span &sp={}) noexcept
Constructs an invalid type-expression sentinel.
Node representing a local variable binding.
Compiler_Let_Stmt(const Source_Span &kw={}, std::string value="", const Source_Span &name_sp={}, const Source_Span &colon_sp={}, Compiler_Type_Expr *annot=nullptr, Compiler_Expr *init=nullptr, const Source_Span &semi={}) noexcept
Constructs a variable binding statement.
std::string name
Name of the bound variable.
Source_Span keyword_span
Location of the let keyword.
Source_Span name_span
Location of the variable name.
Source_Span semicolon_span
Location of the trailing ‘’;'`.
Source_Span colon_span
Location of the optional : before the type annotation.
Node representing a literal value.
Compiler_Literal_Expr(const Compiler_Expr_Kind k=Compiler_Expr_Kind::Invalid, std::string value="", const Source_Span &sp={}, const bool bool_val=false) noexcept
Constructs a literal expression.
std::string lexeme
Raw source spelling of the literal.
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.
Compiler_Module(const Source_Span &sp={}) noexcept
Constructs a module node.
DynArray< Compiler_Stmt * > statements
Optional top-level code.
DynArray< Compiler_Import_Decl * > imports
Top-level import declarations.
DynArray< Compiler_Function_Decl * > functions
Top-level function definitions.
Named type syntax such as Int, Bool, or T.
Source_Span name_span
Span covering only the name token.
std::string name
Raw type-name spelling.
Compiler_Named_Type_Expr(std::string value="", const Source_Span &sp={}) noexcept
Constructs a named type-expression node.
Representation of a function parameter.
Source_Span span
Location in the source.
Source_Span colon_span
Location of the optional : before the annotation.
std::string name
Parameter identifier.
Node representing a return from the current function.
Source_Span semicolon_span
Location of the trailing ‘’;'`.
Source_Span keyword_span
Location of the return keyword.
Compiler_Return_Stmt(const Source_Span &kw={}, Compiler_Expr *expr=nullptr, const Source_Span &semi={}) noexcept
Constructs a return statement.
Top-level import declaration naming one other source unit.
Compiler_Source_Import_Decl(const Source_Span &kw={}, std::string imported="", const Source_Span &module_sp={}, const Source_Span &semi_sp={}) noexcept
Constructs one import "name"; declaration.
Abstract base class for statement nodes.
Compiler_Stmt(const Compiler_Stmt_Kind k=Compiler_Stmt_Kind::Invalid, const Source_Span &sp={}) noexcept
Constructs a statement base.
Compiler_Stmt_Kind kind
Specific statement type.
Nominal top-level struct declaration.
Source_Span rbrace_span
Span of the closing }.
Source_Span lbrace_span
Span of the opening {.
Compiler_Struct_Decl(const Source_Span &kw={}, std::string value="", const Source_Span &name_sp={}, const Source_Span &lbrace_sp={}, const Source_Span &rbrace_sp={}) noexcept
Constructs one struct declaration.
DynArray< Compiler_Struct_Field > fields
Declared fields in source order.
One named field inside a parsed struct declaration.
std::string name
Field name.
Source_Span name_span
Span of the field name.
Source_Span colon_span
Span of the separating :.
Source_Span semicolon_span
Span of the trailing ;.
Tuple type syntax such as (Int, Bool).
Compiler_Tuple_Type_Expr(const Source_Span &lparen={}, const Source_Span &rparen={}) noexcept
Constructs a tuple type-expression node.
DynArray< Compiler_Type_Expr * > members
Tuple element types in source order.
Source_Span rparen_span
Span of the closing ).
Source_Span lparen_span
Span of the opening (.
Transparent top-level type alias declaration.
Source_Span semicolon_span
Span of the trailing ;.
Compiler_Type_Alias_Decl(const Source_Span &kw={}, std::string value="", const Source_Span &name_sp={}, const Source_Span &eq_sp={}, Compiler_Type_Expr *target=nullptr, const Source_Span &semi_sp={}) noexcept
Constructs one type alias declaration.
Source_Span equal_span
Span of the separating =.
Abstract base class for top-level type declarations.
Source_Span keyword_span
Span of the introducing keyword.
Source_Span name_span
Span of the declared type name.
std::string name
Declared type name.
Compiler_Type_Decl(const Compiler_Type_Decl_Kind k=Compiler_Type_Decl_Kind::Invalid, const Source_Span &kw={}, std::string value="", const Source_Span &name_sp={}, const Source_Span &sp={}) noexcept
Constructs a type-declaration base node.
Abstract base class for parsed type-annotation syntax.
Compiler_Type_Expr(const Compiler_Type_Expr_Kind k=Compiler_Type_Expr_Kind::Invalid, const Source_Span &sp={}) noexcept
Constructs a type-expression base node.
Compiler_Type_Expr_Kind kind
Specific type-expression variant.
Node representing a prefix unary operation.
Compiler_Unary_Expr(const Compiler_Token_Kind op_kind=Compiler_Token_Kind::Invalid, const Source_Span &op_sp={}, Compiler_Expr *expr=nullptr) noexcept
Constructs a unary expression.
Source_Span operator_span
Location of the operator token.
Node representing a while-loop.
Source_Span keyword_span
Location of the while keyword.
Compiler_While_Stmt(const Source_Span &kw={}, Compiler_Expr *cond=nullptr, Compiler_Stmt *stmt=nullptr) noexcept
Constructs a while statement.
Half-open byte range inside a source file.
Definition ah-source.H:100
Source_File_Id file_id
Stable file identifier; 0 means invalid.
Definition ah-source.H:101
static int * k
Lazy and scalable dynamic array implementation.