Gyoji Compiler
Loading...
Searching...
No Matches
function-scope.hpp
1/* Copyright 2025 Jonathan S. Arney
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * https://github.com/jarney/gyoji/blob/master/LICENSE
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#pragma once
16#include <gyoji-frontend.hpp>
17#include <gyoji-mir.hpp>
18
20
21 class Scope;
22 class ScopeOperation;
23 class ScopeTracker;
24 class LocalVariable;
25
38 public:
39 FunctionPoint(size_t _basic_block_id, size_t _location);
41 size_t get_basic_block_id() const;
42 size_t get_location() const;
43 private:
44 size_t basic_block_id;
45 size_t location;
46 };
47
61 public:
62
89
90 static Gyoji::owned<ScopeOperation> create_variable(
91 std::string _variable_name,
92 const Gyoji::mir::Type *_variable_type,
93 const Gyoji::context::SourceReference & _source_ref
94 );
95 static Gyoji::owned<ScopeOperation> create_label(
96 std::string _label_name,
97 const Gyoji::context::SourceReference & _source_ref
98 );
99 static Gyoji::owned<ScopeOperation> create_goto(
100 std::string _goto_label,
101 Gyoji::owned<FunctionPoint> _goto_point,
102 const Gyoji::context::SourceReference & _source_ref
103 );
104 static Gyoji::owned<ScopeOperation> create_child(
105 Gyoji::owned<Scope> _child,
106 const Gyoji::context::SourceReference & _source_ref
107 );
108
109 void dump(int indent) const;
110 const ScopeOperationType & get_type() const;
111 const std::string & get_label_name() const;
112
113 const std::string & get_goto_label() const;
114 const FunctionPoint & get_goto_point() const;
115
116 const std::string & get_variable_name() const;
117 const Gyoji::mir::Type *get_variable_type() const;
118 const Scope *get_child() const;
119
120 const Gyoji::context::SourceReference & get_source_ref() const;
121
122
123 private:
125 ScopeOperationType _type,
126 const Gyoji::context::SourceReference & _source_ref
127 );
129
130 const Gyoji::context::SourceReference & source_ref;
131
132 const Gyoji::mir::Type *variable_type;
133 std::string variable_name;
134
135 std::string label_name;
136
137 std::string goto_label;
139
141 };
142
143 class LocalVariable {
144 public:
145 LocalVariable(
146 const Gyoji::mir::Type *_type,
147 const Gyoji::context::SourceReference & _source_ref
148 );
155 ~LocalVariable();
156 const Gyoji::mir::Type *get_type() const;
157 const Gyoji::context::SourceReference & get_source_ref() const;
158 private:
159 const Gyoji::mir::Type *type;
160 const Gyoji::context::SourceReference & source_ref;
161 };
162
178 class Scope {
179 public:
184 Scope(bool _is_unsafe);
191 Scope(
192 bool _is_unsafe,
193 bool _is_loop,
194 size_t _loop_break_blockid,
195 size_t _loop_continue_blockid
196 );
203 ~Scope();
204 void add_operation(Gyoji::owned<ScopeOperation> op);
205
206 void dump(int indent) const;
207
213 const LocalVariable *get_variable(std::string name) const;
214
215 bool is_loop() const;
216
224 bool is_unsafe() const;
225
226 size_t get_loop_break_blockid() const;
227
228 size_t get_loop_continue_blockid() const;
229
230 void add_variable(std::string name, const Gyoji::mir::Type *mir_type, const Gyoji::context::SourceReference & source_ref);
231
232 const std::map<std::string, Gyoji::owned<LocalVariable>> & get_variables() const;
233
234 const std::vector<std::string> & get_variables_in_declaration_order() const;
235
236 Scope *get_parent() const;
237
238 void set_parent(Scope *_parent);
239
240 private:
241 friend ScopeTracker;
242 Scope *parent;
243
244 // If this scope is a loop,
245 // what is the block id to jump
246 // to for a 'break' or 'continue' operation?
247 bool scope_is_loop;
248 bool scope_is_unsafe;
249 size_t loop_break_blockid;
250 size_t loop_continue_blockid;
251
254 std::vector<std::string> variables_in_declaration_order;
255 };
256
279 public:
281 size_t _block_id
282 );
290 size_t get_block() const;
291 bool is_resolved() const;
292 void resolve(const Gyoji::context::SourceReference & _src_ref);
293 const Gyoji::context::SourceReference & get_source_ref() const;
294 private:
295 bool resolved;
296 size_t block_id;
297 const Gyoji::context::SourceReference * src_ref;
298 };
299
327 public:
329 bool _root_is_unsafe,
330 const Gyoji::context::CompilerContext & _compiler_context
331 );
339
345 void scope_push(
346 bool is_unsafe,
347 const Gyoji::context::SourceReference & _source_ref
348 );
349
354 void scope_push_loop(
355 const Gyoji::context::SourceReference & _source_ref,
356 size_t _loop_break_blockid,
357 size_t _loop_continue_blockid
358 );
359
363 void scope_pop();
364
371 // Use this for 'label' to say we have a label and it's in the current
372 // scope, but it's on the 'notfound' list, so move it over to
373 // the real list because we've found it now.
374 void label_define(
375 std::string label_name,
376 const Gyoji::context::SourceReference & _source_ref
377 );
378
379 // Use this for 'label' to say we have a label, it's in the
380 // current scope, but it wasn't forwar-declared on the
381 // notfound list.
382 void label_define(
383 std::string label_name,
384 size_t label_block_id,
385 const Gyoji::context::SourceReference & _source_ref
386 );
387
388 // Use this for 'goto' to say we want a label, but we
389 // don't yet know where it will live, so put it on the
390 // notfound labels list.
391 void label_declare(std::string label_name, size_t label_blockid);
392
393 void add_goto(
394 std::string goto_label,
395 Gyoji::owned<FunctionPoint> function_point,
396 const Gyoji::context::SourceReference & _source_ref
397 );
398
399 const FunctionLabel * get_label(std::string name) const;
400
404 bool add_variable(std::string variable_name, const Gyoji::mir::Type *mir_type, const Gyoji::context::SourceReference & source_ref);
405
406 void dump() const;
407
436 bool check(
438 ) const;
439
444 bool is_in_loop() const;
445
446 size_t get_loop_break_blockid() const;
447 size_t get_loop_continue_blockid() const;
448
456 const LocalVariable* get_variable(std::string variable_name) const;
457
464
471
472 std::vector<std::string> get_variables_to_unwind_for_break() const;
473
480
481 const Scope *get_current() const;
482
487 bool is_unsafe() const;
488 private:
489 void add_flat_op(const ScopeOperation *op);
490
491 void add_operation(Gyoji::owned<ScopeOperation> op);
492
494 Scope *current;
495 const Gyoji::context::CompilerContext & compiler_context;
496
497 // Labels that actually have a definition.
499
500 // Labels that have been referenced in a 'goto'
501 // but not yet defined in a scope.
503
504 std::vector<size_t> tracker_prior_point;
505 std::map<size_t, size_t> tracker_backward_edges;
507
508 std::map<std::string, size_t> tracker_label_locations;
509 std::map<size_t, std::string> tracker_goto_labels_at;
510 };
511};
Compiler Context.
Definition gyoji-context.hpp:44
References a location in the source-file.
Definition source-reference.hpp:30
A named label inside a scope.
Definition function-scope.hpp:278
~FunctionLabel()
Move along, nothing to see here.
Definition function-scope.cpp:720
Location inside a specific basic block.
Definition function-scope.hpp:37
Primitive operation in a scope.
Definition function-scope.hpp:60
ScopeOperationType
Definition function-scope.hpp:63
@ GOTO_DEFINITION
Definition function-scope.hpp:75
@ CHILD_SCOPE
Definition function-scope.hpp:80
@ VAR_DECL
Definition function-scope.hpp:67
@ LABEL_DEFINITION
Definition function-scope.hpp:71
~ScopeOperation()
Move along, nothing to see here.
Definition function-scope.cpp:84
Tracks variables declared in each scope along with abels and goto statements in a highly simplified i...
Definition function-scope.hpp:326
void label_define(std::string label_name, const Gyoji::context::SourceReference &_source_ref)
Definition function-scope.cpp:319
std::vector< std::string > get_variables_to_unwind_for_label(std::string &label) const
bool add_variable(std::string variable_name, const Gyoji::mir::Type *mir_type, const Gyoji::context::SourceReference &source_ref)
Definition function-scope.cpp:476
std::vector< std::string > get_variables_to_unwind_for_root() const
Definition function-scope.cpp:413
bool is_unsafe() const
Definition function-scope.cpp:463
std::vector< std::string > get_variables_to_unwind_for_scope() const
Definition function-scope.cpp:430
void scope_pop()
Definition function-scope.cpp:297
bool check(std::vector< std::pair< const ScopeOperation *, std::vector< const ScopeOperation * > > > &goto_fixups) const
Definition function-scope.cpp:586
bool is_in_loop() const
Definition function-scope.cpp:547
void scope_push_loop(const Gyoji::context::SourceReference &_source_ref, size_t _loop_break_blockid, size_t _loop_continue_blockid)
Definition function-scope.cpp:281
~ScopeTracker()
Move along, nothing to see here.
Definition function-scope.cpp:263
void scope_push(bool is_unsafe, const Gyoji::context::SourceReference &_source_ref)
Definition function-scope.cpp:269
const LocalVariable * get_variable(std::string variable_name) const
Definition function-scope.cpp:397
Represents variable declarations, labels, and goto inside a lexical scope.
Definition function-scope.hpp:178
~Scope()
Move along, nothing to see here.
Definition function-scope.cpp:186
bool is_unsafe() const
Definition function-scope.cpp:211
const LocalVariable * get_variable(std::string name) const
Definition function-scope.cpp:196
This represents a type as declared in a translation unit.
Definition types.hpp:313
Converts the strongly-typed syntax tree into the MIR representation.
Definition function-lowering.hpp:37