AST verifier for semantic analysis. More...
#include <verifier.hpp>
Protected Member Functions | |
| void | _prepare () override |
| Protected virtual method for preparation before starting the work. | |
| void | _onEndWork () override |
| Protected virtual method called after the work is completed. | |
Protected Member Functions inherited from by::visitor | |
| void | _onWork () override |
| void | _prepare () override |
| Protected virtual method for preparation before starting the work. | |
Protected Member Functions inherited from by::tworker< void, node > | |
| void | _report (baseErr *e) |
| area & | _getArea () |
| void | _onEndErrReport (const errReport &rpt) const |
Friends | |
| struct | ::verifierTest |
Additional Inherited Members | |
Public Types inherited from by::tworker< void, node > | |
| enum | logFlag |
Public Attributes inherited from by::tworker< void, node > | |
| me setTask | it |
| me setTask * | this |
AST verifier for semantic analysis.
Handles code verification based on visitor. Although the byeol language has an interpreter structure, the language itself uses strong typing and produces errors in advance as if executing compilation. verifier implements the core of that functionality. It checks for errors before executing the final AST created by parser and expander.
verifier is an advanced class even within the core module that uses various modules, so you need to know about several classes beforehand. It's probably one of the classes that will only be understood at the very last stage in this project. You need to know not only node and visitor but also expr and WHEN macros to understand it easily.
Since onTraverse is filled in by visitor, verifier only defines what should be done during onVisit and onLeave.
Program execution ultimately consists of each node's eval(), but verifier is not interested in executed runtime values. It's only interested in type matching such as whether execution is possible and whether the result of a specified expression is implicitly convertible with the defined property's type. node's infer() performs type inference functionality, returning the result type as an origin object without knowing the value when executed. It's faster than eval() because it doesn't compute values. Now you might sense it, but verifier focuses on using infer() rather than eval().
As in the above example, infer() is mainly used instead of eval().
verifier is one of the files with the most LOC. At this time, the code is largely classified into 3 types.
visitor can only have 1 onVisit() function per type. However, verifier usually has 2 or more verification cases that need to be checked when given one type. So if not careful, one onVisit() function becomes mixed with multiple verification logics making it difficult to distinguish. Detailed stage logging helps with this, playing the role of leaving logs about what verification logic will be performed on the object being verified. For example, the _STEP macro automatically counts which stage within that function it is and shows the log.
verifier is a class with many verification codes like if (!check) return res;. So verifier inevitably has numerous WHEN macros.
starter directly executes the program. verifier only performs verification. The biggest difference between them is that when starter executes expressions with eval(), verifier only gets type information with infer(). However, there are some tasks that verifier must perform identically to starter.
|
overrideprotectedvirtual |
Protected virtual method called after the work is completed.
This hook allows derived classes to perform any necessary cleanup or finalization after _onWork() has finished.
Reimplemented from by::tworker< void, node >.
|
overrideprotectedvirtual |
Protected virtual method for preparation before starting the work.
This hook allows derived classes to perform any necessary setup or initialization before _onWork() is invoked.
Reimplemented from by::tworker< void, node >.
Reimplemented from by::visitor.
Reimplemented from by::visitor.