Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

func update #874

Open
wants to merge 29 commits into
base: testnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2e2ce00
add string case transformer to td namespace
pyAndr3w Jan 14, 2024
6259202
add camelCase aliases for keywords/builtins in FunC and Asm.fif
pyAndr3w Jan 14, 2024
0617f2b
add method_name transformation to snake_case before calculating crc16…
pyAndr3w Jan 14, 2024
8e9dbae
add StringCase to tdutils cmake
pyAndr3w Jan 15, 2024
9471a48
stdlibCamel draft
pyAndr3w Jan 15, 2024
ead4c5e
fix str_const in VarDescr
pyAndr3w Jan 24, 2024
7db9476
add more builtin-funcs
pyAndr3w Jan 24, 2024
26c4c22
stdlib update (draft)
pyAndr3w Jan 24, 2024
eedfa8c
add addr_none constant to stdlib
pyAndr3w Jan 24, 2024
6d09184
optimize store_slice as zeroes/ones
pyAndr3w Jan 24, 2024
022c4d6
fix typo STZEROES (store_slice builtin)
pyAndr3w Jan 24, 2024
053b058
stdlib.fc | cosmetic
pyAndr3w Jan 29, 2024
432a115
fix const types
pyAndr3w Jan 29, 2024
26424e3
stdlib.fc | cosmetic
pyAndr3w Jan 29, 2024
583d657
new slice methods
pyAndr3w Jan 30, 2024
a797d1d
stdlib.fc | new funcs (tvm v6 + address)
pyAndr3w Feb 1, 2024
97004fc
stdlib.fc | more funcs for dicts
pyAndr3w Feb 6, 2024
481f5a2
stdlib.fc | hash funcs + signatures
pyAndr3w Feb 8, 2024
6a22f32
Merge pull request #1 from pyAndr3w/master
pyAndr3w Feb 13, 2024
838502d
four new camelCase aliases for builtin funcs + cosmetic
pyAndr3w Feb 13, 2024
e3bf85b
fix "slice_begins_with?" name + alias
pyAndr3w Feb 13, 2024
b1c3079
stdlib.fc | funcs for c5 register
pyAndr3w Feb 13, 2024
30f8388
Update stdlibCamel.fc
pyAndr3w Feb 13, 2024
b053eb2
add // and /* */ comments to FunC
pyAndr3w Feb 15, 2024
26db913
stdlib.fc | slice_split + cosmetic
pyAndr3w Feb 15, 2024
661a8d2
Update stdlibCamel.fc
pyAndr3w Feb 15, 2024
25fd989
builtin headers support
pyAndr3w Feb 19, 2024
0bdca1d
pragma camelCase
pyAndr3w Feb 23, 2024
4735e77
turn off check pragma camelCase in libs
pyAndr3w Feb 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion blockchain-explorer/blockchain-explorer-query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
#include "crypto/vm/utils.h"
#include "td/utils/crypto.h"

#include "td/utils/StringCase.h"

#include "vm/boc.h"
#include "vm/cellops.h"
#include "vm/cells/MerkleProof.h"
Expand Down Expand Up @@ -1418,7 +1420,7 @@ void HttpQueryRunMethod::finish_query() {
auto code = state_init.code->prefetch_ref();
auto data = state_init.data->prefetch_ref();
auto stack = td::make_ref<vm::Stack>(std::move(params_));
td::int64 method_id = (td::crc16(td::Slice{method_name_}) & 0xffff) | 0x10000;
td::int64 method_id = (td::crc16(td::Slice{td::StringCase::is_camel_case(method_name_) ? td::StringCase::camel_to_snake(method_name_) : method_name_}) & 0xffff) | 0x10000;
stack.write().push_smallint(method_id);
long long gas_limit = vm::GasLimits::infty;
// OstreamLogger ostream_logger(ctx.error_stream);
Expand Down
3 changes: 3 additions & 0 deletions crypto/fift/lib/Asm.fif
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,9 @@ forget @proclist forget @proccnt
-3 constant split_prepare
-4 constant split_install

recv_internal constant receiveInternalMessage
recv_external constant receiveExternalMessage

{ asm-mode 0 3 ~! } : asm-no-remove-unused
{ asm-mode 1 1 ~! } : asm-remove-unused // enabled by default
{ asm-mode 3 3 ~! } : asm-warn-remove-unused
Expand Down
3 changes: 3 additions & 0 deletions crypto/func/abscode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,16 +200,19 @@ void VarDescr::operator&=(const VarDescr& y) {
void VarDescr::set_value(const VarDescr& y) {
val = y.val;
int_const = y.int_const;
str_const = y.str_const;
}

void VarDescr::set_value(VarDescr&& y) {
val = y.val;
int_const = std::move(y.int_const);
str_const = std::move(y.str_const);
}

void VarDescr::clear_value() {
val = 0;
int_const.clear();
str_const.clear();
}

void VarDescrList::show(std::ostream& os) const {
Expand Down
133 changes: 133 additions & 0 deletions crypto/func/builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
Copyright 2017-2020 Telegram Systems LLP
*/
#include "func.h"
#include <iostream>

namespace funC {
using namespace std::literals::string_literals;
Expand Down Expand Up @@ -1116,6 +1117,103 @@ AsmOp compile_is_null(std::vector<VarDescr>& res, std::vector<VarDescr>& args, c
return exec_op("ISNULL", 1, 1);
}

AsmOp compile_slice_begins(std::vector<VarDescr>& res, std::vector<VarDescr>& args, const SrcLocation&) {
func_assert(args.size() == 2 && res.size() == 2);
auto& slice = args[1];
if (!slice.is_const()) {
return exec_op("SDBEGINSXQ", 2, 2);
}
std::ostringstream os;
os << "x{" << slice.str_const << "} SDBEGINSQ";
slice.unused();
return exec_op(os.str(), 1, 2);
}

AsmOp compile_store_slice(std::vector<VarDescr>& res, std::vector<VarDescr>& args, const SrcLocation&) {
func_assert(args.size() == 2 && res.size() == 1);
auto& slice = args[1];
if (!slice.is_const()) {
return exec_op("STSLICE", 2, 1);
}

unsigned char buff[128];
int slice_size = (int)td::bitstring::parse_bitstring_hex_literal(buff, sizeof(buff), slice.str_const.data(), slice.str_const.data() + slice.str_const.size());

td::BitString slice_bs(slice_size);

td::bitstring::bits_memcpy(slice_bs.bits(), buff, slice_size);

bool all_zeroes = td::bitstring::bits_memscan(slice_bs.bits(), slice_size, false) == (u_long)slice_size;
bool all_ones = td::bitstring::bits_memscan(slice_bs.bits(), slice_size, true) == (u_long)slice_size;

if (all_zeroes && slice_size == 1) {
slice.unused();
return exec_op("STZERO", 1, 1);
}
if (all_ones && slice_size == 1) {
slice.unused();
return exec_op("STONE", 1, 1);
}

std::ostringstream os;

if (all_ones && (slice_size > 17 || slice_size == 10)) {
slice.unused();
os << slice_size << " INT STONES";
return exec_op(os.str(), 1, 1);
}

if (all_zeroes && (slice_size > 17 || slice_size == 10)) {
slice.unused();
os << slice_size << " INT STZEROES";
return exec_op(os.str(), 1, 1);
}

if (slice_size <= 57) {
os << "x{" << slice.str_const << "} STSLICECONST";
slice.unused();
return exec_op(os.str(), 1, 1);
}

return exec_op("STSLICE", 2, 1);
}

AsmOp compile_pack_address(std::vector<VarDescr>& res, std::vector<VarDescr>& args, const SrcLocation&) {
auto& wc = args[0];
auto& hash = args[1];
std::ostringstream os;

bool const_wc = wc.is_const();
bool const_hash = hash.is_const();

td::BitString address_bb(3 + 8 + 256);
td::bitstring::bits_store_long(address_bb.bits(), 4, 3); // addr_std$10 anycast:(Maybe Anycast)

if (const_wc) {
td::bitstring::bits_store_long(address_bb.bits() + 3, wc.int_const->to_long(), 8);
os << "NEWC x{" << td::bitstring::bits_to_hex(address_bb.bits(), 3 + 8) << "} STSLICECONST ";
wc.unused();
} else {
os << "NEWC b{100} STSLICECONST 8 STI ";
}

if (const_hash) {
hash.int_const->export_bits(address_bb.bits() + 3 + 8, 256, true);
}

os << "256 STU "; // hash

if (const_wc && const_hash) {
hash.unused();
return exec_op("x{" + td::bitstring::bits_to_hex(address_bb.bits(), 267) + "} PUSHSLICE", 0, 1);
}

os << "ENDC CTOS";

return exec_op(os.str(), 2 - (unsigned)const_wc - (unsigned)const_hash, 1);
}


bool compile_run_method(AsmOpList& code, std::vector<VarDescr>& res, std::vector<VarDescr>& args, int n,
bool has_value) {
func_assert(args.size() == (unsigned)n + 1 && res.size() == (unsigned)has_value);
Expand Down Expand Up @@ -1156,6 +1254,9 @@ void define_builtins() {
auto store_int_op = TypeExpr::new_map(TypeExpr::new_tensor({Builder, Int, Int}), Builder);
auto store_int_method =
TypeExpr::new_map(TypeExpr::new_tensor({Builder, Int, Int}), TypeExpr::new_tensor({Builder, Unit}));
auto store_slice_op = TypeExpr::new_map(TypeExpr::new_tensor({Builder, Slice}), Builder);
auto store_slice_method =
TypeExpr::new_map(TypeExpr::new_tensor({Builder, Slice}), TypeExpr::new_tensor({Builder, Unit}));
auto fetch_slice_op = TypeExpr::new_map(SliceInt, TypeExpr::new_tensor({Slice, Slice}));
auto prefetch_slice_op = TypeExpr::new_map(SliceInt, Slice);
//auto arith_null_op = TypeExpr::new_map(TypeExpr::new_unit(), Int);
Expand Down Expand Up @@ -1248,6 +1349,11 @@ void define_builtins() {
AsmOp::Custom("s0 DUMP", 1, 1), true);
define_builtin_func("~strdump", TypeExpr::new_forall({X}, TypeExpr::new_map(X, TypeExpr::new_tensor({X, Unit}))),
AsmOp::Custom("STRDUMP", 1, 1), true);
define_builtin_func("slice_begins_with?", TypeExpr::new_map(TypeExpr::new_tensor({Slice, Slice}), SliceInt),
compile_slice_begins, true);
define_builtin_func("store_slice", store_slice_op, compile_store_slice, {1, 0});
define_builtin_func("~store_slice", store_slice_method, compile_store_slice, {1, 0});
define_builtin_func("pack_address", TypeExpr::new_map(Int2, Slice), compile_pack_address, {1, 0});
define_builtin_func(
"run_method0", TypeExpr::new_map(Int, Unit),
[](AsmOpList& a, auto b, auto c) { return compile_run_method(a, b, c, 0, false); }, true);
Expand All @@ -1260,6 +1366,33 @@ void define_builtins() {
define_builtin_func(
"run_method3", TypeExpr::new_forall({X, Y, Z}, TypeExpr::new_map(TypeExpr::new_tensor({Int, X, Y, Z}), Unit)),
[](AsmOpList& a, auto b, auto c) { return compile_run_method(a, b, c, 3, false); }, {1, 2, 3, 0}, {}, true);

// camelCase aliases
define_builtin_func("isNull", TypeExpr::new_forall({X}, TypeExpr::new_map(X, Int)), compile_is_null);
define_builtin_func("throwIf", impure_bin_op, std::bind(compile_cond_throw, _1, _2, true), true);
define_builtin_func("throwUnless", impure_bin_op, std::bind(compile_cond_throw, _1, _2, false), true);
define_builtin_func("throwArg", throw_arg_op, compile_throw_arg, true);
define_builtin_func("throwArgIf", cond_throw_arg_op, std::bind(compile_cond_throw_arg, _1, _2, true), true);
define_builtin_func("throwArgUnless", cond_throw_arg_op, std::bind(compile_cond_throw_arg, _1, _2, false), true);
define_builtin_func("loadInt", fetch_int_op, std::bind(compile_fetch_int, _1, _2, true, true), {}, {1, 0});
define_builtin_func("loadUint", fetch_int_op, std::bind(compile_fetch_int, _1, _2, true, false), {}, {1, 0});
define_builtin_func("preloadInt", prefetch_int_op, std::bind(compile_fetch_int, _1, _2, false, true));
define_builtin_func("preloadUint", prefetch_int_op, std::bind(compile_fetch_int, _1, _2, false, false));
define_builtin_func("storeInt", store_int_op, std::bind(compile_store_int, _1, _2, true), {1, 0, 2});
define_builtin_func("storeUint", store_int_op, std::bind(compile_store_int, _1, _2, false), {1, 0, 2});
define_builtin_func("~storeInt", store_int_method, std::bind(compile_store_int, _1, _2, true), {1, 0, 2});
define_builtin_func("~storeUint", store_int_method, std::bind(compile_store_int, _1, _2, false), {1, 0, 2});
define_builtin_func("loadBits", fetch_slice_op, std::bind(compile_fetch_slice, _1, _2, true), {}, {1, 0});
define_builtin_func("preloadBits", prefetch_slice_op, std::bind(compile_fetch_slice, _1, _2, false));
define_builtin_func("intAt", TypeExpr::new_map(TupleInt, Int), compile_tuple_at);
define_builtin_func("cellAt", TypeExpr::new_map(TupleInt, Cell), compile_tuple_at);
define_builtin_func("sliceAt", TypeExpr::new_map(TupleInt, Slice), compile_tuple_at);
define_builtin_func("tupleAt", TypeExpr::new_map(TupleInt, Tuple), compile_tuple_at);
define_builtin_func("isSliceBeginsWith", TypeExpr::new_map(TypeExpr::new_tensor({Slice, Slice}), SliceInt),
compile_slice_begins, true);
define_builtin_func("storeSlice", store_slice_op, compile_store_slice, {1, 0});
define_builtin_func("~storeSlice", store_slice_method, compile_store_slice, {1, 0});
define_builtin_func("packAddress", TypeExpr::new_map(Int2, Slice), compile_pack_address, {1, 0});
}

} // namespace funC
2 changes: 2 additions & 0 deletions crypto/func/keywords.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ void define_keywords() {
.add_keyword("inline_ref", Kw::_InlineRef)
.add_keyword("auto_apply", Kw::_AutoApply)
.add_keyword("method_id", Kw::_MethodId)
.add_keyword("inlineRef", Kw::_InlineRef)
.add_keyword("methodId", Kw::_MethodId)
.add_keyword("operator", Kw::_Operator)
.add_keyword("infix", Kw::_Infix)
.add_keyword("infixl", Kw::_Infixl)
Expand Down
3 changes: 2 additions & 1 deletion crypto/func/parse-func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
#include "func.h"
#include "td/utils/crypto.h"
#include "td/utils/StringCase.h"
#include "common/refint.h"
#include "openssl/digest.hpp"
#include "block/block.h"
Expand Down Expand Up @@ -1475,7 +1476,7 @@ void parse_func_def(Lexer& lex) {
method_name = func_name.str;
}
if (method_id.is_null()) {
unsigned crc = td::crc16(method_name);
unsigned crc = td::crc16(td::StringCase::is_camel_case(method_name) ? td::StringCase::camel_to_snake(method_name) : method_name);
method_id = td::make_refint((crc & 0xffff) | 0x10000);
}
}
Expand Down
19 changes: 12 additions & 7 deletions crypto/parser/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,10 @@ int Lexem::set(std::string _str, const SrcLocation& _loc, int _tp, int _val) {
return classify();
}

Lexer::Lexer(SourceReader& _src, bool init, std::string active_chars, std::string eol_cmts, std::string open_cmts,
std::string close_cmts, std::string quote_chars, std::string multiline_quote)
Lexer::Lexer(SourceReader& _src, bool init, std::string active_chars,
std::string eol_cmts, std::string open_cmts, std::string close_cmts,
std::string camel_eol_cmts, std::string camel_open_cmts, std::string camel_close_cmts,
std::string quote_chars, std::string multiline_quote)
: src(_src), eof(false), lexem("", src.here(), Lexem::Undefined), peek_lexem("", {}, Lexem::Undefined),
multiline_quote(std::move(multiline_quote)) {
std::memset(char_class, 0, sizeof(char_class));
Expand All @@ -142,6 +144,9 @@ Lexer::Lexer(SourceReader& _src, bool init, std::string active_chars, std::strin
set_spec(eol_cmt, eol_cmts);
set_spec(cmt_op, open_cmts);
set_spec(cmt_cl, close_cmts);
set_spec(c_eol_cmt, camel_eol_cmts);
set_spec(c_cmt_op, camel_open_cmts);
set_spec(c_cmt_cl, camel_close_cmts);
for (int c : quote_chars) {
if (c > ' ' && c <= 0x7f) {
char_class[(unsigned)c] |= cc::quote_char;
Expand Down Expand Up @@ -206,24 +211,24 @@ const Lexem& Lexer::next() {
long long comm = 1;
while (!src.seek_eof()) {
int cc = src.cur_char(), nc = src.next_char();
if (cc == eol_cmt[0] || (cc == eol_cmt[1] && nc == eol_cmt[2])) {
if ((cc == eol_cmt[0] || (cc == eol_cmt[1] && nc == eol_cmt[2])) || (cc == c_eol_cmt[0] || (cc == c_eol_cmt[1] && nc == c_eol_cmt[2]))) {
src.load_line();
} else if (cc == cmt_op[1] && nc == cmt_op[2]) {
} else if ((cc == cmt_op[1] && nc == cmt_op[2]) || (cc == c_cmt_op[1] && nc == c_cmt_op[2])) {
src.advance(2);
comm = comm * 2 + 1;
} else if (cc == cmt_op[0]) {
} else if ((cc == cmt_op[0]) || (cc == c_cmt_op[0])) {
src.advance(1);
comm *= 2;
} else if (comm == 1) {
break;
} else if (cc == cmt_cl[1] && nc == cmt_cl[2]) {
} else if ((cc == cmt_cl[1] && nc == cmt_cl[2]) || (cc == c_cmt_cl[1] && nc == c_cmt_cl[2])) {
if (!(comm & 1)) {
src.error(std::string{"a `"} + (char)cmt_op[0] + "` comment closed by `" + (char)cmt_cl[1] + (char)cmt_cl[2] +
"`");
}
comm >>= 1;
src.advance(2);
} else if (cc == cmt_cl[0]) {
} else if ((cc == cmt_cl[0]) || (cc == c_cmt_cl[0])) {
if (!(comm & 1)) {
src.error(std::string{"a `"} + (char)cmt_op[1] + (char)cmt_op[2] + "` comment closed by `" + (char)cmt_cl[0] +
"`");
Expand Down
9 changes: 5 additions & 4 deletions crypto/parser/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,18 @@ class Lexer {
bool eof;
Lexem lexem, peek_lexem;
unsigned char char_class[128];
std::array<int, 3> eol_cmt, cmt_op, cmt_cl;
std::array<int, 3> eol_cmt, cmt_op, cmt_cl, c_eol_cmt, c_cmt_op, c_cmt_cl;
std::string multiline_quote;
enum cc { left_active = 2, right_active = 1, active = 3, allow_repeat = 4, quote_char = 8 };

public:
bool eof_found() const {
return eof;
}
Lexer(SourceReader& _src, bool init = false, std::string active_chars = ";,() ~.", std::string eol_cmts = ";;",
std::string open_cmts = "{-", std::string close_cmts = "-}", std::string quote_chars = "\"",
std::string multiline_quote = "\"\"\"");
Lexer(SourceReader& _src, bool init = false, std::string active_chars = ";,() ~.",
std::string eol_cmts = ";;", std::string open_cmts = "{-", std::string close_cmts = "-}",
std::string camel_eol_cmts = "//", std::string camel_open_cmts = "/*", std::string camel_close_cmts = "*/",
std::string quote_chars = "\"", std::string multiline_quote = "\"\"\"");
const Lexem& next();
const Lexem& cur() const {
return lexem;
Expand Down
Loading