Visitor for expanding generic types and expressions. More...
#include <expander.hpp>
Protected Member Functions | |
| void | _onWork () override |
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) |
| virtual void | _onEndWork () |
| Protected virtual method called after the work is completed. | |
| area & | _getArea () |
| void | _onEndErrReport (const errReport &rpt) const |
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 |
Visitor for expanding generic types and expressions.
As mentioned in parser, the current prior type inference algorithm doesn't create dependency graphs but collects all prior type inference expressions and repeatedly attempts type inference. Since this approach is used, it's not suitable to perform the operation of repeatedly traversing expressions and attempting prior type inference all at once inside verifier. Therefore, it's necessary to complete prior type inference with expander before verifying with verifier.
Basic operation is based on visitor, so it's good to understand visitor beforehand.
Basically, this applies to all expressions where the user did not specify a type. However, not all expressions without type specification are handled. Prior type inference is only needed when there is no type and the symbol exists in an obj scope. Consider the following byeol code example:
Both age in 1 and name in 2 need type inference, but only 1 performs prior type inference. This is because 2 has no influence. That is, since name inside the foo() function is a local variable, it's sufficient for verifier to perform type inference inside the foo() function.
When parser encounters an expression (property or function) that needs prior type inference, it puts the expression into a function called @expand of the object it belongs to. expander traverses all given root origin obj through visitor, checking if the @expand function exists. When it exists, it creates context to use during expansion and adds it to _stack.
After all visitation ends, it performs prior type inference through the following process:
_stack is empty, terminate type inference_stack elements, prepare frame and verify the expression with verifiereval()For optimization purposes, during visitation for prior type inference, it performs the operation of replacing getExpr with origin objects, which is called type convergence. During convergence, sometimes replacement to origin is immediately possible, but sometimes replacement is only possible after prior type inference is completed. If getExpr is not replaced with origin during visitation, it's stored in _cons and replacement is attempted once after type inference is completed. Even in this case, if it fails, it's just ignored and no error occurs.
|
overrideprotectedvirtual |
Implements by::tworker< void, node >.