Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
bytecode_example.cc
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
36#include <iostream>
37
38#include <Bytecode.H>
39
40using namespace Aleph;
41
42namespace
43{
46 {
47 Compiler_IR_Module module;
48
50 global.id = 0;
51 global.kind = Compiler_IR_Slot_Kind::Global;
52 global.name = "answer";
53 module.global_slots.append(global);
54
55 auto * function = new Compiler_IR_Function();
56 function->id = 0;
57 function->name = "choose";
58 function->entry_block = 0;
59 function->exit_block = 1;
60 function->next_value_id = 5;
61
63 flag.id = 0;
64 flag.kind = Compiler_IR_Slot_Kind::Parameter;
65 flag.name = "flag";
66 function->local_slots.append(flag);
67
69 value.id = 1;
70 value.kind = Compiler_IR_Slot_Kind::Local;
71 value.name = "value";
72 function->local_slots.append(value);
73
75 entry.id = 0;
76 entry.label = "entry";
77
79 zero.kind = Compiler_IR_Instruction_Kind::Constant;
80 zero.result_id = 1;
81 zero.text = "0";
82 entry.instructions.append(zero);
83
85 init_store.kind = Compiler_IR_Instruction_Kind::Store;
86 init_store.local_slot_id = 1;
87 init_store.operands.append(1);
88 entry.instructions.append(init_store);
89
91 load_flag.kind = Compiler_IR_Instruction_Kind::Load;
92 load_flag.result_id = 2;
93 load_flag.local_slot_id = 0;
94 entry.instructions.append(load_flag);
95
96 entry.terminator.kind = Compiler_IR_Terminator_Kind::Branch;
100
102 exit.id = 1;
103 exit.label = "exit";
104 exit.terminator.kind = Compiler_IR_Terminator_Kind::Exit;
105 exit.predecessors.append(3);
106
108 then_block.id = 2;
109 then_block.label = "if.then.0";
110
112 one.kind = Compiler_IR_Instruction_Kind::Constant;
113 one.result_id = 3;
114 one.text = "1";
115 then_block.instructions.append(one);
116
118 then_store.kind = Compiler_IR_Instruction_Kind::Store;
119 then_store.local_slot_id = 1;
120 then_store.operands.append(3);
121 then_block.instructions.append(then_store);
122
123 then_block.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
124 then_block.terminator.successors.append(3);
125 then_block.predecessors.append(0);
126
128 join_block.id = 3;
129 join_block.label = "if.end.0";
130
132 load_value.kind = Compiler_IR_Instruction_Kind::Load;
133 load_value.result_id = 5;
134 load_value.local_slot_id = 1;
135 join_block.instructions.append(load_value);
136
137 join_block.terminator.kind = Compiler_IR_Terminator_Kind::Return;
138 join_block.terminator.return_value = 5;
139 join_block.terminator.successors.append(1);
140 join_block.predecessors.append(2);
141 join_block.predecessors.append(4);
142
144 else_block.id = 4;
145 else_block.label = "if.else.0";
146
148 two.kind = Compiler_IR_Instruction_Kind::Constant;
149 two.result_id = 4;
150 two.text = "2";
151 else_block.instructions.append(two);
152
154 else_store.kind = Compiler_IR_Instruction_Kind::Store;
155 else_store.local_slot_id = 1;
156 else_store.operands.append(4);
157 else_block.instructions.append(else_store);
158
159 else_block.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
160 else_block.terminator.successors.append(3);
161 else_block.predecessors.append(0);
162
163 function->blocks.append(entry);
164 function->blocks.append(exit);
165 function->blocks.append(then_block);
166 function->blocks.append(join_block);
167 function->blocks.append(else_block);
168 module.functions.append(function);
169
170 auto * top = new Compiler_IR_Function();
171 top->id = compiler_ir_invalid_id();
172 top->name = "<top-level>";
173 top->entry_block = 0;
174 top->exit_block = 1;
175 top->next_value_id = 3;
176
178 top_entry.id = 0;
179 top_entry.label = "entry";
180
182 function_ref.kind = Compiler_IR_Instruction_Kind::Function_Ref;
183 function_ref.result_id = 1;
184 function_ref.function_id = 0;
185 top_entry.instructions.append(function_ref);
186
188 constant.kind = Compiler_IR_Instruction_Kind::Constant;
189 constant.result_id = 2;
190 constant.text = "true";
191 constant.bool_value = true;
192 top_entry.instructions.append(constant);
193
195 call.kind = Compiler_IR_Instruction_Kind::Call;
196 call.result_id = 3;
197 call.operands.append(1);
198 call.operands.append(2);
199 top_entry.instructions.append(call);
200
202 store_global.kind = Compiler_IR_Instruction_Kind::Store;
203 store_global.global_slot_id = 0;
204 store_global.operands.append(3);
205 top_entry.instructions.append(store_global);
206
207 top_entry.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
208 top_entry.terminator.successors.append(1);
209
211 top_exit.id = 1;
212 top_exit.label = "exit";
213 top_exit.terminator.kind = Compiler_IR_Terminator_Kind::Exit;
214 top_exit.predecessors.append(0);
215
216 top->blocks.append(top_entry);
217 top->blocks.append(top_exit);
218 module.top_level = top;
219 return module;
220 }
221}
222
223int main()
224{
225 Compiler_Bytecode_Context ctx(1 << 16);
227
228 auto module = make_demo_module();
229 const auto * bytecode = lowering.lower_module(&module);
231
233 if (not report.warnings.is_empty())
234 {
235 std::cout << "\nWarnings:\n";
236 for (size_t i = 0; i < report.warnings.size(); ++i)
237 std::cout << "- " << report.warnings.access(i) << '\n';
238 }
239
240 delete module.functions.access(0);
241 delete module.top_level;
242 return report.valid ? 0 : 1;
243}
Reusable bytecode format and lowering from Compiler_IR_Model.H.
int main()
size_t size_t int32_t value
Definition ca-c-api.h:116
Arena-backed ownership context for bytecode functions and modules.
Definition Bytecode.H:254
Lowers explicit IR into register-based bytecode.
Definition Bytecode.H:581
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
void exit(const char *file, int line, const char *format,...)
Print a message and exit the program.
Definition ahDefs.C:125
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
constexpr size_t compiler_ir_invalid_id() noexcept
Returns the sentinel invalid IR id.
Compiler_Bytecode_Validation_Report validate_bytecode_module(const Compiler_Bytecode_Module &module)
Validates all bytecode functions in one module.
Definition Bytecode.H:900
One basic block of IR instructions.
std::string label
Deterministic debug label.
Compiler_IR_Terminator terminator
Explicit block terminator.
DynArray< Compiler_IR_Instruction > instructions
Linear instruction list.
Compiler_IR_Block_Id id
Stable block id.
Lowered IR for one function or top-level body.
One instruction producing an optional explicit result value.
std::string text
Constant spelling or debug payload.
Compiler_IR_Instruction_Kind kind
Instruction category.
Compiler_IR_Value_Id result_id
Produced value id, or 0 for void instructions.
DynArray< Compiler_IR_Value_Id > operands
Input values in deterministic order.
Lowered IR module with shared global slots and functions.
One storage slot used by the IR.
std::string name
Debug name of the slot.
size_t id
Stable slot id within its storage space.
Compiler_IR_Slot_Kind kind
Slot storage category.
Compiler_IR_Terminator_Kind kind
Terminator category.
DynArray< Compiler_IR_Block_Id > successors
Successor blocks in deterministic order.
Compiler_IR_Value_Id condition_value
Branch condition value, if any.