Compare commits

..

19 Commits

Author SHA1 Message Date
Radosław Rowicki d14a0025f2 Merge branch 'master' into radrow-patch-2 2019-09-02 12:09:53 +02:00
Radosław Rowicki fe0c22851f Update CHANGELOG.md 2019-09-02 12:08:01 +02:00
Thomas Arts a50730155f Merge pull request #138 from aeternity/aens-at-full-node-ver-ta
Compile name fee in contracts
2019-09-02 11:07:59 +02:00
Thomas Arts e9f717a17b Update src/aeso_ast_to_icode.erl
Co-Authored-By: Ulf Norell <ulf.norell@gmail.com>
2019-09-02 10:21:35 +02:00
Ulf Norell 97ff1aac23 Merge pull request #136 from radrow/stdlib-extensions
Updated some functions, renamed some stuff, added from_to IN STDLIB
2019-09-02 09:56:56 +02:00
sennui 1ee5a57924 change aebytecode version, aeserialization and add enacl 2019-09-02 08:54:38 +02:00
Thomas Arts cf91a27fb2 Keep sign last 2019-09-01 10:58:49 +02:00
sennui 83d06977f9 add extra argument to claim for bidding 2019-09-01 10:58:49 +02:00
Ulf Norell 41e59506ba Merge pull request #137 from aeternity/polymorpism-checks
Polymorphism checks
2019-08-30 15:48:34 +02:00
Ulf Norell 062309e578 Type variables mentioned in local functions should not be flexible
(cc #112)
2019-08-30 14:22:31 +02:00
Radosław Rowicki 6408969cd3 Remove from_to_ 2019-08-30 14:06:46 +02:00
Radosław Rowicki 71a556ce81 nth update 2019-08-30 13:46:02 +02:00
Radosław Rowicki 256aadd575 [......]
Co-Authored-By: Ulf Norell <ulf.norell@gmail.com>
2019-08-30 13:44:26 +02:00
Ulf Norell f27ba528d8 aebytecode commit 2019-08-30 11:21:26 +02:00
Ulf Norell 6fd39d4cb1 Add checks for polymorphic/higher order oracles and higher order entrypoints (AEVM) 2019-08-30 11:18:20 +02:00
Ulf Norell 1ce95b32ac Add checks for polymorphic/higher order oracles and higher order entrypoints (FATE) 2019-08-30 11:18:20 +02:00
radrow 076d635dbe Fix errors 2019-08-29 15:32:10 +02:00
radrow 1d962f2001 Updated some functions, renamed, added from_to 2019-08-29 13:41:04 +02:00
Radosław Rowicki 1fbfe418c7 Update CHANGELOG.md 2019-08-22 14:23:15 +02:00
14 changed files with 158 additions and 93 deletions
+1
View File
@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Standard library support. `ListInternal` can be included implicitly if list comprehensions are used.
- Added the `[a..b]` language construct, returning the list of numbers between
`a` and `b` (inclusive). Returns the empty list if `a` > `b`.
### Changed
+29 -17
View File
@@ -32,14 +32,16 @@ namespace List =
[] => reverse(acc)
h::t => find_indices_(p, t, n+1, if(p(h)) n::acc else acc)
function nth(n : int, l : list('a)) : option('a) = switch(l)
[] => None
h::t => if(n == 0) Some(h) else nth(n-1, t)
function nth(n : int, l : list('a)) : option('a) =
switch(l)
[] => None
h::t => if(n == 0) Some(h) else nth(n-1, t)
/* Unsafe version of `nth` */
function get(n : int, l : list('a)) : 'a = switch(l)
[] => abort("Out of index get")
h::t => if(n == 0) h else get(n-1, t)
function get(n : int, l : list('a)) : 'a =
switch(l)
[] => abort(if(n < 0) "Negative index get" else "Out of index get")
h::t => if(n == 0) h else get(n-1, t)
function length(l : list('a)) : int = length_(l, 0)
@@ -48,6 +50,13 @@ namespace List =
_::t => length_(t, acc + 1)
function from_to(a : int, b : int) : list(int) = [a..b]
function from_to_step(a : int, b : int, s : int) : list(int) = from_to_step_(a, b, s, [])
private function from_to_step_(a, b, s, acc) =
if (a > b) reverse(acc) else from_to_step_(a + s, b, s, a :: acc)
/* Unsafe. Replaces `n`th element of `l` with `e`. Crashes on over/underflow */
function replace_at(n : int, e : 'a, l : list('a)) : list('a) =
if(n<0) abort("insert_at underflow") else replace_at_(n, e, l, [])
@@ -66,14 +75,17 @@ namespace List =
[] => abort("insert_at overflow")
h::t => insert_at_(n-1, e, t, h::acc)
function insert_by(f : (('a, 'a) => bool), x : 'a, l : list('a)) : list('a) =
function insert_by(cmp : (('a, 'a) => bool), x : 'a, l : list('a)) : list('a) =
insert_by_(cmp, x, l, [])
private function insert_by_(cmp : (('a, 'a) => bool), x : 'a, l : list('a), acc : list('a)) : list('a) =
switch(l)
[] => [x]
(e :: l') =>
if(f(x, e))
e :: insert_by(f, x, l')
[] => reverse(x::acc)
h::t =>
if(cmp(x, h)) // x < h
reverse(acc) ++ (x::l)
else
x :: l
insert_by_(cmp, x, t, h::acc)
function foldr(cons : ('a, 'b) => 'b, nil : 'b, l : list('a)) : 'b = switch(l)
[] => nil
@@ -83,12 +95,12 @@ namespace List =
[] => acc
h::t => foldl(rcons, rcons(acc, h), t)
function foreach(f : 'a => unit, l : list('a)) : unit =
function foreach(l : list('a), f : 'a => unit) : unit =
switch(l)
[] => ()
e :: l' =>
[] => ()
e::l' =>
f(e)
foreach(f, l')
foreach(l', f)
function reverse(l : list('a)) : list('a) = foldl((lst, el) => el :: lst, [], l)
@@ -144,7 +156,7 @@ namespace List =
h::t => if(p(h)) partition_(p, t, h::acc_t, acc_f) else partition_(p, t, acc_t, h::acc_f)
function concats(ll : list(list('a))) : list('a) = foldr((l1, l2) => l1 ++ l2, [], ll)
function flatten(ll : list(list('a))) : list('a) = foldr((l1, l2) => l1 ++ l2, [], ll)
function all(p : 'a => bool, l : list('a)) : bool = switch(l)
[] => true
+1 -1
View File
@@ -19,7 +19,7 @@ namespace Option =
function force(o : option('a)) : 'a = default(abort("Forced None value"), o)
function on_elem(f : 'a => unit, o : option('a)) : unit = match((), f, o)
function on_elem(o : option('a), f : 'a => unit) : unit = match((), f, o)
function map(f : 'a => 'b, o : option('a)) : option('b) = switch(o)
None => None
+1 -1
View File
@@ -2,7 +2,7 @@
{erl_opts, [debug_info]}.
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"3f85375"}}}
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"72b2a58"}}}
, {getopt, "1.0.1"}
, {eblake2, "1.0.0"}
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
+6 -2
View File
@@ -1,17 +1,21 @@
{"1.1.0",
[{<<"aebytecode">>,
{git,"https://github.com/aeternity/aebytecode.git",
{ref,"3f85375cb2288083e442541d5b53f9705f22053a"}},
{ref,"72b2a581d5a6d488a208331da88de1a488ac2da1"}},
0},
{<<"aeserialization">>,
{git,"https://github.com/aeternity/aeserialization.git",
{ref,"816bf994ffb5cee218c3f22dc5fea296c9e0882e"}},
{ref,"47aaa8f5434b365c50a35bfd1490340b19241991"}},
1},
{<<"base58">>,
{git,"https://github.com/aeternity/erl-base58.git",
{ref,"60a335668a60328a29f9731b67c4a0e9e3d50ab6"}},
2},
{<<"eblake2">>,{pkg,<<"eblake2">>,<<"1.0.0">>},0},
{<<"enacl">>,
{git,"https://github.com/aeternity/enacl.git",
{ref,"26180f42c0b3a450905d2efd8bc7fd5fd9cece75"}},
2},
{<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},0},
{<<"jsx">>,
{git,"https://github.com/talentdeficit/jsx.git",
+3 -4
View File
@@ -443,10 +443,9 @@ global_env() ->
{ funs = MkDefs(
[{"resolve", Fun([String, String], option_t(Ann, A))},
{"preclaim", SignFun([Address, Hash], Unit)},
{"claim", SignFun([Address, String, Int], Unit)},
{"claim", SignFun([Address, String, Int, Int], Unit)},
{"transfer", SignFun([Address, Address, String], Unit)},
{"revoke", SignFun([Address, String], Unit)},
{"subname", SignFun([Address, String, Map(Q, Map(K, A))], Unit)}]) },
{"revoke", SignFun([Address, String], Unit)}]) },
MapScope = #scope
{ funs = MkDefs(
@@ -1328,7 +1327,7 @@ infer_block(Env, _, [E], BlockType) ->
[check_expr(Env, E, BlockType)];
infer_block(Env, Attrs, [Def={letfun, Ann, _, _, _, _}|Rest], BlockType) ->
{{Name, TypeSig}, LetFun} = infer_letfun(Env, Def),
FunT = freshen_type(Ann, typesig_to_fun_t(TypeSig)),
FunT = typesig_to_fun_t(TypeSig),
NewE = bind_var({id, Ann, Name}, FunT, Env),
[LetFun|infer_block(NewE, Attrs, Rest, BlockType)];
infer_block(Env, _, [{letval, Attrs, Pattern, Type, E}|Rest], BlockType) ->
+49 -4
View File
@@ -185,8 +185,8 @@ builtins() ->
{["Oracle"], [{"register", 4}, {"query_fee", 1}, {"query", 5}, {"get_question", 2},
{"respond", 4}, {"extend", 3}, {"get_answer", 2},
{"check", 1}, {"check_query", 2}]},
{["AENS"], [{"resolve", 2}, {"preclaim", 3}, {"claim", 4}, {"transfer", 4},
{"revoke", 3}, {"subname", 3}]},
{["AENS"], [{"resolve", 2}, {"preclaim", 3}, {"claim", 5}, {"transfer", 4},
{"revoke", 3}]},
{["Map"], [{"from_list", 1}, {"to_list", 1}, {"lookup", 2},
{"lookup_default", 3}, {"delete", 2}, {"member", 2}, {"size", 1}]},
{["Crypto"], [{"verify_sig", 3}, {"verify_sig_secp256k1", 3},
@@ -282,10 +282,13 @@ decl_to_fcode(Env = #{ functions := Funs }, {letfun, Ann, {id, _, Name}, Args, R
Attrs = get_attributes(Ann),
FName = lookup_fun(Env, qname(Env, Name)),
FArgs = args_to_fcode(Env, Args),
FRet = type_to_fcode(Env, Ret),
FBody = expr_to_fcode(Env#{ vars => [X || {X, _} <- FArgs] }, Body),
[ ensure_first_order_entrypoint(Ann, FArgs, FRet)
|| aeso_syntax:get_ann(entrypoint, Ann, false) ],
Def = #{ attrs => Attrs,
args => FArgs,
return => type_to_fcode(Env, Ret),
return => FRet,
body => FBody },
NewFuns = Funs#{ FName => Def },
Env#{ functions := NewFuns }.
@@ -510,7 +513,7 @@ expr_to_fcode(Env, _Type, {app, _Ann, {Op, _}, [A]}) when is_atom(Op) ->
end;
%% Function calls
expr_to_fcode(Env, Type, {app, _Ann, Fun = {typed, _, _, {fun_t, _, NamedArgsT, _, _}}, Args}) ->
expr_to_fcode(Env, Type, {app, _, Fun = {typed, _, _, {fun_t, _, NamedArgsT, _, _}}, Args}) ->
Args1 = get_named_args(NamedArgsT, Args),
FArgs = [expr_to_fcode(Env, Arg) || Arg <- Args1],
case expr_to_fcode(Env, Fun) of
@@ -524,11 +527,13 @@ expr_to_fcode(Env, Type, {app, _Ann, Fun = {typed, _, _, {fun_t, _, NamedArgsT,
%% Get the type of the oracle from the args or the expression itself
OType = get_oracle_type(B, Type, Args1),
{oracle, QType, RType} = type_to_fcode(Env, OType),
validate_oracle_type(aeso_syntax:get_ann(Fun), QType, RType),
TypeArgs = [{lit, {typerep, QType}}, {lit, {typerep, RType}}],
builtin_to_fcode(B, FArgs ++ TypeArgs);
{builtin_u, B, _} when B =:= aens_resolve ->
%% Get the type we are assuming the name resolves to
AensType = type_to_fcode(Env, Type),
validate_aens_resolve_type(aeso_syntax:get_ann(Fun), AensType),
TypeArgs = [{lit, {typerep, AensType}}],
builtin_to_fcode(B, FArgs ++ TypeArgs);
{builtin_u, B, _Ar} -> builtin_to_fcode(B, FArgs);
@@ -604,6 +609,46 @@ get_oracle_type(oracle_check, _Type, [{typed, _, _Expr, OType}]) ->
get_oracle_type(oracle_check_query, _Type, [{typed, _, _Expr, OType} | _]) -> OType;
get_oracle_type(oracle_respond, _Type, [_, {typed, _,_Expr, OType} | _]) -> OType.
validate_oracle_type(Ann, QType, RType) ->
ensure_monomorphic(QType, {polymorphic_query_type, Ann, QType}),
ensure_monomorphic(RType, {polymorphic_response_type, Ann, RType}),
ensure_first_order(QType, {higher_order_query_type, Ann, QType}),
ensure_first_order(RType, {higher_order_response_type, Ann, RType}),
ok.
validate_aens_resolve_type(Ann, {variant, [[], [Type]]}) ->
ensure_monomorphic(Type, {polymorphic_aens_resolve, Ann, Type}),
ensure_first_order(Type, {higher_order_aens_resolve, Ann, Type}),
ok.
ensure_first_order_entrypoint(Ann, Args, Ret) ->
[ ensure_first_order(T, {higher_order_entrypoint_argument, Ann, X, T})
|| {X, T} <- Args ],
ensure_first_order(Ret, {higher_order_entrypoint_return, Ann, Ret}),
ok.
ensure_monomorphic(Type, Err) ->
case is_monomorphic(Type) of
true -> ok;
false -> fcode_error(Err)
end.
ensure_first_order(Type, Err) ->
case is_first_order(Type) of
true -> ok;
false -> fcode_error(Err)
end.
is_monomorphic({tvar, _}) -> false;
is_monomorphic(Ts) when is_list(Ts) -> lists:all(fun is_monomorphic/1, Ts);
is_monomorphic(Tup) when is_tuple(Tup) -> is_monomorphic(tuple_to_list(Tup));
is_monomorphic(_) -> true.
is_first_order({function, _, _}) -> false;
is_first_order(Ts) when is_list(Ts) -> lists:all(fun is_first_order/1, Ts);
is_first_order(Tup) when is_tuple(Tup) -> is_first_order(tuple_to_list(Tup));
is_first_order(_) -> true.
%% -- Pattern matching --
-spec alts_to_fcode(env(), ftype(), var_name(), [aeso_syntax:alt()]) -> fsplit().
+48 -37
View File
@@ -93,6 +93,8 @@ contract_to_icode([{letfun, Attrib, Name, Args, _What, Body={typed,_,_,T}}|Rest]
FunAttrs = [ stateful || proplists:get_value(stateful, Attrib, false) ] ++
[ payable || proplists:get_value(payable, Attrib, false) ] ++
[ private || is_private(Attrib, Icode) ],
[ check_entrypoint_type(Attrib, Name, Args, T)
|| aeso_syntax:get_ann(entrypoint, Attrib, false) ],
%% TODO: Handle types
FunName = ast_id(Name),
%% TODO: push funname to env
@@ -105,7 +107,7 @@ contract_to_icode([{letfun, Attrib, Name, Args, _What, Body={typed,_,_,T}}|Rest]
#{ state_type := StateType } = Icode,
{#tuple{ cpts = [type_value(StateType), ast_body(Body, Icode)] },
{tuple, [typerep, ast_typerep(T, Icode)]}};
_ -> {ast_body(Body, Icode), ast_typerep(T, Icode)}
_ -> {ast_body(Body, Icode), ast_typerep1(T, Icode)}
end,
QName = aeso_icode:qualify(Name, Icode),
NewIcode = ast_fun_to_icode(ast_id(QName), FunAttrs, FunArgs, FunBody, TypeRep, Icode),
@@ -121,7 +123,7 @@ ast_id({id, _, Id}) -> Id;
ast_id({qid, _, Id}) -> Id.
ast_args([{arg, _, Name, Type}|Rest], Acc, Icode) ->
ast_args(Rest, [{ast_id(Name), ast_type(Type, Icode)}| Acc], Icode);
ast_args(Rest, [{ast_id(Name), ast_typerep1(Type, Icode)}| Acc], Icode);
ast_args([], Acc, _Icode) -> lists:reverse(Acc).
ast_type(T, Icode) ->
@@ -268,10 +270,10 @@ ast_body(?qid_app(["AENS", "preclaim"], Args, _, _), Icode) ->
[word, word, sign_t()], {tuple, []});
ast_body(?qid_app(["AENS", "claim"], Args, _, _), Icode) ->
{Sign, [Addr, Name, Salt]} = get_signature_arg(Args),
{Sign, [Addr, Name, Salt, NameFee]} = get_signature_arg(Args),
prim_call(?PRIM_CALL_AENS_CLAIM, #integer{value = 0},
[ast_body(Addr, Icode), ast_body(Name, Icode), ast_body(Salt, Icode), ast_body(Sign, Icode)],
[word, string, word, sign_t()], {tuple, []});
[ast_body(Addr, Icode), ast_body(Name, Icode), ast_body(Salt, Icode), ast_body(NameFee, Icode), ast_body(Sign, Icode)],
[word, string, word, word, sign_t()], {tuple, []});
ast_body(?qid_app(["AENS", "transfer"], Args, _, _), Icode) ->
{Sign, [FromAddr, ToAddr, Name]} = get_signature_arg(Args),
@@ -285,18 +287,11 @@ ast_body(?qid_app(["AENS", "revoke"], Args, _, _), Icode) ->
[ast_body(Addr, Icode), ast_body(Name, Icode), ast_body(Sign, Icode)],
[word, word, sign_t()], {tuple, []});
ast_body(?qid_app(["AENS", "subname"], Args, _, _), Icode) ->
{Sign, [Addr, Name, Subnames]} = get_signature_arg(Args),
prim_call(?PRIM_CALL_AENS_SUBNAME, #integer{value = 0},
[ast_body(Addr, Icode), ast_body(Name, Icode), ast_body(Subnames, Icode), ast_body(Sign, Icode)],
[word, word, word, sign_t()], {tuple, []});
ast_body({qid, _, ["AENS", "resolve"]}, _Icode) -> gen_error({underapplied_primitive, 'AENS.resolve'});
ast_body({qid, _, ["AENS", "preclaim"]}, _Icode) -> gen_error({underapplied_primitive, 'AENS.preclaim'});
ast_body({qid, _, ["AENS", "claim"]}, _Icode) -> gen_error({underapplied_primitive, 'AENS.claim'});
ast_body({qid, _, ["AENS", "transfer"]}, _Icode) -> gen_error({underapplied_primitive, 'AENS.transfer'});
ast_body({qid, _, ["AENS", "revoke"]}, _Icode) -> gen_error({underapplied_primitive, 'AENS.revoke'});
ast_body({qid, _, ["AENS", "subname"]}, _Icode) -> gen_error({underapplied_primitive, 'AENS.subname'});
%% Maps
@@ -589,7 +584,7 @@ ast_body({block,As,[E|Rest]}, Icode) ->
#switch{expr=ast_body(E, Icode),
cases=[{#var_ref{name="_"},ast_body({block,As,Rest}, Icode)}]};
ast_body({lam,_,Args,Body}, Icode) ->
#lambda{args=[#arg{name = ast_id(P), type = ast_type(T, Icode)} || {arg,_,P,T} <- Args],
#lambda{args=[#arg{name = ast_id(P), type = ast_typerep1(T, Icode)} || {arg,_,P,T} <- Args],
body=ast_body(Body, Icode)};
ast_body({typed,_,{record,Attrs,Fields},{record_t,DefFields}}, Icode) ->
%% Compile as a tuple with the fields in the order they appear in the definition.
@@ -724,6 +719,22 @@ map_upd(Key, Default, ValFun, Map = {typed, Ann, _, MapType}, Icode) ->
Args = [ast_body(Map, Icode), ast_body(Key, Icode), ast_body(Default, Icode), ast_body(ValFun, Icode)],
builtin_call(FunName, Args).
check_entrypoint_type(Ann, Name, Args, Ret) ->
Check = fun(T, Err) ->
case is_simple_type(T) of
false -> gen_error(Err);
true -> ok
end end,
[ Check(T, {entrypoint_argument_must_have_simple_type, Ann1, Name, X, T})
|| {arg, Ann1, X, T} <- Args ],
Check(Ret, {entrypoint_must_have_simple_return_type, Ann, Name, Ret}).
is_simple_type({tvar, _, _}) -> false;
is_simple_type({fun_t, _, _, _, _}) -> false;
is_simple_type(Ts) when is_list(Ts) -> lists:all(fun is_simple_type/1, Ts);
is_simple_type(T) when is_tuple(T) -> is_simple_type(tuple_to_list(T));
is_simple_type(_) -> true.
is_monomorphic({tvar, _, _}) -> false;
is_monomorphic([H|T]) ->
is_monomorphic(H) andalso is_monomorphic(T);
@@ -764,42 +775,49 @@ make_type_def(Args, Def, Icode = #{ type_vars := TypeEnv }) ->
TVars = [ X || {tvar, _, X} <- Args ],
fun(Types) ->
TypeEnv1 = maps:from_list(lists:zip(TVars, Types)),
ast_typerep(Def, Icode#{ type_vars := maps:merge(TypeEnv, TypeEnv1) })
ast_typerep1(Def, Icode#{ type_vars := maps:merge(TypeEnv, TypeEnv1) })
end.
-spec ast_typerep(aeso_syntax:type()) -> aeb_aevm_data:type().
ast_typerep(Type) -> ast_typerep(Type, aeso_icode:new([])).
ast_typerep(Type) ->
ast_typerep(Type, aeso_icode:new([])).
ast_typerep({id, _, Name}, Icode) ->
ast_typerep(Type, Icode) ->
case is_simple_type(Type) of
false -> gen_error({not_a_simple_type, Type});
true -> ast_typerep1(Type, Icode)
end.
ast_typerep1({id, _, Name}, Icode) ->
lookup_type_id(Name, [], Icode);
ast_typerep({qid, _, Name}, Icode) ->
ast_typerep1({qid, _, Name}, Icode) ->
lookup_type_id(Name, [], Icode);
ast_typerep({con, _, _}, _) ->
ast_typerep1({con, _, _}, _) ->
word; %% Contract type
ast_typerep({bytes_t, _, Len}, _) ->
ast_typerep1({bytes_t, _, Len}, _) ->
bytes_t(Len);
ast_typerep({app_t, _, {I, _, Name}, Args}, Icode) when I =:= id; I =:= qid ->
ArgReps = [ ast_typerep(Arg, Icode) || Arg <- Args ],
ast_typerep1({app_t, _, {I, _, Name}, Args}, Icode) when I =:= id; I =:= qid ->
ArgReps = [ ast_typerep1(Arg, Icode) || Arg <- Args ],
lookup_type_id(Name, ArgReps, Icode);
ast_typerep({tvar,_,A}, #{ type_vars := TypeVars }) ->
ast_typerep1({tvar,_,A}, #{ type_vars := TypeVars }) ->
case maps:get(A, TypeVars, undefined) of
undefined -> word; %% We serialize type variables just as addresses in the originating VM.
Type -> Type
end;
ast_typerep({tuple_t,_,Cpts}, Icode) ->
{tuple, [ast_typerep(C, Icode) || C<-Cpts]};
ast_typerep({record_t,Fields}, Icode) ->
ast_typerep1({tuple_t,_,Cpts}, Icode) ->
{tuple, [ast_typerep1(C, Icode) || C<-Cpts]};
ast_typerep1({record_t,Fields}, Icode) ->
{tuple, [ begin
{field_t, _, _, T} = Field,
ast_typerep(T, Icode)
ast_typerep1(T, Icode)
end || Field <- Fields]};
ast_typerep({fun_t,_,_,_,_}, _Icode) ->
ast_typerep1({fun_t,_,_,_,_}, _Icode) ->
function;
ast_typerep({alias_t, T}, Icode) -> ast_typerep(T, Icode);
ast_typerep({variant_t, Cons}, Icode) ->
ast_typerep1({alias_t, T}, Icode) -> ast_typerep1(T, Icode);
ast_typerep1({variant_t, Cons}, Icode) ->
{variant, [ begin
{constr_t, _, _, Args} = Con,
[ ast_typerep(Arg, Icode) || Arg <- Args ]
[ ast_typerep1(Arg, Icode) || Arg <- Args ]
end || Con <- Cons ]}.
ttl_t(Icode) ->
@@ -848,13 +866,6 @@ type_value({map, K, V}) ->
#tuple{ cpts = [#integer{ value = ?TYPEREP_MAP_TAG },
type_value(K), type_value(V)] }.
%% As abort is a built-in in the future it will be illegal to for
%% users to define abort. For the time being strip away all user
%% defined abort functions.
ast_fun_to_icode("abort", _Atts, _Args, _Body, _TypeRep, Icode) ->
%% Strip away all user defined abort functions.
Icode;
ast_fun_to_icode(Name, Attrs, Args, Body, TypeRep, #{functions := Funs} = Icode) ->
NewFuns = [{Name, Attrs, Args, Body, TypeRep}| Funs],
aeso_icode:set_functions(NewFuns, Icode).
+3 -6
View File
@@ -557,8 +557,8 @@ builtin_to_scode(Env, aens_resolve, [_Name, _Key, _Type] = Args) ->
builtin_to_scode(Env, aens_preclaim, [_Sign, _Account, _Hash] = Args) ->
call_to_scode(Env, [aeb_fate_ops:aens_preclaim(?a, ?a, ?a),
tuple(0)], Args);
builtin_to_scode(Env, aens_claim, [_Sign, _Account, _NameString, _Salt] = Args) ->
call_to_scode(Env, [aeb_fate_ops:aens_claim(?a, ?a, ?a, ?a),
builtin_to_scode(Env, aens_claim, [_Sign, _Account, _NameString, _Salt, _NameFee] = Args) ->
call_to_scode(Env, [aeb_fate_ops:aens_claim(?a, ?a, ?a, ?a, ?a),
tuple(0)], Args);
builtin_to_scode(Env, aens_transfer, [_Sign, _From, _To, _Name] = Args) ->
call_to_scode(Env, [aeb_fate_ops:aens_transfer(?a, ?a, ?a, ?a),
@@ -566,8 +566,6 @@ builtin_to_scode(Env, aens_transfer, [_Sign, _From, _To, _Name] = Args) ->
builtin_to_scode(Env, aens_revoke, [_Sign, _Account, _Name] = Args) ->
call_to_scode(Env, [aeb_fate_ops:aens_revoke(?a, ?a, ?a),
tuple(0)], Args);
builtin_to_scode(Env, aens_subname, [_Sign, _Account, _Name, _Subnames] = Args) ->
call_to_scode(Env, [aeb_fate_ops:aens_subname(?a, ?a, ?a, ?a), tuple(0)], Args);
builtin_to_scode(_Env, auth_tx_hash, []) ->
[aeb_fate_ops:auth_tx_hash(?a)].
@@ -885,11 +883,10 @@ attributes(I) ->
{'ORACLE_QUERY_FEE', A, B} -> Impure(A, [B]);
{'AENS_RESOLVE', A, B, C, D} -> Impure(A, [B, C, D]);
{'AENS_PRECLAIM', A, B, C} -> Impure(none, [A, B, C]);
{'AENS_CLAIM', A, B, C, D} -> Impure(none, [A, B, C, D]);
{'AENS_CLAIM', A, B, C, D, E} -> Impure(none, [A, B, C, D, E]);
'AENS_UPDATE' -> Impure(none, []);%% TODO
{'AENS_TRANSFER', A, B, C, D} -> Impure(none, [A, B, C, D]);
{'AENS_REVOKE', A, B, C} -> Impure(none, [A, B, C]);
{'AENS_SUBNAME', A, B, C} -> Impure(none, [A, B, C]);
{'ABORT', A} -> Impure(pc, A);
{'EXIT', A} -> Impure(pc, A);
'NOP' -> Pure(none, [])
+5 -17
View File
@@ -1,8 +1,6 @@
// AENS tests
contract AENSTest =
type subnames = map(string, map(string, address))
// Name resolution
stateful entrypoint resolve_word(name : string, key : string) : option(address) =
@@ -24,14 +22,16 @@ contract AENSTest =
stateful entrypoint claim(addr : address,
name : string,
salt : int) : unit =
AENS.claim(addr, name, salt)
salt : int,
name_fee : int) : unit =
AENS.claim(addr, name, salt, name_fee)
stateful entrypoint signedClaim(addr : address,
name : string,
salt : int,
name_fee : int,
sign : signature) : unit =
AENS.claim(addr, name, salt, signature = sign)
AENS.claim(addr, name, salt, name_fee, signature = sign)
// TODO: update() -- how to handle pointers?
@@ -54,15 +54,3 @@ contract AENSTest =
name : string,
sign : signature) : unit =
AENS.revoke(owner, name, signature = sign)
stateful entrypoint subname(owner : address,
name : string,
subnames : subnames) : unit =
AENS.subname(owner, name, subnames)
stateful entrypoint signedSubname(owner : address,
name : string,
subnames : subnames,
sign : signature) : unit =
AENS.subname(owner, name, subnames, signature = sign)
+1 -1
View File
@@ -50,7 +50,7 @@ contract ComplexTypes =
entrypoint remote_pair(n : int, s : string) : int * string =
state.worker.pair(gas = 10000, n, s)
entrypoint map(f, xs) =
function map(f, xs) =
switch(xs)
[] => []
x :: xs => f(x) :: map(f, xs)
+7
View File
@@ -0,0 +1,7 @@
contract Fail =
entrypoint tttt() : bool * int =
let f(x : 'a) : 'a = x
(f(true), f(1))
+3 -2
View File
@@ -91,10 +91,11 @@ contract Identity =
// }
// let id(x) = x
// let main(xs) = map(double,xs)
entrypoint z(f,x) = x
function z(f,x) = x
function s(n) = (f,x)=>f(n(f,x))
function add(m,n) = (f,x)=>m(f,n(f,x))
entrypoint main(_) =
entrypoint main() =
let three=s(s(s(z)))
add(three,three)
(((i)=>i+1),0)
+1 -1
View File
@@ -1,6 +1,6 @@
contract TuplesMatch =
entrypoint tuplify3() = (t) => switch(t)
function tuplify3() = (t) => switch(t)
(x, y, z) => 3
entrypoint fst(p : int * string) =