mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
updated func
- updated func - deleted autogenerated files from git - updated liteclient - increase state sync timeout
This commit is contained in:
parent
c50074fd55
commit
9c9248a9ae
28 changed files with 302 additions and 2465 deletions
|
@ -50,15 +50,15 @@ void define_builtin_func(std::string name, TypeExpr* func_type, const T& func, b
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
void define_builtin_func_x(std::string name, TypeExpr* func_type, const T& func, std::initializer_list<int> arg_order,
|
||||
std::initializer_list<int> ret_order = {}, bool impure = false) {
|
||||
void define_builtin_func(std::string name, TypeExpr* func_type, const T& func, std::initializer_list<int> arg_order,
|
||||
std::initializer_list<int> ret_order = {}, bool impure = false) {
|
||||
SymDef* def = predefine_builtin_func(name, func_type);
|
||||
def->value = new SymValAsmFunc{func_type, func, arg_order, ret_order, impure};
|
||||
}
|
||||
|
||||
void define_builtin_func_x(std::string name, TypeExpr* func_type, const AsmOp& macro,
|
||||
std::initializer_list<int> arg_order, std::initializer_list<int> ret_order = {},
|
||||
bool impure = false) {
|
||||
void define_builtin_func(std::string name, TypeExpr* func_type, const AsmOp& macro,
|
||||
std::initializer_list<int> arg_order, std::initializer_list<int> ret_order = {},
|
||||
bool impure = false) {
|
||||
SymDef* def = predefine_builtin_func(name, func_type);
|
||||
def->value = new SymValAsmFunc{func_type, make_simple_compile(macro), arg_order, ret_order, impure};
|
||||
}
|
||||
|
@ -429,10 +429,14 @@ AsmOp compile_mul(std::vector<VarDescr>& res, std::vector<VarDescr>& args) {
|
|||
}
|
||||
return exec_arg_op("MULCONST", y.int_const, 1);
|
||||
}
|
||||
if (k >= 0) {
|
||||
if (k > 0) {
|
||||
y.unused();
|
||||
return exec_arg_op("LSHIFT#", k, 1);
|
||||
}
|
||||
if (k == 0) {
|
||||
y.unused();
|
||||
return AsmOp::Nop();
|
||||
}
|
||||
}
|
||||
if (x.is_int_const()) {
|
||||
int k = is_pos_pow2(x.int_const);
|
||||
|
@ -451,10 +455,14 @@ AsmOp compile_mul(std::vector<VarDescr>& res, std::vector<VarDescr>& args) {
|
|||
}
|
||||
return exec_arg_op("MULCONST", x.int_const, 1);
|
||||
}
|
||||
if (k >= 0) {
|
||||
if (k > 0) {
|
||||
x.unused();
|
||||
return exec_arg_op("LSHIFT#", k, 1);
|
||||
}
|
||||
if (k == 0) {
|
||||
x.unused();
|
||||
return AsmOp::Nop();
|
||||
}
|
||||
}
|
||||
return exec_op("MUL", 2);
|
||||
}
|
||||
|
@ -848,10 +856,7 @@ void define_builtins() {
|
|||
auto X = TypeExpr::new_var();
|
||||
auto Y = TypeExpr::new_var();
|
||||
auto Z = TypeExpr::new_var();
|
||||
auto T = TypeExpr::new_var();
|
||||
auto XY = TypeExpr::new_tensor({X, Y});
|
||||
auto XYZ = TypeExpr::new_tensor({X, Y, Z});
|
||||
auto XYZT = TypeExpr::new_tensor({X, Y, Z, T});
|
||||
auto arith_bin_op = TypeExpr::new_map(Int2, Int);
|
||||
auto arith_un_op = TypeExpr::new_map(Int, Int);
|
||||
auto impure_bin_op = TypeExpr::new_map(Int2, Unit);
|
||||
|
@ -869,16 +874,20 @@ void define_builtins() {
|
|||
define_builtin_func("-_", arith_un_op, compile_negate);
|
||||
define_builtin_func("_*_", arith_bin_op, compile_mul);
|
||||
define_builtin_func("_/_", arith_bin_op, std::bind(compile_div, _1, _2, -1));
|
||||
define_builtin_func("_/~_", arith_bin_op, std::bind(compile_div, _1, _2, 0));
|
||||
define_builtin_func("_/^_", arith_bin_op, std::bind(compile_div, _1, _2, 1));
|
||||
define_builtin_func("_~/_", arith_bin_op, std::bind(compile_div, _1, _2, 0));
|
||||
define_builtin_func("_^/_", arith_bin_op, std::bind(compile_div, _1, _2, 1));
|
||||
define_builtin_func("_%_", arith_bin_op, std::bind(compile_mod, _1, _2, -1));
|
||||
define_builtin_func("_%~_", arith_bin_op, std::bind(compile_mod, _1, _2, 0));
|
||||
define_builtin_func("_%^_", arith_bin_op, std::bind(compile_mod, _1, _2, -1));
|
||||
define_builtin_func("_~%_", arith_bin_op, std::bind(compile_mod, _1, _2, 0));
|
||||
define_builtin_func("_^%_", arith_bin_op, std::bind(compile_mod, _1, _2, 1));
|
||||
define_builtin_func("_/%_", TypeExpr::new_map(Int2, Int2), AsmOp::Custom("DIVMOD", 2, 2));
|
||||
define_builtin_func("divmod", TypeExpr::new_map(Int2, Int2), AsmOp::Custom("DIVMOD", 2, 2));
|
||||
define_builtin_func("~divmod", TypeExpr::new_map(Int2, Int2), AsmOp::Custom("DIVMOD", 2, 2));
|
||||
define_builtin_func("moddiv", TypeExpr::new_map(Int2, Int2), AsmOp::Custom("DIVMOD", 2, 2), {}, {1, 0});
|
||||
define_builtin_func("~moddiv", TypeExpr::new_map(Int2, Int2), AsmOp::Custom("DIVMOD", 2, 2), {}, {1, 0});
|
||||
define_builtin_func("_<<_", arith_bin_op, compile_lshift);
|
||||
define_builtin_func("_>>_", arith_bin_op, std::bind(compile_rshift, _1, _2, -1));
|
||||
define_builtin_func("_>>~_", arith_bin_op, std::bind(compile_rshift, _1, _2, 0));
|
||||
define_builtin_func("_>>^_", arith_bin_op, std::bind(compile_rshift, _1, _2, 1));
|
||||
define_builtin_func("_~>>_", arith_bin_op, std::bind(compile_rshift, _1, _2, 0));
|
||||
define_builtin_func("_^>>_", arith_bin_op, std::bind(compile_rshift, _1, _2, 1));
|
||||
define_builtin_func("_&_", arith_bin_op, AsmOp::Custom("AND", 2));
|
||||
define_builtin_func("_|_", arith_bin_op, AsmOp::Custom("OR", 2));
|
||||
define_builtin_func("_^_", arith_bin_op, AsmOp::Custom("XOR", 2));
|
||||
|
@ -887,15 +896,15 @@ void define_builtins() {
|
|||
define_builtin_func("^_-=_", arith_bin_op, compile_sub);
|
||||
define_builtin_func("^_*=_", arith_bin_op, compile_mul);
|
||||
define_builtin_func("^_/=_", arith_bin_op, std::bind(compile_div, _1, _2, -1));
|
||||
define_builtin_func("^_/~=_", arith_bin_op, std::bind(compile_div, _1, _2, 0));
|
||||
define_builtin_func("^_/^=_", arith_bin_op, std::bind(compile_div, _1, _2, 1));
|
||||
define_builtin_func("^_~/=_", arith_bin_op, std::bind(compile_div, _1, _2, 0));
|
||||
define_builtin_func("^_^/=_", arith_bin_op, std::bind(compile_div, _1, _2, 1));
|
||||
define_builtin_func("^_%=_", arith_bin_op, std::bind(compile_mod, _1, _2, -1));
|
||||
define_builtin_func("^_%~=_", arith_bin_op, std::bind(compile_mod, _1, _2, 0));
|
||||
define_builtin_func("^_%^=_", arith_bin_op, std::bind(compile_mod, _1, _2, 1));
|
||||
define_builtin_func("^_~%=_", arith_bin_op, std::bind(compile_mod, _1, _2, 0));
|
||||
define_builtin_func("^_^%=_", arith_bin_op, std::bind(compile_mod, _1, _2, 1));
|
||||
define_builtin_func("^_<<=_", arith_bin_op, compile_lshift);
|
||||
define_builtin_func("^_>>=_", arith_bin_op, std::bind(compile_rshift, _1, _2, -1));
|
||||
define_builtin_func("^_>>~=_", arith_bin_op, std::bind(compile_rshift, _1, _2, 0));
|
||||
define_builtin_func("^_>>^=_", arith_bin_op, std::bind(compile_rshift, _1, _2, 1));
|
||||
define_builtin_func("^_~>>=_", arith_bin_op, std::bind(compile_rshift, _1, _2, 0));
|
||||
define_builtin_func("^_^>>=_", arith_bin_op, std::bind(compile_rshift, _1, _2, 1));
|
||||
define_builtin_func("^_&=_", arith_bin_op, AsmOp::Custom("AND", 2));
|
||||
define_builtin_func("^_|=_", arith_bin_op, AsmOp::Custom("OR", 2));
|
||||
define_builtin_func("^_^=_", arith_bin_op, AsmOp::Custom("XOR", 2));
|
||||
|
@ -915,42 +924,18 @@ void define_builtins() {
|
|||
define_builtin_func("nil", Tuple, AsmOp::Const("PUSHNULL"));
|
||||
define_builtin_func("Nil", Tuple, AsmOp::Const("NIL"));
|
||||
define_builtin_func("null?", TypeExpr::new_forall({X}, TypeExpr::new_map(X, Int)), compile_is_null);
|
||||
define_builtin_func("cons", TypeExpr::new_forall({X}, TypeExpr::new_map(TypeExpr::new_tensor(X, Tuple), Tuple)),
|
||||
AsmOp::Custom("CONS", 2, 1));
|
||||
define_builtin_func("uncons", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, TypeExpr::new_tensor(X, Tuple))),
|
||||
AsmOp::Custom("UNCONS", 1, 2));
|
||||
define_builtin_func_x("list_next",
|
||||
TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, TypeExpr::new_tensor(Tuple, X))),
|
||||
AsmOp::Custom("UNCONS", 1, 2), {}, {1, 0});
|
||||
define_builtin_func("car", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("CAR", 1, 1));
|
||||
define_builtin_func("cdr", TypeExpr::new_map(Tuple, Tuple), AsmOp::Custom("CDR", 1, 1));
|
||||
define_builtin_func("pair", TypeExpr::new_forall({X, Y}, TypeExpr::new_map(XY, Tuple)), AsmOp::Custom("PAIR", 2, 1));
|
||||
define_builtin_func("unpair", TypeExpr::new_forall({X, Y}, TypeExpr::new_map(Tuple, XY)),
|
||||
AsmOp::Custom("UNPAIR", 1, 2));
|
||||
define_builtin_func("triple", TypeExpr::new_forall({X, Y, Z}, TypeExpr::new_map(XYZ, Tuple)),
|
||||
AsmOp::Custom("TRIPLE", 3, 1));
|
||||
define_builtin_func("untriple", TypeExpr::new_forall({X, Y, Z}, TypeExpr::new_map(Tuple, XYZ)),
|
||||
AsmOp::Custom("UNTRIPLE", 1, 3));
|
||||
define_builtin_func("tuple4", TypeExpr::new_forall({X, Y, Z, T}, TypeExpr::new_map(XYZT, Tuple)),
|
||||
AsmOp::Custom("4 TUPLE", 4, 1));
|
||||
define_builtin_func("untuple4", TypeExpr::new_forall({X, Y, Z, T}, TypeExpr::new_map(Tuple, XYZT)),
|
||||
AsmOp::Custom("4 UNTUPLE", 1, 4));
|
||||
define_builtin_func("first", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("FIRST", 1, 1));
|
||||
define_builtin_func("second", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("SECOND", 1, 1));
|
||||
define_builtin_func("third", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("THIRD", 1, 1));
|
||||
define_builtin_func("fourth", TypeExpr::new_forall({X}, TypeExpr::new_map(Tuple, X)), AsmOp::Custom("3 INDEX", 1, 1));
|
||||
define_builtin_func("throw", impure_un_op, compile_throw, true);
|
||||
define_builtin_func("throw_if", impure_bin_op, std::bind(compile_cond_throw, _1, _2, true), true);
|
||||
define_builtin_func("throw_unless", impure_bin_op, std::bind(compile_cond_throw, _1, _2, false), true);
|
||||
define_builtin_func_x("load_int", fetch_int_op, std::bind(compile_fetch_int, _1, _2, true, true), {}, {1, 0});
|
||||
define_builtin_func_x("load_uint", fetch_int_op, std::bind(compile_fetch_int, _1, _2, true, false), {}, {1, 0});
|
||||
define_builtin_func("load_int", fetch_int_op, std::bind(compile_fetch_int, _1, _2, true, true), {}, {1, 0});
|
||||
define_builtin_func("load_uint", fetch_int_op, std::bind(compile_fetch_int, _1, _2, true, false), {}, {1, 0});
|
||||
define_builtin_func("preload_int", prefetch_int_op, std::bind(compile_fetch_int, _1, _2, false, true));
|
||||
define_builtin_func("preload_uint", prefetch_int_op, std::bind(compile_fetch_int, _1, _2, false, false));
|
||||
define_builtin_func_x("store_int", store_int_op, std::bind(compile_store_int, _1, _2, true), {1, 0, 2});
|
||||
define_builtin_func_x("store_uint", store_int_op, std::bind(compile_store_int, _1, _2, false), {1, 0, 2});
|
||||
define_builtin_func_x("~store_int", store_int_method, std::bind(compile_store_int, _1, _2, true), {1, 0, 2});
|
||||
define_builtin_func_x("~store_uint", store_int_method, std::bind(compile_store_int, _1, _2, false), {1, 0, 2});
|
||||
define_builtin_func_x("load_bits", fetch_slice_op, std::bind(compile_fetch_slice, _1, _2, true), {}, {1, 0});
|
||||
define_builtin_func("store_int", store_int_op, std::bind(compile_store_int, _1, _2, true), {1, 0, 2});
|
||||
define_builtin_func("store_uint", store_int_op, std::bind(compile_store_int, _1, _2, false), {1, 0, 2});
|
||||
define_builtin_func("~store_int", store_int_method, std::bind(compile_store_int, _1, _2, true), {1, 0, 2});
|
||||
define_builtin_func("~store_uint", store_int_method, std::bind(compile_store_int, _1, _2, false), {1, 0, 2});
|
||||
define_builtin_func("load_bits", fetch_slice_op, std::bind(compile_fetch_slice, _1, _2, true), {}, {1, 0});
|
||||
define_builtin_func("preload_bits", prefetch_slice_op, std::bind(compile_fetch_slice, _1, _2, false));
|
||||
define_builtin_func("int_at", TypeExpr::new_map(TupleInt, Int), compile_tuple_at);
|
||||
define_builtin_func("cell_at", TypeExpr::new_map(TupleInt, Cell), compile_tuple_at);
|
||||
|
@ -967,13 +952,12 @@ void define_builtins() {
|
|||
AsmOp::Custom("s0 DUMP", 1, 1));
|
||||
define_builtin_func("run_method0", TypeExpr::new_map(Int, Unit),
|
||||
[](auto a, auto b, auto c) { return compile_run_method(a, b, c, 0, false); }, true);
|
||||
define_builtin_func_x("run_method1",
|
||||
TypeExpr::new_forall({X}, TypeExpr::new_map(TypeExpr::new_tensor({Int, X}), Unit)),
|
||||
[](auto a, auto b, auto c) { return compile_run_method(a, b, c, 1, false); }, {1, 0}, {}, true);
|
||||
define_builtin_func_x(
|
||||
define_builtin_func("run_method1", TypeExpr::new_forall({X}, TypeExpr::new_map(TypeExpr::new_tensor({Int, X}), Unit)),
|
||||
[](auto a, auto b, auto c) { return compile_run_method(a, b, c, 1, false); }, {1, 0}, {}, true);
|
||||
define_builtin_func(
|
||||
"run_method2", TypeExpr::new_forall({X, Y}, TypeExpr::new_map(TypeExpr::new_tensor({Int, X, Y}), Unit)),
|
||||
[](auto a, auto b, auto c) { return compile_run_method(a, b, c, 2, false); }, {1, 2, 0}, {}, true);
|
||||
define_builtin_func_x(
|
||||
define_builtin_func(
|
||||
"run_method3", TypeExpr::new_forall({X, Y, Z}, TypeExpr::new_map(TypeExpr::new_tensor({Int, X, Y, Z}), Unit)),
|
||||
[](auto a, auto b, auto c) { return compile_run_method(a, b, c, 3, false); }, {1, 2, 3, 0}, {}, true);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ enum Keyword {
|
|||
_RshiftC,
|
||||
_DivR,
|
||||
_DivC,
|
||||
_ModR,
|
||||
_ModC,
|
||||
_DivMod,
|
||||
_PlusLet,
|
||||
_MinusLet,
|
||||
|
@ -75,6 +77,8 @@ enum Keyword {
|
|||
_DivRLet,
|
||||
_DivCLet,
|
||||
_ModLet,
|
||||
_ModRLet,
|
||||
_ModCLet,
|
||||
_LshiftLet,
|
||||
_RshiftLet,
|
||||
_RshiftRLet,
|
||||
|
@ -90,6 +94,7 @@ enum Keyword {
|
|||
_Tuple,
|
||||
_Type,
|
||||
_Mapsto,
|
||||
_Forall,
|
||||
_Asm,
|
||||
_Impure,
|
||||
_Extern,
|
||||
|
@ -128,7 +133,7 @@ class IdSc {
|
|||
*/
|
||||
|
||||
struct TypeExpr {
|
||||
enum te_type { te_Unknown, te_Indirect, te_Atomic, te_Tensor, te_Map, te_Type, te_ForAll } constr;
|
||||
enum te_type { te_Unknown, te_Var, te_Indirect, te_Atomic, te_Tensor, te_Map, te_Type, te_ForAll } constr;
|
||||
enum {
|
||||
_Int = Keyword::_Int,
|
||||
_Cell = Keyword::_Cell,
|
||||
|
@ -173,6 +178,9 @@ struct TypeExpr {
|
|||
bool is_int() const {
|
||||
return is_atomic(_Int);
|
||||
}
|
||||
bool is_var() const {
|
||||
return constr == te_Var;
|
||||
}
|
||||
bool has_fixed_width() const {
|
||||
return minw == maxw;
|
||||
}
|
||||
|
@ -215,7 +223,10 @@ struct TypeExpr {
|
|||
return new_tensor({te1, te2, te3});
|
||||
}
|
||||
static TypeExpr* new_var() {
|
||||
return new TypeExpr{te_Unknown, --type_vars, 1};
|
||||
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)};
|
||||
|
@ -724,6 +735,16 @@ struct SymValCodeFunc : SymValFunc {
|
|||
}
|
||||
};
|
||||
|
||||
struct SymValType : sym::SymValBase {
|
||||
TypeExpr* sym_type;
|
||||
SymValType(int _type, int _idx, TypeExpr* _stype = nullptr) : sym::SymValBase(_type, _idx), sym_type(_stype) {
|
||||
}
|
||||
~SymValType() override = default;
|
||||
TypeExpr* get_type() const {
|
||||
return sym_type;
|
||||
}
|
||||
};
|
||||
|
||||
extern int glob_func_cnt, undef_func_cnt;
|
||||
extern std::vector<SymDef*> glob_func;
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ void define_keywords() {
|
|||
.add_kw_char('>')
|
||||
.add_kw_char('&')
|
||||
.add_kw_char('|')
|
||||
.add_kw_char('^')
|
||||
.add_kw_char('~');
|
||||
|
||||
using Kw = funC::Keyword;
|
||||
|
@ -64,22 +65,26 @@ void define_keywords() {
|
|||
.add_keyword("<=>", Kw::_Spaceship)
|
||||
.add_keyword("<<", Kw::_Lshift)
|
||||
.add_keyword(">>", Kw::_Rshift)
|
||||
.add_keyword(">>~", Kw::_RshiftR)
|
||||
.add_keyword(">>^", Kw::_RshiftC)
|
||||
.add_keyword("/~", Kw::_DivR)
|
||||
.add_keyword("/^", Kw::_DivC)
|
||||
.add_keyword("~>>", Kw::_RshiftR)
|
||||
.add_keyword("^>>", Kw::_RshiftC)
|
||||
.add_keyword("~/", Kw::_DivR)
|
||||
.add_keyword("^/", Kw::_DivC)
|
||||
.add_keyword("~%", Kw::_ModR)
|
||||
.add_keyword("^%", Kw::_ModC)
|
||||
.add_keyword("/%", Kw::_DivMod)
|
||||
.add_keyword("+=", Kw::_PlusLet)
|
||||
.add_keyword("-=", Kw::_MinusLet)
|
||||
.add_keyword("*=", Kw::_TimesLet)
|
||||
.add_keyword("/=", Kw::_DivLet)
|
||||
.add_keyword("~/=", Kw::_DivRLet)
|
||||
.add_keyword("^/=", Kw::_DivCLet)
|
||||
.add_keyword("%=", Kw::_ModLet)
|
||||
.add_keyword("/~=", Kw::_DivRLet)
|
||||
.add_keyword("/^=", Kw::_DivCLet)
|
||||
.add_keyword("~%=", Kw::_ModRLet)
|
||||
.add_keyword("^%=", Kw::_ModCLet)
|
||||
.add_keyword("<<=", Kw::_LshiftLet)
|
||||
.add_keyword(">>=", Kw::_RshiftLet)
|
||||
.add_keyword(">>~=", Kw::_RshiftRLet)
|
||||
.add_keyword(">>^=", Kw::_RshiftCLet)
|
||||
.add_keyword("~>>=", Kw::_RshiftRLet)
|
||||
.add_keyword("^>>=", Kw::_RshiftCLet)
|
||||
.add_keyword("&=", Kw::_AndLet)
|
||||
.add_keyword("|=", Kw::_OrLet)
|
||||
.add_keyword("^=", Kw::_XorLet);
|
||||
|
@ -103,7 +108,9 @@ void define_keywords() {
|
|||
.add_keyword("builder", Kw::_Builder)
|
||||
.add_keyword("cont", Kw::_Cont)
|
||||
.add_keyword("tuple", Kw::_Tuple)
|
||||
.add_keyword("->", Kw::_Mapsto);
|
||||
.add_keyword("type", Kw::_Type)
|
||||
.add_keyword("->", Kw::_Mapsto)
|
||||
.add_keyword("forall", Kw::_Forall);
|
||||
|
||||
sym::symbols.add_keyword("extern", Kw::_Extern)
|
||||
.add_keyword("asm", Kw::_Asm)
|
||||
|
|
|
@ -89,6 +89,15 @@ TypeExpr* parse_type1(Lexer& lex) {
|
|||
case '_':
|
||||
lex.next();
|
||||
return TypeExpr::new_hole();
|
||||
case _Ident: {
|
||||
auto sym = sym::lookup_symbol(lex.cur().val);
|
||||
if (sym && dynamic_cast<SymValType*>(sym->value)) {
|
||||
auto val = dynamic_cast<SymValType*>(sym->value);
|
||||
lex.next();
|
||||
return val->get_type();
|
||||
}
|
||||
lex.cur().error_at("`", "` is not a type identifier");
|
||||
}
|
||||
}
|
||||
lex.expect('(');
|
||||
if (lex.tp() == ')') {
|
||||
|
@ -133,7 +142,14 @@ FormalArg parse_formal_arg(Lexer& lex, int fa_idx) {
|
|||
} else if (lex.tp() != _Ident) {
|
||||
arg_type = parse_type(lex);
|
||||
} else {
|
||||
arg_type = TypeExpr::new_hole();
|
||||
auto sym = sym::lookup_symbol(lex.cur().val);
|
||||
if (sym && dynamic_cast<SymValType*>(sym->value)) {
|
||||
auto val = dynamic_cast<SymValType*>(sym->value);
|
||||
lex.next();
|
||||
arg_type = val->get_type();
|
||||
} else {
|
||||
arg_type = TypeExpr::new_hole();
|
||||
}
|
||||
}
|
||||
if (lex.tp() == '_' || lex.tp() == ',' || lex.tp() == ')') {
|
||||
if (lex.tp() == '_') {
|
||||
|
@ -147,6 +163,9 @@ FormalArg parse_formal_arg(Lexer& lex, int fa_idx) {
|
|||
}
|
||||
loc = lex.cur().loc;
|
||||
SymDef* new_sym_def = sym::define_symbol(lex.cur().val, true, loc);
|
||||
if (!new_sym_def) {
|
||||
lex.cur().error_at("cannot define symbol `", "`");
|
||||
}
|
||||
if (new_sym_def->value) {
|
||||
lex.cur().error_at("redefined formal parameter `", "`");
|
||||
}
|
||||
|
@ -295,6 +314,15 @@ Expr* parse_expr100(Lexer& lex, CodeBlob& code, bool nv) {
|
|||
return res;
|
||||
}
|
||||
if (t == _Ident) {
|
||||
auto sym = sym::lookup_symbol(lex.cur().val);
|
||||
if (sym && dynamic_cast<SymValType*>(sym->value)) {
|
||||
auto val = dynamic_cast<SymValType*>(sym->value);
|
||||
Expr* res = new Expr{Expr::_Type, lex.cur().loc};
|
||||
res->flags = Expr::_IsType;
|
||||
res->e_type = val->get_type();
|
||||
lex.next();
|
||||
return res;
|
||||
}
|
||||
Expr* res = new Expr{Expr::_Var, lex.cur().loc};
|
||||
if (nv) {
|
||||
res->val = ~lex.cur().val;
|
||||
|
@ -302,14 +330,14 @@ Expr* parse_expr100(Lexer& lex, CodeBlob& code, bool nv) {
|
|||
res->flags = Expr::_IsLvalue | Expr::_IsNewVar;
|
||||
// std::cerr << "defined new variable " << lex.cur().str << " : " << res->e_type << std::endl;
|
||||
} else {
|
||||
res->sym = sym::lookup_symbol(lex.cur().val);
|
||||
if (!res->sym) {
|
||||
if (!sym) {
|
||||
check_global_func(lex.cur());
|
||||
res->sym = sym::lookup_symbol(lex.cur().val);
|
||||
sym = sym::lookup_symbol(lex.cur().val);
|
||||
}
|
||||
res->sym = sym;
|
||||
SymVal* val = nullptr;
|
||||
if (res->sym) {
|
||||
val = dynamic_cast<SymVal*>(res->sym->value);
|
||||
if (sym) {
|
||||
val = dynamic_cast<SymVal*>(sym->value);
|
||||
}
|
||||
if (!val) {
|
||||
lex.cur().error_at("undefined identifier `", "`");
|
||||
|
@ -463,7 +491,7 @@ Expr* parse_expr75(Lexer& lex, CodeBlob& code, bool nv) {
|
|||
Expr* parse_expr30(Lexer& lex, CodeBlob& code, bool nv) {
|
||||
Expr* res = parse_expr75(lex, code, nv);
|
||||
while (lex.tp() == '*' || lex.tp() == '/' || lex.tp() == '%' || lex.tp() == _DivMod || lex.tp() == _DivC ||
|
||||
lex.tp() == _DivR || lex.tp() == '&') {
|
||||
lex.tp() == _DivR || lex.tp() == _ModC || lex.tp() == _ModR || lex.tp() == '&') {
|
||||
res->chk_rvalue(lex.cur());
|
||||
int t = lex.tp();
|
||||
sym_idx_t name = symbols.lookup_add(std::string{"_"} + lex.cur().str + "_");
|
||||
|
@ -481,7 +509,7 @@ Expr* parse_expr30(Lexer& lex, CodeBlob& code, bool nv) {
|
|||
return res;
|
||||
}
|
||||
|
||||
// parse [-] E { (+ | - | `|` ) E }
|
||||
// parse [-] E { (+ | - | `|` | ^) E }
|
||||
Expr* parse_expr20(Lexer& lex, CodeBlob& code, bool nv) {
|
||||
Expr* res;
|
||||
int t = lex.tp();
|
||||
|
@ -500,7 +528,7 @@ Expr* parse_expr20(Lexer& lex, CodeBlob& code, bool nv) {
|
|||
} else {
|
||||
res = parse_expr30(lex, code, nv);
|
||||
}
|
||||
while (lex.tp() == '-' || lex.tp() == '+' || lex.tp() == '|') {
|
||||
while (lex.tp() == '-' || lex.tp() == '+' || lex.tp() == '|' || lex.tp() == '^') {
|
||||
res->chk_rvalue(lex.cur());
|
||||
t = lex.tp();
|
||||
sym_idx_t name = symbols.lookup_add(std::string{"_"} + lex.cur().str + "_");
|
||||
|
@ -586,8 +614,8 @@ Expr* parse_expr10(Lexer& lex, CodeBlob& code, bool nv) {
|
|||
auto x = parse_expr13(lex, code, nv);
|
||||
int t = lex.tp();
|
||||
if (t == _PlusLet || t == _MinusLet || t == _TimesLet || t == _DivLet || t == _DivRLet || t == _DivCLet ||
|
||||
t == _ModLet || t == _LshiftLet || t == _RshiftLet || t == _RshiftCLet || t == _RshiftRLet || t == _AndLet ||
|
||||
t == _OrLet || t == _XorLet) {
|
||||
t == _ModLet || t == _ModCLet || t == _ModRLet || t == _LshiftLet || t == _RshiftLet || t == _RshiftCLet ||
|
||||
t == _RshiftRLet || t == _AndLet || t == _OrLet || t == _XorLet) {
|
||||
x->chk_lvalue(lex.cur());
|
||||
x->chk_rvalue(lex.cur());
|
||||
sym_idx_t name = symbols.lookup_add(std::string{"^_"} + lex.cur().str + "_");
|
||||
|
@ -960,9 +988,76 @@ SymValAsmFunc* parse_asm_func_body(Lexer& lex, TypeExpr* func_type, const Formal
|
|||
return res;
|
||||
}
|
||||
|
||||
std::vector<TypeExpr*> parse_type_var_list(Lexer& lex) {
|
||||
std::vector<TypeExpr*> res;
|
||||
lex.expect(_Forall);
|
||||
int idx = 0;
|
||||
while (true) {
|
||||
if (lex.tp() == _Type) {
|
||||
lex.next();
|
||||
}
|
||||
if (lex.tp() != _Ident) {
|
||||
throw src::ParseError{lex.cur().loc, "free type identifier expected"};
|
||||
}
|
||||
auto loc = lex.cur().loc;
|
||||
SymDef* new_sym_def = sym::define_symbol(lex.cur().val, true, loc);
|
||||
if (new_sym_def->value) {
|
||||
lex.cur().error_at("redefined type variable `", "`");
|
||||
}
|
||||
auto var = TypeExpr::new_var(idx);
|
||||
new_sym_def->value = new SymValType{SymVal::_Typename, idx++, var};
|
||||
res.push_back(var);
|
||||
lex.next();
|
||||
if (lex.tp() != ',') {
|
||||
break;
|
||||
}
|
||||
lex.next();
|
||||
}
|
||||
lex.expect(_Mapsto);
|
||||
return res;
|
||||
}
|
||||
|
||||
void type_var_usage(TypeExpr* expr, const std::vector<TypeExpr*>& typevars, std::vector<bool>& used) {
|
||||
if (expr->constr != TypeExpr::te_Var) {
|
||||
for (auto arg : expr->args) {
|
||||
type_var_usage(arg, typevars, used);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (std::size_t i = 0; i < typevars.size(); i++) {
|
||||
if (typevars[i] == expr) {
|
||||
used.at(i) = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TypeExpr* compute_type_closure(TypeExpr* expr, const std::vector<TypeExpr*>& typevars) {
|
||||
if (typevars.empty()) {
|
||||
return expr;
|
||||
}
|
||||
std::vector<bool> used(typevars.size(), false);
|
||||
type_var_usage(expr, typevars, used);
|
||||
std::vector<TypeExpr*> used_vars;
|
||||
for (std::size_t i = 0; i < typevars.size(); i++) {
|
||||
if (used.at(i)) {
|
||||
used_vars.push_back(typevars[i]);
|
||||
}
|
||||
}
|
||||
if (!used_vars.empty()) {
|
||||
expr = TypeExpr::new_forall(std::move(used_vars), expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
void parse_func_def(Lexer& lex) {
|
||||
SrcLocation loc{lex.cur().loc};
|
||||
sym::open_scope(lex);
|
||||
std::vector<TypeExpr*> type_vars;
|
||||
if (lex.tp() == _Forall) {
|
||||
type_vars = parse_type_var_list(lex);
|
||||
}
|
||||
auto ret_type = parse_type(lex);
|
||||
if (lex.tp() != _Ident) {
|
||||
throw src::ParseError{lex.cur().loc, "function name identifier expected"};
|
||||
|
@ -1010,6 +1105,7 @@ void parse_func_def(Lexer& lex) {
|
|||
lex.expect('{', "function body block expected");
|
||||
}
|
||||
TypeExpr* func_type = TypeExpr::new_map(extract_total_arg_type(arg_list), ret_type);
|
||||
func_type = compute_type_closure(func_type, type_vars);
|
||||
if (verbosity >= 1) {
|
||||
std::cerr << "function " << func_name.str << " : " << func_type << std::endl;
|
||||
}
|
||||
|
|
|
@ -59,20 +59,20 @@ operator _/%_ infix 20;
|
|||
return (x / y, x % y);
|
||||
}
|
||||
-}
|
||||
{-
|
||||
< type A, type B, type C >
|
||||
|
||||
forall A, B, C ->
|
||||
(B, C, A) rot (A x, B y, C z) {
|
||||
return (y, z, x);
|
||||
}
|
||||
-}
|
||||
|
||||
int ataninv(int base, int q) { ;; computes base*atan(1/q)
|
||||
base /~= q;
|
||||
base ~/= q;
|
||||
q *= - q;
|
||||
int sum = 0;
|
||||
int n = 1;
|
||||
do {
|
||||
sum += base /~ n;
|
||||
base /~= q;
|
||||
sum += base ~/ n;
|
||||
base ~/= q;
|
||||
n += 2;
|
||||
} until base == 0;
|
||||
return sum;
|
||||
|
@ -81,5 +81,9 @@ int ataninv(int base, int q) { ;; computes base*atan(1/q)
|
|||
int calc_pi() {
|
||||
int base = 64;
|
||||
repeat (70) { base *= 10; }
|
||||
return (ataninv(base << 2, 5) - ataninv(base, 239)) >>~ 4;
|
||||
return (ataninv(base << 2, 5) - ataninv(base, 239)) ~>> 4;
|
||||
}
|
||||
|
||||
int main() {
|
||||
return calc_pi();
|
||||
}
|
||||
|
|
22
crypto/func/test/a6_3.fc
Normal file
22
crypto/func/test/a6_3.fc
Normal file
|
@ -0,0 +1,22 @@
|
|||
forall A, B, C ->
|
||||
(B, C, A) rot(A x, B y, C z) {
|
||||
return (y, z, x);
|
||||
}
|
||||
|
||||
forall A, B, C ->
|
||||
_ rot2(A x, B y, C z) {
|
||||
return rot(rot(x, y, z));
|
||||
}
|
||||
|
||||
_ test() {
|
||||
return rot2(2, 3, 9);
|
||||
}
|
||||
|
||||
_ test2(cell x, slice y, tuple z) {
|
||||
return rot2(x, y, z);
|
||||
}
|
||||
|
||||
forall A ->
|
||||
_ test3(cell x, A y, int z) {
|
||||
return rot2(x, y, z);
|
||||
}
|
|
@ -153,7 +153,7 @@ bool TypeExpr::remove_forall(TypeExpr*& te) {
|
|||
bool TypeExpr::remove_forall_in(TypeExpr*& te, TypeExpr* te2, const std::vector<TypeExpr*>& new_vars) {
|
||||
assert(te);
|
||||
assert(te2 && te2->constr == te_ForAll);
|
||||
if (te->constr == te_Unknown) {
|
||||
if (te->constr == te_Var) {
|
||||
for (std::size_t i = 0; i < new_vars.size(); i++) {
|
||||
if (te == te2->args[i + 1]) {
|
||||
te = new_vars[i];
|
||||
|
@ -201,12 +201,14 @@ std::ostream& operator<<(std::ostream& os, TypeExpr* type_expr) {
|
|||
std::ostream& TypeExpr::print(std::ostream& os, int lex_level) {
|
||||
switch (constr) {
|
||||
case te_Unknown:
|
||||
if (value >= 0) {
|
||||
return os << "??" << value;
|
||||
} else if (value >= -26) {
|
||||
return os << (char)(64 - value);
|
||||
return os << "??" << value;
|
||||
case te_Var:
|
||||
if (value >= -26 && value < 0) {
|
||||
return os << "_" << (char)(91 + value);
|
||||
} else if (value >= 0 && value < 26) {
|
||||
return os << (char)(65 + value);
|
||||
} else {
|
||||
return os << "TVAR" << -value;
|
||||
return os << "TVAR" << value;
|
||||
}
|
||||
case te_Indirect:
|
||||
return os << args[0];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue