Add a constraint field to type_sig
This commit is contained in:
parent
6551690dff
commit
244ef6a6e2
@ -81,7 +81,9 @@
|
|||||||
-type type() :: aeso_syntax:type().
|
-type type() :: aeso_syntax:type().
|
||||||
-type name() :: string().
|
-type name() :: string().
|
||||||
-type qname() :: [string()].
|
-type qname() :: [string()].
|
||||||
-type typesig() :: {type_sig, aeso_syntax:ann(), [aeso_syntax:named_arg_t()], [type()], type()}.
|
-type typesig() :: {type_sig, aeso_syntax:ann(), type_constraints(), [aeso_syntax:named_arg_t()], [type()], type()}.
|
||||||
|
|
||||||
|
-type type_constraints() :: none.
|
||||||
|
|
||||||
-type fun_info() :: {aeso_syntax:ann(), typesig() | type()}.
|
-type fun_info() :: {aeso_syntax:ann(), typesig() | type()}.
|
||||||
-type type_info() :: {aeso_syntax:ann(), typedef()}.
|
-type type_info() :: {aeso_syntax:ann(), typedef()}.
|
||||||
@ -206,7 +208,7 @@ bind_state(Env) ->
|
|||||||
false -> Unit
|
false -> Unit
|
||||||
end,
|
end,
|
||||||
Env1 = bind_funs([{"state", State},
|
Env1 = bind_funs([{"state", State},
|
||||||
{"put", {type_sig, [stateful | Ann], [], [State], Unit}}], Env),
|
{"put", {type_sig, [stateful | Ann], none, [], [State], Unit}}], Env),
|
||||||
|
|
||||||
case lookup_type(Env, {id, Ann, "event"}) of
|
case lookup_type(Env, {id, Ann, "event"}) of
|
||||||
{E, _} ->
|
{E, _} ->
|
||||||
@ -370,16 +372,16 @@ global_env() ->
|
|||||||
Option = fun(T) -> {app_t, Ann, {id, Ann, "option"}, [T]} end,
|
Option = fun(T) -> {app_t, Ann, {id, Ann, "option"}, [T]} end,
|
||||||
Map = fun(A, B) -> {app_t, Ann, {id, Ann, "map"}, [A, B]} end,
|
Map = fun(A, B) -> {app_t, Ann, {id, Ann, "map"}, [A, B]} end,
|
||||||
Pair = fun(A, B) -> {tuple_t, Ann, [A, B]} end,
|
Pair = fun(A, B) -> {tuple_t, Ann, [A, B]} end,
|
||||||
Fun = fun(Ts, T) -> {type_sig, Ann, [], Ts, T} end,
|
Fun = fun(Ts, T) -> {type_sig, Ann, none, [], Ts, T} end,
|
||||||
Fun1 = fun(S, T) -> Fun([S], T) end,
|
Fun1 = fun(S, T) -> Fun([S], T) end,
|
||||||
%% Lambda = fun(Ts, T) -> {fun_t, Ann, [], Ts, T} end,
|
%% Lambda = fun(Ts, T) -> {fun_t, Ann, [], Ts, T} end,
|
||||||
%% Lambda1 = fun(S, T) -> Lambda([S], T) end,
|
%% Lambda1 = fun(S, T) -> Lambda([S], T) end,
|
||||||
StateFun = fun(Ts, T) -> {type_sig, [stateful|Ann], [], Ts, T} end,
|
StateFun = fun(Ts, T) -> {type_sig, [stateful|Ann], none, [], Ts, T} end,
|
||||||
TVar = fun(X) -> {tvar, Ann, "'" ++ X} end,
|
TVar = fun(X) -> {tvar, Ann, "'" ++ X} end,
|
||||||
SignId = {id, Ann, "signature"},
|
SignId = {id, Ann, "signature"},
|
||||||
SignDef = {bytes, Ann, <<0:64/unit:8>>},
|
SignDef = {bytes, Ann, <<0:64/unit:8>>},
|
||||||
Signature = {named_arg_t, Ann, SignId, SignId, {typed, Ann, SignDef, SignId}},
|
Signature = {named_arg_t, Ann, SignId, SignId, {typed, Ann, SignDef, SignId}},
|
||||||
SignFun = fun(Ts, T) -> {type_sig, [stateful|Ann], [Signature], Ts, T} end,
|
SignFun = fun(Ts, T) -> {type_sig, [stateful|Ann], none, [Signature], Ts, T} end,
|
||||||
TTL = {qid, Ann, ["Chain", "ttl"]},
|
TTL = {qid, Ann, ["Chain", "ttl"]},
|
||||||
Fee = Int,
|
Fee = Int,
|
||||||
[A, Q, R, K, V] = lists:map(TVar, ["a", "q", "r", "k", "v"]),
|
[A, Q, R, K, V] = lists:map(TVar, ["a", "q", "r", "k", "v"]),
|
||||||
@ -669,7 +671,7 @@ check_typedef_sccs(Env, TypeMap, [{acyclic, Name} | SCCs], Acc) ->
|
|||||||
check_typedef_sccs(Env2, TypeMap, SCCs, Acc1);
|
check_typedef_sccs(Env2, TypeMap, SCCs, Acc1);
|
||||||
{variant_t, Cons} ->
|
{variant_t, Cons} ->
|
||||||
Target = check_type(Env1, app_t(Ann, D, Xs)),
|
Target = check_type(Env1, app_t(Ann, D, Xs)),
|
||||||
ConType = fun([]) -> Target; (Args) -> {type_sig, Ann, [], Args, Target} end,
|
ConType = fun([]) -> Target; (Args) -> {type_sig, Ann, none, [], Args, Target} end,
|
||||||
ConTypes = [ begin
|
ConTypes = [ begin
|
||||||
{constr_t, _, {con, _, Con}, Args} = ConDef,
|
{constr_t, _, {con, _, Con}, Args} = ConDef,
|
||||||
{Con, ConType(Args)}
|
{Con, ConType(Args)}
|
||||||
@ -842,7 +844,7 @@ check_constructor_overlap(Env, Con = {con, Ann, Name}, NewType) ->
|
|||||||
case lookup_env(Env, term, Ann, Name) of
|
case lookup_env(Env, term, Ann, Name) of
|
||||||
false -> ok;
|
false -> ok;
|
||||||
{_, {Ann, Type}} ->
|
{_, {Ann, Type}} ->
|
||||||
OldType = case Type of {type_sig, _, _, _, T} -> T;
|
OldType = case Type of {type_sig, _, _, _, _, T} -> T;
|
||||||
_ -> Type end,
|
_ -> Type end,
|
||||||
OldCon = {con, Ann, Name},
|
OldCon = {con, Ann, Name},
|
||||||
type_error({repeated_constructor, [{OldCon, OldType}, {Con, NewType}]})
|
type_error({repeated_constructor, [{OldCon, OldType}, {Con, NewType}]})
|
||||||
@ -884,10 +886,10 @@ check_reserved_entrypoints(Funs) ->
|
|||||||
-spec check_fundecl(env(), aeso_syntax:decl()) -> {{name(), typesig()}, aeso_syntax:decl()}.
|
-spec check_fundecl(env(), aeso_syntax:decl()) -> {{name(), typesig()}, aeso_syntax:decl()}.
|
||||||
check_fundecl(Env, {fun_decl, Ann, Id = {id, _, Name}, Type = {fun_t, _, _, _, _}}) ->
|
check_fundecl(Env, {fun_decl, Ann, Id = {id, _, Name}, Type = {fun_t, _, _, _, _}}) ->
|
||||||
Type1 = {fun_t, _, Named, Args, Ret} = check_type(Env, Type),
|
Type1 = {fun_t, _, Named, Args, Ret} = check_type(Env, Type),
|
||||||
{{Name, {type_sig, Ann, Named, Args, Ret}}, {fun_decl, Ann, Id, Type1}};
|
{{Name, {type_sig, Ann, none, Named, Args, Ret}}, {fun_decl, Ann, Id, Type1}};
|
||||||
check_fundecl(Env, {fun_decl, Ann, Id = {id, _, Name}, Type}) ->
|
check_fundecl(Env, {fun_decl, Ann, Id = {id, _, Name}, Type}) ->
|
||||||
type_error({fundecl_must_have_funtype, Ann, Id, Type}),
|
type_error({fundecl_must_have_funtype, Ann, Id, Type}),
|
||||||
{{Name, {type_sig, Ann, [], [], Type}}, check_type(Env, Type)}.
|
{{Name, {type_sig, Ann, none, [], [], Type}}, check_type(Env, Type)}.
|
||||||
|
|
||||||
infer_nonrec(Env, LetFun) ->
|
infer_nonrec(Env, LetFun) ->
|
||||||
create_constraints(),
|
create_constraints(),
|
||||||
@ -901,7 +903,7 @@ infer_nonrec(Env, LetFun) ->
|
|||||||
|
|
||||||
%% Currenty only the init function.
|
%% Currenty only the init function.
|
||||||
check_special_funs(Env, {{"init", Type}, _}) ->
|
check_special_funs(Env, {{"init", Type}, _}) ->
|
||||||
{type_sig, Ann, _Named, _Args, Res} = Type,
|
{type_sig, Ann, _Constr, _Named, _Args, Res} = Type,
|
||||||
State =
|
State =
|
||||||
%% We might have implicit (no) state.
|
%% We might have implicit (no) state.
|
||||||
case lookup_type(Env, {id, [], "state"}) of
|
case lookup_type(Env, {id, [], "state"}) of
|
||||||
@ -911,7 +913,8 @@ check_special_funs(Env, {{"init", Type}, _}) ->
|
|||||||
unify(Env, Res, State, {checking_init_type, Ann});
|
unify(Env, Res, State, {checking_init_type, Ann});
|
||||||
check_special_funs(_, _) -> ok.
|
check_special_funs(_, _) -> ok.
|
||||||
|
|
||||||
typesig_to_fun_t({type_sig, Ann, Named, Args, Res}) -> {fun_t, Ann, Named, Args, Res}.
|
typesig_to_fun_t({type_sig, Ann, _Constr, Named, Args, Res}) ->
|
||||||
|
{fun_t, Ann, Named, Args, Res}.
|
||||||
|
|
||||||
infer_letrec(Env, Defs) ->
|
infer_letrec(Env, Defs) ->
|
||||||
create_constraints(),
|
create_constraints(),
|
||||||
@ -945,7 +948,7 @@ infer_letfun(Env0, {letfun, Attrib, Fun = {id, NameAttrib, Name}, Args, What, Bo
|
|||||||
NewArgs = [{arg, A1, {id, A2, ArgName}, T}
|
NewArgs = [{arg, A1, {id, A2, ArgName}, T}
|
||||||
|| {{_, T}, {arg, A1, {id, A2, ArgName}, _}} <- lists:zip(ArgTypes, Args)],
|
|| {{_, T}, {arg, A1, {id, A2, ArgName}, _}} <- lists:zip(ArgTypes, Args)],
|
||||||
NamedArgs = [],
|
NamedArgs = [],
|
||||||
TypeSig = {type_sig, Attrib, NamedArgs, [T || {arg, _, _, T} <- NewArgs], ResultType},
|
TypeSig = {type_sig, Attrib, none, NamedArgs, [T || {arg, _, _, T} <- NewArgs], ResultType},
|
||||||
{{Name, TypeSig},
|
{{Name, TypeSig},
|
||||||
{letfun, Attrib, {id, NameAttrib, Name}, NewArgs, ResultType, NewBody}}.
|
{letfun, Attrib, {id, NameAttrib, Name}, NewArgs, ResultType, NewBody}}.
|
||||||
|
|
||||||
@ -981,14 +984,14 @@ lookup_name(Env, As, Id, Options) ->
|
|||||||
Freshen = proplists:get_value(freshen, Options, false),
|
Freshen = proplists:get_value(freshen, Options, false),
|
||||||
check_stateful(Env, Id, Ty),
|
check_stateful(Env, Id, Ty),
|
||||||
Ty1 = case Ty of
|
Ty1 = case Ty of
|
||||||
{type_sig, _, _, _, _} -> freshen_type(As, typesig_to_fun_t(Ty));
|
{type_sig, _, _, _, _, _} -> freshen_type_sig(As, Ty);
|
||||||
_ when Freshen -> freshen_type(As, Ty);
|
_ when Freshen -> freshen_type(As, Ty);
|
||||||
_ -> Ty
|
_ -> Ty
|
||||||
end,
|
end,
|
||||||
{set_qname(QId, Id), Ty1}
|
{set_qname(QId, Id), Ty1}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
check_stateful(#env{ stateful = false, current_function = Fun }, Id, Type = {type_sig, _, _, _, _}) ->
|
check_stateful(#env{ stateful = false, current_function = Fun }, Id, Type = {type_sig, _, _, _, _, _}) ->
|
||||||
case aeso_syntax:get_ann(stateful, Type, false) of
|
case aeso_syntax:get_ann(stateful, Type, false) of
|
||||||
false -> ok;
|
false -> ok;
|
||||||
true ->
|
true ->
|
||||||
@ -1803,8 +1806,8 @@ unfold_types(Env, {typed, Attr, E, Type}, Options) ->
|
|||||||
{typed, Attr, unfold_types(Env, E, Options), unfold_types_in_type(Env, Type, Options)};
|
{typed, Attr, unfold_types(Env, E, Options), unfold_types_in_type(Env, Type, Options)};
|
||||||
unfold_types(Env, {arg, Attr, Id, Type}, Options) ->
|
unfold_types(Env, {arg, Attr, Id, Type}, Options) ->
|
||||||
{arg, Attr, Id, unfold_types_in_type(Env, Type, Options)};
|
{arg, Attr, Id, unfold_types_in_type(Env, Type, Options)};
|
||||||
unfold_types(Env, {type_sig, Ann, NamedArgs, Args, Ret}, Options) ->
|
unfold_types(Env, {type_sig, Ann, Constr, NamedArgs, Args, Ret}, Options) ->
|
||||||
{type_sig, Ann,
|
{type_sig, Ann, Constr,
|
||||||
unfold_types_in_type(Env, NamedArgs, Options),
|
unfold_types_in_type(Env, NamedArgs, Options),
|
||||||
unfold_types_in_type(Env, Args, Options),
|
unfold_types_in_type(Env, Args, Options),
|
||||||
unfold_types_in_type(Env, Ret, Options)};
|
unfold_types_in_type(Env, Ret, Options)};
|
||||||
@ -2032,6 +2035,13 @@ freshen(Ann, [A | B]) ->
|
|||||||
freshen(_, X) ->
|
freshen(_, X) ->
|
||||||
X.
|
X.
|
||||||
|
|
||||||
|
freshen_type_sig(Ann, TypeSig = {type_sig, _, Constr, _, _, _}) ->
|
||||||
|
FunT = freshen_type(Ann, typesig_to_fun_t(TypeSig)),
|
||||||
|
apply_typesig_constraint(Ann, Constr, FunT),
|
||||||
|
FunT.
|
||||||
|
|
||||||
|
apply_typesig_constraint(_Ann, none, _FunT) -> ok.
|
||||||
|
|
||||||
%% Dereferences all uvars and replaces the uninstantiated ones with a
|
%% Dereferences all uvars and replaces the uninstantiated ones with a
|
||||||
%% succession of tvars.
|
%% succession of tvars.
|
||||||
instantiate(E) ->
|
instantiate(E) ->
|
||||||
@ -2443,7 +2453,7 @@ if_branches(If = {'if', Ann, _, Then, Else}) ->
|
|||||||
end;
|
end;
|
||||||
if_branches(E) -> [E].
|
if_branches(E) -> [E].
|
||||||
|
|
||||||
pp_typed(Label, E, T = {type_sig, _, _, _, _}) -> pp_typed(Label, E, typesig_to_fun_t(T));
|
pp_typed(Label, E, T = {type_sig, _, _, _, _, _}) -> pp_typed(Label, E, typesig_to_fun_t(T));
|
||||||
pp_typed(Label, {typed, _, Expr, _}, Type) ->
|
pp_typed(Label, {typed, _, Expr, _}, Type) ->
|
||||||
pp_typed(Label, Expr, Type);
|
pp_typed(Label, Expr, Type);
|
||||||
pp_typed(Label, Expr, Type) ->
|
pp_typed(Label, Expr, Type) ->
|
||||||
@ -2475,7 +2485,7 @@ pp_loc(T) ->
|
|||||||
plural(No, _Yes, [_]) -> No;
|
plural(No, _Yes, [_]) -> No;
|
||||||
plural(_No, Yes, _) -> Yes.
|
plural(_No, Yes, _) -> Yes.
|
||||||
|
|
||||||
pp(T = {type_sig, _, _, _, _}) ->
|
pp(T = {type_sig, _, _, _, _, _}) ->
|
||||||
pp(typesig_to_fun_t(T));
|
pp(typesig_to_fun_t(T));
|
||||||
pp([]) ->
|
pp([]) ->
|
||||||
"";
|
"";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user