mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
[Tolk] Smart casts and control flow graph
With the introduction of nullable types, we want the compiler to be smart in cases like > if (x == null) return; > // x is int now or > if (x == null) x = 0; > // x is int now These are called smart casts: when the type of variable at particular usage might differ from its declaration. Implementing smart casts is very challenging. They are based on building control-flow graph and handling every AST vertex with care. Actually, I represent cfg not a as a "graph with edges". Instead, it's a "structured DFS" for the AST: 1) at every point of inferring, we have "current flow facts" 2) when we see an `if (...)`, we create two derived contexts 3) after `if`, finalize them at the end and unify 4) if we detect unreachable code, we mark that context In other words, we get the effect of a CFG but in a more direct approach. That's enough for AST-level data-flow. Smart casts work for local variables and tensor/tuple indices. Compilation errors have been reworked and now are more friendly. There are also compilation warnings for always true/false conditions inside if, assert, etc.
This commit is contained in:
parent
f3e620f48c
commit
7bcb8b895f
47 changed files with 3057 additions and 833 deletions
|
@ -18,6 +18,7 @@
|
|||
#include "compiler-state.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace tolk {
|
||||
|
||||
|
@ -146,9 +147,10 @@ void SrcLocation::show_context(std::ostream& os) const {
|
|||
return;
|
||||
}
|
||||
SrcFile::SrcPosition pos = src_file->convert_offset(char_offset);
|
||||
os << " " << pos.line_str << "\n";
|
||||
os << std::right << std::setw(4) << pos.line_no << " | ";
|
||||
os << pos.line_str << "\n";
|
||||
|
||||
os << " ";
|
||||
os << " " << " | ";
|
||||
for (int i = 1; i < pos.char_no; ++i) {
|
||||
os << ' ';
|
||||
}
|
||||
|
@ -193,8 +195,11 @@ std::ostream& operator<<(std::ostream& os, const ParseError& error) {
|
|||
}
|
||||
|
||||
void ParseError::show(std::ostream& os) const {
|
||||
os << where << ": error: " << message << std::endl;
|
||||
where.show_context(os);
|
||||
os << loc << ": error: " << message << std::endl;
|
||||
if (current_function) {
|
||||
os << " // in function `" << current_function->as_human_readable() << "`" << std::endl;
|
||||
}
|
||||
loc.show_context(os);
|
||||
}
|
||||
|
||||
} // namespace tolk
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue