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

Add triple quotes asms (#463)

* Add python-like triple quotes for multiline strings

* Add test for multiline asm

* Allow asm definition duplicate

* Asm duplicate: add test & fixes

* Fix multiline asm

* Fix asm duplicate

Co-authored-by: legaii <jgates.ardux@gmail.com>
This commit is contained in:
EmelyanenkoK 2022-09-22 16:54:26 +03:00 committed by GitHub
parent e913871f4f
commit d23267d996
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 13 deletions

View file

@ -1270,19 +1270,48 @@ SymValAsmFunc* parse_asm_func_body(Lexer& lex, TypeExpr* func_type, const Formal
lex.expect(')');
}
while (lex.tp() == _String) {
asm_ops.push_back(AsmOp::Parse(lex.cur().str, cnt, width));
lex.next();
if (asm_ops.back().is_custom()) {
cnt = width;
std::string ops = lex.cur().str; // <op>\n<op>\n...
std::string op;
for (const char& c : ops) {
if (c == '\n') {
if (!op.empty()) {
asm_ops.push_back(AsmOp::Parse(op, cnt, width));
if (asm_ops.back().is_custom()) {
cnt = width;
}
op.clear();
}
} else {
op.push_back(c);
}
}
if (!op.empty()) {
asm_ops.push_back(AsmOp::Parse(op, cnt, width));
if (asm_ops.back().is_custom()) {
cnt = width;
}
}
lex.next();
}
if (asm_ops.empty()) {
throw src::ParseError{lex.cur().loc, "string with assembler instruction expected"};
}
lex.expect(';');
std::string crc_s;
for (const AsmOp& asm_op : asm_ops) {
crc_s += asm_op.op;
}
crc_s.push_back(impure);
for (const int& x : arg_order) {
crc_s += std::string((const char*) (&x), (const char*) (&x + 1));
}
for (const int& x : ret_order) {
crc_s += std::string((const char*) (&x), (const char*) (&x + 1));
}
auto res = new SymValAsmFunc{func_type, asm_ops, impure};
res->arg_order = std::move(arg_order);
res->ret_order = std::move(ret_order);
res->crc = td::crc64(crc_s);
return res;
}
@ -1448,16 +1477,22 @@ void parse_func_def(Lexer& lex) {
// code->print(std::cerr); // !!!DEBUG!!!
func_sym_code->code = code;
} else {
Lexem asm_lexem = lex.cur();
SymValAsmFunc* asm_func = parse_asm_func_body(lex, func_type, arg_list, ret_type, impure);
if (func_sym_val) {
if (dynamic_cast<SymValCodeFunc*>(func_sym_val)) {
lex.cur().error("function `"s + func_name.str + "` was already declared as an ordinary function");
asm_lexem.error("function `"s + func_name.str + "` was already declared as an ordinary function");
}
if (dynamic_cast<SymValAsmFunc*>(func_sym_val)) {
lex.cur().error("redefinition of built-in assembler function `"s + func_name.str + "`");
SymValAsmFunc* asm_func_old = dynamic_cast<SymValAsmFunc*>(func_sym_val);
if (asm_func_old) {
if (asm_func->crc != asm_func_old->crc) {
asm_lexem.error("redefinition of built-in assembler function `"s + func_name.str + "`");
}
} else {
asm_lexem.error("redefinition of previously (somehow) defined function `"s + func_name.str + "`");
}
lex.cur().error("redefinition of previously (somehow) defined function `"s + func_name.str + "`");
}
func_sym->value = parse_asm_func_body(lex, func_type, arg_list, ret_type, impure);
func_sym->value = asm_func;
}
if (method_id.not_null()) {
auto val = dynamic_cast<SymVal*>(func_sym->value);