1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

updated func and tonlib

This commit is contained in:
ton 2020-02-15 20:03:17 +04:00
parent 493ae2410c
commit a73d202ba2
50 changed files with 1340 additions and 271 deletions

View file

@ -14,10 +14,12 @@
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2019 Telegram Systems LLP
Copyright 2017-2020 Telegram Systems LLP
*/
#include "func.h"
using namespace std::literals::string_literals;
namespace funC {
/*
@ -164,7 +166,8 @@ bool Expr::deduce_type(const Lexem& lem) {
int Expr::define_new_vars(CodeBlob& code) {
switch (cls) {
case _Tuple:
case _Tensor:
case _MkTuple:
case _TypeApply: {
int res = 0;
for (const auto& x : args) {
@ -189,7 +192,8 @@ int Expr::define_new_vars(CodeBlob& code) {
int Expr::predefine_vars() {
switch (cls) {
case _Tuple:
case _Tensor:
case _MkTuple:
case _TypeApply: {
int res = 0;
for (const auto& x : args) {
@ -201,6 +205,7 @@ int Expr::predefine_vars() {
if (!sym) {
assert(val < 0 && here.defined());
sym = sym::define_symbol(~val, false, here);
// std::cerr << "predefining variable " << sym::symbols.get_name(~val) << std::endl;
if (!sym) {
throw src::ParseError{here, std::string{"redefined variable `"} + sym::symbols.get_name(~val) + "`"};
}
@ -216,12 +221,51 @@ var_idx_t Expr::new_tmp(CodeBlob& code) const {
return code.create_tmp_var(e_type, &here);
}
std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code) const {
std::vector<var_idx_t> Expr::pre_compile_let(CodeBlob& code, Expr* lhs, Expr* rhs, const SrcLocation& here) {
while (lhs->is_type_apply()) {
lhs = lhs->args.at(0);
}
while (rhs->is_type_apply()) {
rhs = rhs->args.at(0);
}
if (lhs->is_mktuple()) {
if (rhs->is_mktuple()) {
return pre_compile_let(code, lhs->args.at(0), rhs->args.at(0), here);
}
auto right = rhs->pre_compile(code);
TypeExpr::remove_indirect(rhs->e_type);
auto unpacked_type = rhs->e_type->args.at(0);
std::vector<var_idx_t> tmp{code.create_tmp_var(unpacked_type, &rhs->here)};
code.emplace_back(lhs->here, Op::_UnTuple, tmp, std::move(right));
auto tvar = new Expr{_Var};
tvar->set_val(tmp[0]);
tvar->set_location(rhs->here);
tvar->e_type = unpacked_type;
pre_compile_let(code, lhs->args.at(0), tvar, here);
return tmp;
}
auto right = rhs->pre_compile(code);
if (lhs->cls == Expr::_GlobVar) {
assert(lhs->sym);
auto& op = code.emplace_back(here, Op::_SetGlob, std::vector<var_idx_t>{}, right, lhs->sym);
op.flags |= Op::_Impure;
} else {
auto left = lhs->pre_compile(code, true);
code.emplace_back(here, Op::_Let, std::move(left), right);
}
return right;
}
std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, bool lval) const {
if (lval && !(cls == _Tensor || cls == _Var || cls == _Hole || cls == _TypeApply)) {
std::cerr << "lvalue expression constructor is " << cls << std::endl;
throw src::Fatal{"cannot compile lvalue expression with unknown constructor"};
}
switch (cls) {
case _Tuple: {
case _Tensor: {
std::vector<var_idx_t> res;
for (const auto& x : args) {
auto add = x->pre_compile(code);
auto add = x->pre_compile(code, lval);
res.insert(res.end(), add.cbegin(), add.cend());
}
return res;
@ -253,7 +297,7 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code) const {
return rvect;
}
case _TypeApply:
return args[0]->pre_compile(code);
return args[0]->pre_compile(code, lval);
case _Var:
case _Hole:
return {val};
@ -289,25 +333,22 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code) const {
return rvect;
}
case _Letop: {
auto right = args[1]->pre_compile(code);
if (args[0]->cls == Expr::_GlobVar) {
assert(args[0]->sym);
auto& op = code.emplace_back(here, Op::_SetGlob, std::vector<var_idx_t>{}, right, args[0]->sym);
op.flags |= Op::_Impure;
} else {
auto left = args[0]->pre_compile(code);
code.emplace_back(here, Op::_Let, std::move(left), right);
}
return right;
return pre_compile_let(code, args.at(0), args.at(1), here);
}
case _LetFirst: {
auto rvect = new_tmp_vect(code);
auto right = args[1]->pre_compile(code);
auto left = args[0]->pre_compile(code);
auto left = args[0]->pre_compile(code, true);
left.push_back(rvect[0]);
code.emplace_back(here, Op::_Let, std::move(left), std::move(right));
return rvect;
}
case _MkTuple: {
auto left = new_tmp_vect(code);
auto right = args[0]->pre_compile(code);
code.emplace_back(here, Op::_Tuple, left, std::move(right));
return left;
}
case _CondExpr: {
auto cond = args[0]->pre_compile(code);
assert(cond.size() == 1);