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

updated func/fift

- updated func/fift
- updated liteclient/liteserver
- bugfixes
This commit is contained in:
ton 2019-12-29 12:14:12 +03:00
parent d41ce55305
commit acf16718e6
45 changed files with 1360 additions and 185 deletions

View file

@ -174,6 +174,53 @@ FormalArg parse_formal_arg(Lexer& lex, int fa_idx) {
return std::make_tuple(arg_type, new_sym_def, loc);
}
void parse_global_var_decl(Lexer& lex) {
TypeExpr* var_type = 0;
SrcLocation loc = lex.cur().loc;
if (lex.tp() == '_') {
lex.next();
var_type = TypeExpr::new_hole();
loc = lex.cur().loc;
} else if (lex.tp() != _Ident) {
var_type = parse_type(lex);
} else {
auto sym = sym::lookup_symbol(lex.cur().val);
if (sym && dynamic_cast<SymValType*>(sym->value)) {
auto val = dynamic_cast<SymValType*>(sym->value);
lex.next();
var_type = val->get_type();
} else {
var_type = TypeExpr::new_hole();
}
}
if (lex.tp() != _Ident) {
lex.expect(_Ident, "global variable name");
}
loc = lex.cur().loc;
SymDef* sym_def = sym::define_global_symbol(lex.cur().val, false, loc);
if (!sym_def) {
lex.cur().error_at("cannot define global symbol `", "`");
}
if (sym_def->value) {
auto val = dynamic_cast<SymValGlobVar*>(sym_def->value);
if (!val) {
lex.cur().error_at("symbol `", "` cannot be redefined as a global variable");
}
try {
unify(var_type, val->sym_type);
} catch (UnifyError& ue) {
std::ostringstream os;
os << "cannot unify new type " << var_type << " of global variable `" << sym_def->name()
<< "` with its previous type " << val->sym_type << ": " << ue;
lex.cur().error(os.str());
}
} else {
sym_def->value = new SymValGlobVar{glob_var_cnt++, var_type};
glob_vars.push_back(sym_def);
}
lex.next();
}
FormalArgList parse_formal_args(Lexer& lex) {
FormalArgList args;
lex.expect('(', "formal argument list");
@ -205,6 +252,18 @@ TypeExpr* extract_total_arg_type(const FormalArgList& arg_list) {
return TypeExpr::new_tensor(std::move(type_list));
}
void parse_global_var_decls(Lexer& lex) {
lex.expect(_Global);
while (true) {
parse_global_var_decl(lex);
if (lex.tp() != ',') {
break;
}
lex.expect(',');
}
lex.expect(';');
}
SymValCodeFunc* make_new_glob_func(SymDef* func_sym, TypeExpr* func_type, bool impure = false) {
SymValCodeFunc* res = new SymValCodeFunc{glob_func_cnt, func_type, impure};
func_sym->value = res;
@ -239,6 +298,22 @@ bool check_global_func(const Lexem& cur, sym_idx_t func_name = 0) {
}
}
Expr* make_func_apply(Expr* fun, Expr* x) {
Expr* res;
if (fun->cls == Expr::_Glob) {
if (x->cls == Expr::_Tuple) {
res = new Expr{Expr::_Apply, fun->sym, x->args};
} else {
res = new Expr{Expr::_Apply, fun->sym, {x}};
}
res->flags = Expr::_IsRvalue | (fun->flags & Expr::_IsImpure);
} else {
res = new Expr{Expr::_VarApply, {fun, x}};
res->flags = Expr::_IsRvalue;
}
return res;
}
Expr* parse_expr(Lexer& lex, CodeBlob& code, bool nv = false);
// parse ( E { , E } ) | () | id | num | _
@ -323,6 +398,16 @@ Expr* parse_expr100(Lexer& lex, CodeBlob& code, bool nv) {
lex.next();
return res;
}
if (sym && dynamic_cast<SymValGlobVar*>(sym->value)) {
auto val = dynamic_cast<SymValGlobVar*>(sym->value);
Expr* res = new Expr{Expr::_GlobVar, lex.cur().loc};
res->e_type = val->get_type();
res->sym = sym;
res->flags = Expr::_IsLvalue | Expr::_IsRvalue | Expr::_IsImpure;
lex.next();
return res;
}
bool auto_apply = false;
Expr* res = new Expr{Expr::_Var, lex.cur().loc};
if (nv) {
res->val = ~lex.cur().val;
@ -344,6 +429,7 @@ Expr* parse_expr100(Lexer& lex, CodeBlob& code, bool nv) {
} else if (val->type == SymVal::_Func) {
res->e_type = val->get_type();
res->cls = Expr::_Glob;
auto_apply = val->auto_apply;
} else if (val->idx < 0) {
lex.cur().error_at("accessing variable `", "` being defined");
} else {
@ -354,6 +440,12 @@ Expr* parse_expr100(Lexer& lex, CodeBlob& code, bool nv) {
// std::cerr << "accessing symbol " << lex.cur().str << " : " << res->e_type << (val->impure ? " (impure)" : " (pure)") << std::endl;
res->flags = Expr::_IsLvalue | Expr::_IsRvalue | (val->impure ? Expr::_IsImpure : 0);
}
if (auto_apply) {
int impure = res->flags & Expr::_IsImpure;
delete res;
res = new Expr{Expr::_Apply, sym, {}};
res->flags = Expr::_IsRvalue | impure;
}
res->deduce_type(lex.cur());
lex.next();
return res;
@ -362,22 +454,6 @@ Expr* parse_expr100(Lexer& lex, CodeBlob& code, bool nv) {
return nullptr;
}
Expr* make_func_apply(Expr* fun, Expr* x) {
Expr* res;
if (fun->cls == Expr::_Glob) {
if (x->cls == Expr::_Tuple) {
res = new Expr{Expr::_Apply, fun->sym, x->args};
} else {
res = new Expr{Expr::_Apply, fun->sym, {x}};
}
res->flags = Expr::_IsRvalue | (fun->flags & Expr::_IsImpure);
} else {
res = new Expr{Expr::_VarApply, {fun, x}};
res->flags = Expr::_IsRvalue;
}
return res;
}
// parse E { E }
Expr* parse_expr90(Lexer& lex, CodeBlob& code, bool nv) {
Expr* res = parse_expr100(lex, code, nv);
@ -1193,7 +1269,11 @@ bool parse_source(std::istream* is, const src::FileDescr* fdescr) {
src::SourceReader reader{is, fdescr};
Lexer lex{reader, true};
while (lex.tp() != _Eof) {
parse_func_def(lex);
if (lex.tp() == _Global) {
parse_global_var_decls(lex);
} else {
parse_func_def(lex);
}
}
return true;
}