1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-12 11:12:16 +00:00
ton/tolk/type-expr.h
tolk-vm d9dba320cc
[Tolk] Get rid of ~tilda with mutate and self methods
This is a very big change.
If FunC has `.methods()` and `~methods()`, Tolk has only dot,
one and only way to call a `.method()`.
A method may mutate an object, or may not.
It's a behavioral and semantic difference from FunC.

- `cs.loadInt(32)` modifies a slice and returns an integer
- `b.storeInt(x, 32)` modifies a builder
- `b = b.storeInt()` also works, since it not only modifies, but returns
- chained methods also work, they return `self`
- everything works exactly as expected, similar to JS
- no runtime overhead, exactly same Fift instructions
- custom methods are created with ease
- tilda `~` does not exist in Tolk at all
2024-11-02 03:44:14 +04:00

131 lines
4.3 KiB
C++

#pragma once
#include <vector>
#include <iostream>
namespace tolk {
struct TypeExpr {
enum Kind { te_Unknown, te_Var, te_Indirect, te_Atomic, te_Tensor, te_Tuple, te_Map, te_ForAll };
enum AtomicType { _Int, _Cell, _Slice, _Builder, _Continutaion, _Tuple };
Kind constr;
int value;
int minw, maxw;
static constexpr int w_inf = 1023;
std::vector<TypeExpr*> args;
bool was_forall_var = false;
explicit TypeExpr(Kind _constr, int _val = 0) : constr(_constr), value(_val), minw(0), maxw(w_inf) {
}
TypeExpr(Kind _constr, int _val, int width) : constr(_constr), value(_val), minw(width), maxw(width) {
}
TypeExpr(Kind _constr, std::vector<TypeExpr*> list)
: constr(_constr), value((int)list.size()), args(std::move(list)) {
compute_width();
}
TypeExpr(Kind _constr, std::initializer_list<TypeExpr*> list)
: constr(_constr), value((int)list.size()), args(std::move(list)) {
compute_width();
}
TypeExpr(Kind _constr, TypeExpr* elem0) : constr(_constr), value(1), args{elem0} {
compute_width();
}
TypeExpr(Kind _constr, TypeExpr* elem0, std::vector<TypeExpr*> list)
: constr(_constr), value((int)list.size() + 1), args{elem0} {
args.insert(args.end(), list.begin(), list.end());
compute_width();
}
TypeExpr(Kind _constr, TypeExpr* elem0, std::initializer_list<TypeExpr*> list)
: constr(_constr), value((int)list.size() + 1), args{elem0} {
args.insert(args.end(), list.begin(), list.end());
compute_width();
}
bool is_atomic() const {
return constr == te_Atomic;
}
bool is_atomic(int v) const {
return constr == te_Atomic && value == v;
}
bool is_int() const {
return is_atomic(_Int);
}
bool is_var() const {
return constr == te_Var;
}
bool is_map() const {
return constr == te_Map;
}
bool is_tuple() const {
return constr == te_Tuple;
}
bool has_fixed_width() const {
return minw == maxw;
}
int get_width() const {
return has_fixed_width() ? minw : -1;
}
void compute_width();
bool recompute_width();
void show_width(std::ostream& os);
std::ostream& print(std::ostream& os, int prio = 0) const;
void replace_with(TypeExpr* te2);
int extract_components(std::vector<TypeExpr*>& comp_list);
bool equals_to(const TypeExpr* rhs) const;
bool has_unknown_inside() const;
static int holes, type_vars;
static TypeExpr* new_hole() {
return new TypeExpr{te_Unknown, ++holes};
}
static TypeExpr* new_hole(int width) {
return new TypeExpr{te_Unknown, ++holes, width};
}
static TypeExpr* new_unit() {
return new TypeExpr{te_Tensor, 0, 0};
}
static TypeExpr* new_atomic(int value) {
return new TypeExpr{te_Atomic, value, 1};
}
static TypeExpr* new_map(TypeExpr* from, TypeExpr* to);
static TypeExpr* new_func() {
return new_map(new_hole(), new_hole());
}
static TypeExpr* new_tensor(std::vector<TypeExpr*> list, bool red = true) {
return red && list.size() == 1 ? list[0] : new TypeExpr{te_Tensor, std::move(list)};
}
static TypeExpr* new_tensor(std::initializer_list<TypeExpr*> list) {
return new TypeExpr{te_Tensor, std::move(list)};
}
static TypeExpr* new_tensor(TypeExpr* te1, TypeExpr* te2) {
return new_tensor({te1, te2});
}
static TypeExpr* new_tensor(TypeExpr* te1, TypeExpr* te2, TypeExpr* te3) {
return new_tensor({te1, te2, te3});
}
static TypeExpr* new_tuple(TypeExpr* arg0) {
return new TypeExpr{te_Tuple, arg0};
}
static TypeExpr* new_tuple(std::vector<TypeExpr*> list, bool red = false) {
return new_tuple(new_tensor(std::move(list), red));
}
static TypeExpr* new_tuple(std::initializer_list<TypeExpr*> list) {
return new_tuple(new_tensor(list));
}
static TypeExpr* new_var() {
return new TypeExpr{te_Var, --type_vars, 1};
}
static TypeExpr* new_var(int idx) {
return new TypeExpr{te_Var, idx, 1};
}
static TypeExpr* new_forall(std::vector<TypeExpr*> list, TypeExpr* body) {
return new TypeExpr{te_ForAll, body, std::move(list)};
}
static bool remove_indirect(TypeExpr*& te, TypeExpr* forbidden = nullptr);
static std::vector<TypeExpr*> remove_forall(TypeExpr*& te);
static bool remove_forall_in(TypeExpr*& te, TypeExpr* te2, const std::vector<TypeExpr*>& new_vars);
};
std::ostream& operator<<(std::ostream& os, TypeExpr* type_expr);
} // namespace tolk