Fix error messages for some illegal constructions, fix absolute path includes #742
@ -2262,6 +2262,22 @@ mk_t_err(Pos, Msg) ->
|
|||||||
mk_t_err(Pos, Msg, Ctxt) ->
|
mk_t_err(Pos, Msg, Ctxt) ->
|
||||||
aeso_errors:new(type_error, Pos, lists:flatten(Msg), lists:flatten(Ctxt)).
|
aeso_errors:new(type_error, Pos, lists:flatten(Msg), lists:flatten(Ctxt)).
|
||||||
|
|
||||||
|
mk_error({higher_kinded_typevar, T}) ->
|
||||||
|
Msg = io_lib:format("Type ~s is higher kinded (takes a type argument that takes\n"
|
||||||
|
"a type argument)\n", [pp(instantiate(T))]
|
||||||
|
),
|
||||||
|
mk_t_err(pos(T), Msg);
|
||||||
|
mk_error({wrong_type_arguments, X, ArityGiven, ArityReal}) ->
|
||||||
|
Msg = io_lib:format("Arity for ~s doesn't match. Expected ~p, got ~p\n"
|
||||||
|
, [pp(instantiate(X)), ArityReal, ArityGiven]
|
||||||
|
),
|
||||||
|
mk_t_err(pos(X), Msg);
|
||||||
|
mk_error({unnamed_map_update_with_default, Upd}) ->
|
||||||
|
Msg = "Invalid map update with default\n",
|
||||||
|
mk_t_err(pos(Upd), Msg);
|
||||||
|
mk_error({fundecl_must_have_funtype, _Ann, Id, _Type}) ->
|
||||||
|
Msg = io_lib:format("Function/entrypoint declaration must have a function type\n"),
|
||||||
|
mk_t_err(pos(Id), Msg);
|
||||||
mk_error({cannot_unify, A, B, When}) ->
|
mk_error({cannot_unify, A, B, When}) ->
|
||||||
Msg = io_lib:format("Cannot unify ~s\n and ~s\n",
|
Msg = io_lib:format("Cannot unify ~s\n and ~s\n",
|
||||||
[pp(instantiate(A)), pp(instantiate(B))]),
|
[pp(instantiate(A)), pp(instantiate(B))]),
|
||||||
@ -2344,14 +2360,6 @@ mk_error({indexed_type_must_be_word, Type, Type1}) ->
|
|||||||
Msg = io_lib:format("The indexed type ~s (at ~s) equals ~s which is not a word type\n",
|
Msg = io_lib:format("The indexed type ~s (at ~s) equals ~s which is not a word type\n",
|
||||||
[pp_type("", Type), pp_loc(Type), pp_type("", Type1)]),
|
[pp_type("", Type), pp_loc(Type), pp_type("", Type1)]),
|
||||||
mk_t_err(pos(Type), Msg);
|
mk_t_err(pos(Type), Msg);
|
||||||
mk_error({payload_type_must_be_string, Type, Type}) ->
|
|
||||||
Msg = io_lib:format("The payload type ~s (at ~s) should be string\n",
|
|
||||||
[pp_type("", Type), pp_loc(Type)]),
|
|
||||||
mk_t_err(pos(Type), Msg);
|
|
||||||
mk_error({payload_type_must_be_string, Type, Type1}) ->
|
|
||||||
Msg = io_lib:format("The payload type ~s (at ~s) equals ~s but it should be string\n",
|
|
||||||
[pp_type("", Type), pp_loc(Type), pp_type("", Type1)]),
|
|
||||||
mk_t_err(pos(Type), Msg);
|
|
||||||
mk_error({event_0_to_3_indexed_values, Constr}) ->
|
mk_error({event_0_to_3_indexed_values, Constr}) ->
|
||||||
Msg = io_lib:format("The event constructor ~s (at ~s) has too many indexed values (max 3)\n",
|
Msg = io_lib:format("The event constructor ~s (at ~s) has too many indexed values (max 3)\n",
|
||||||
[name(Constr), pp_loc(Constr)]),
|
[name(Constr), pp_loc(Constr)]),
|
||||||
@ -2398,10 +2406,14 @@ mk_error({namespace, _Pos, {con, Pos, Name}, _Def}) ->
|
|||||||
Msg = io_lib:format("Nested namespace not allowed\nNamespace '~s' at ~s not defined at top level.\n",
|
Msg = io_lib:format("Nested namespace not allowed\nNamespace '~s' at ~s not defined at top level.\n",
|
||||||
[Name, pp_loc(Pos)]),
|
[Name, pp_loc(Pos)]),
|
||||||
mk_t_err(pos(Pos), Msg);
|
mk_t_err(pos(Pos), Msg);
|
||||||
mk_error({repeated_arg, Fun, Arg}) ->
|
mk_error({type_decl, _, {id, Pos, Name}, _}) ->
|
||||||
Msg = io_lib:format("Repeated argument ~s to function ~s (at ~s).\n",
|
Msg = io_lib:format("Empty type declarations are not supported\nType ~s at ~s lacks a definition\n",
|
||||||
[Arg, pp(Fun), pp_loc(Fun)]),
|
[Name, pp_loc(Pos)]),
|
||||||
mk_t_err(pos(Fun), Msg);
|
mk_t_err(pos(Pos), Msg);
|
||||||
|
mk_error({letval, _Pos, {id, Pos, Name}, _Def}) ->
|
||||||
|
Msg = io_lib:format("Toplevel \"let\" definitions are not supported\nValue ~s at ~s could be replaced by 0-argument function\n",
|
||||||
|
[Name, pp_loc(Pos)]),
|
||||||
|
mk_t_err(pos(Pos), Msg);
|
||||||
mk_error({stateful_not_allowed, Id, Fun}) ->
|
mk_error({stateful_not_allowed, Id, Fun}) ->
|
||||||
Msg = io_lib:format("Cannot reference stateful function ~s (at ~s)\nin the definition of non-stateful function ~s.\n",
|
Msg = io_lib:format("Cannot reference stateful function ~s (at ~s)\nin the definition of non-stateful function ~s.\n",
|
||||||
[pp(Id), pp_loc(Id), pp(Fun)]),
|
[pp(Id), pp_loc(Id), pp(Fun)]),
|
||||||
|
@ -291,7 +291,6 @@ decls_to_fcode(Env, Decls) ->
|
|||||||
end, Env1, Decls).
|
end, Env1, Decls).
|
||||||
|
|
||||||
-spec decl_to_fcode(env(), aeso_syntax:decl()) -> env().
|
-spec decl_to_fcode(env(), aeso_syntax:decl()) -> env().
|
||||||
decl_to_fcode(Env, {type_decl, _, _, _}) -> Env;
|
|
||||||
decl_to_fcode(Env = #{context := {main_contract, _}}, {fun_decl, _, Id, _}) ->
|
decl_to_fcode(Env = #{context := {main_contract, _}}, {fun_decl, _, Id, _}) ->
|
||||||
case is_no_code(Env) of
|
case is_no_code(Env) of
|
||||||
false -> fcode_error({missing_definition, Id});
|
false -> fcode_error({missing_definition, Id});
|
||||||
|
@ -37,20 +37,24 @@
|
|||||||
-type decl() :: {contract, ann(), con(), [decl()]}
|
-type decl() :: {contract, ann(), con(), [decl()]}
|
||||||
| {namespace, ann(), con(), [decl()]}
|
| {namespace, ann(), con(), [decl()]}
|
||||||
| {pragma, ann(), pragma()}
|
| {pragma, ann(), pragma()}
|
||||||
| {type_decl, ann(), id(), [tvar()]}
|
| {type_decl, ann(), id(), [tvar()]} % Only for error msgs
|
||||||
| {type_def, ann(), id(), [tvar()], typedef()}
|
| {type_def, ann(), id(), [tvar()], typedef()}
|
||||||
| {fun_decl, ann(), id(), type()}
|
| {fun_decl, ann(), id(), type()}
|
||||||
| {fun_clauses, ann(), id(), type(), [letbind()]}
|
| {fun_clauses, ann(), id(), type(), [letbind()]}
|
||||||
| {block, ann(), [decl()]}
|
| {block, ann(), [decl()]}
|
||||||
| letbind().
|
| letfun()
|
||||||
|
| letval(). % Only for error msgs
|
||||||
|
|
||||||
-type compiler_version() :: [non_neg_integer()].
|
-type compiler_version() :: [non_neg_integer()].
|
||||||
|
|
||||||
-type pragma() :: {compiler, '==' | '<' | '>' | '=<' | '>=', compiler_version()}.
|
-type pragma() :: {compiler, '==' | '<' | '>' | '=<' | '>=', compiler_version()}.
|
||||||
|
|
||||||
|
|
||||||
|
-type letval() :: {letval, ann(), pat(), expr()}.
|
||||||
|
-type letfun() :: {letfun, ann(), id(), [pat()], type(), expr()}.
|
||||||
-type letbind()
|
-type letbind()
|
||||||
:: {letval, ann(), pat(), expr()}
|
:: letfun()
|
||||||
| {letfun, ann(), id(), [pat()], type(), expr()}.
|
| letval().
|
||||||
|
|
||||||
-type arg() :: {arg, ann(), id(), type()}.
|
-type arg() :: {arg, ann(), id(), type()}.
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ fold(Alg = #alg{zero = Zero, plus = Plus, scoped = Scoped}, Fun, K, X) ->
|
|||||||
%% decl()
|
%% decl()
|
||||||
{contract, _, _, Ds} -> Decl(Ds);
|
{contract, _, _, Ds} -> Decl(Ds);
|
||||||
{namespace, _, _, Ds} -> Decl(Ds);
|
{namespace, _, _, Ds} -> Decl(Ds);
|
||||||
{type_decl, _, I, _} -> BindType(I);
|
|
||||||
{type_def, _, I, _, D} -> Plus(BindType(I), Decl(D));
|
{type_def, _, I, _, D} -> Plus(BindType(I), Decl(D));
|
||||||
{fun_decl, _, _, T} -> Type(T);
|
{fun_decl, _, _, T} -> Type(T);
|
||||||
{letval, _, P, E} -> Scoped(BindExpr(P), Expr(E));
|
{letval, _, P, E} -> Scoped(BindExpr(P), Expr(E));
|
||||||
|
@ -58,8 +58,7 @@ contract Greeter =
|
|||||||
|
|
||||||
let state = { greeting = "Hello" }
|
let state = { greeting = "Hello" }
|
||||||
|
|
||||||
let setGreeting =
|
function setGreeting(greeting: string) =
|
||||||
(greeting: string) =>
|
|
||||||
state{ greeting = greeting }
|
state{ greeting = greeting }
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,44 +1,78 @@
|
|||||||
// Try to cover all syntactic constructs.
|
// Try to cover all syntactic constructs.
|
||||||
|
@compiler > 0
|
||||||
|
@compiler =< 10.1.1.1.1.1.2.3.4
|
||||||
|
|
||||||
contract AllSyntaxType =
|
contract AllSyntaxType =
|
||||||
type typeDecl /* bla */
|
|
||||||
type paramTypeDecl('a, 'b)
|
|
||||||
|
|
||||||
/** Multi-
|
/** Multi-
|
||||||
* line
|
* line
|
||||||
* comment
|
* comment
|
||||||
*/
|
*/
|
||||||
function foo : _
|
function foo : _
|
||||||
|
entrypoint bar : int => (int * 'a)
|
||||||
|
/*
|
||||||
|
namespace Ns =
|
||||||
|
datatype d('a) = D | S(int) | M('a, list('a), int)
|
||||||
|
private function f() = 123
|
||||||
|
entrypoint
|
||||||
|
f : (int, 'a) => ('a * 'b) => 'a
|
||||||
|
f (1, x) = (_) => x
|
||||||
|
f (_, _) = (t : 'a * 'b) => switch(t)
|
||||||
|
(l, r) => l
|
||||||
|
_ => abort("tuple exploit")
|
||||||
|
|
||||||
contract AllSyntax =
|
contract AllSyntax =
|
||||||
|
|
||||||
type typeDecl = int
|
datatype mickiewicz = Adam | Mickiewicz
|
||||||
type paramTypeDecl('a, 'b) = (('a, 'b) => 'b) => list('a) => 'b => 'b
|
record goethe('a, 'b) = {
|
||||||
|
johann : int,
|
||||||
|
wolfgang : 'a,
|
||||||
|
von : 'a * 'b * int,
|
||||||
|
goethe : unit
|
||||||
|
}
|
||||||
|
type dante = Ns.d(int)
|
||||||
|
type shakespeare('a) = goethe('a, 'a)
|
||||||
|
|
||||||
record nestedRecord = { x : int }
|
type state = shakespeare(int)
|
||||||
record recordType = { z : nestedRecord, y : int }
|
|
||||||
datatype variantType('a) = None | Some('a)
|
|
||||||
|
|
||||||
let valWithType : map(int, int) => option(int) = (m) => Map.get(m, 42)
|
entrypoint init() = {
|
||||||
let valNoType =
|
johann = 1000,
|
||||||
if(valWithType(Map.empty) == None)
|
wolfgang = -10,
|
||||||
print(42 mod 10 * 5 / 3)
|
von = (2 + 2, 0, List.sum([x | k <- [1,2,3]
|
||||||
|
, let l = k + 1
|
||||||
|
, if(l < 10)
|
||||||
|
, let f(x) = x + 100
|
||||||
|
, Adam <- [Adam, Mickiewicz]
|
||||||
|
, let x = f(l)
|
||||||
|
])),
|
||||||
|
goethe = () }
|
||||||
|
|
||||||
function funWithType(x : int, y) : int * list(int) = (x, 0 :: [y] ++ [])
|
function f() =
|
||||||
function funNoType() =
|
let p = "Пушкин"
|
||||||
let foo = (x, y : bool) =>
|
let k(x : bytes(8)) : bytes(8) = Bytes.to_int(#fedcba9876543210)
|
||||||
if (! (y && x =< 0x0b || true)) [x]
|
|
||||||
else [11..20]
|
|
||||||
let setY(r : recordType) : unit = r{ y = 5 }
|
|
||||||
let setX(r : recordType, x : int) : recordType = r { z.x = x } // nested record update
|
|
||||||
let getY(r) = switch(r) {y = y} => y
|
|
||||||
switch (funWithType(1, -2))
|
|
||||||
(x, [y, z]) => bar({x = z, y = -y + - -z * (-1)})
|
|
||||||
(x, y :: _) => ()
|
|
||||||
|
|
||||||
let hash : address = #01ab0fff11
|
let f : () => address = () => ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
|
||||||
let b = false
|
if(Bits.test(Bits.all, 10))
|
||||||
let qcon = Mod.Con
|
abort("ohno")
|
||||||
let str = "blabla\nfoo"
|
if(true && false)
|
||||||
let chr = '"'
|
require(true, "ohyes")
|
||||||
|
elif(false || 2 == 2)
|
||||||
|
()
|
||||||
|
else
|
||||||
|
()
|
||||||
|
if(true) f(1,2)((1,2))
|
||||||
|
else switch(1::[1,2,3])
|
||||||
|
[] => 1
|
||||||
|
a::b => 123
|
||||||
|
1::2::3 => 123123
|
||||||
|
[2,3,4] => 1
|
||||||
|
_ => 13
|
||||||
|
1::[2] => 2138
|
||||||
|
put(state{johann = 1})
|
||||||
|
let m = {["foo"] = 19, /*hey wanna talk about inlined comments?*/ ["bar"] = 42}
|
||||||
|
let n = {}
|
||||||
|
m{ ["x" = 0] @ z = z + state.johann }
|
||||||
|
|
||||||
|
let sh : shakespeare(shakespeare(int)) =
|
||||||
|
{wolfgang = state}
|
||||||
|
sh{wolfgang.wolfgang = sh.wolfgang} // comment
|
||||||
|
/*
|
@ -15,7 +15,7 @@ contract MultiSig =
|
|||||||
| OwnerRemoved (address) // of { .removedOwner : Address }
|
| OwnerRemoved (address) // of { .removedOwner : Address }
|
||||||
| ReqChanged (int) // of { .newReq : int }
|
| ReqChanged (int) // of { .newReq : int }
|
||||||
|
|
||||||
let maxOwners : int = 250
|
function maxOwners() : int = 250
|
||||||
|
|
||||||
record state = { nRequired : int
|
record state = { nRequired : int
|
||||||
, nOwners : int
|
, nOwners : int
|
||||||
@ -68,7 +68,7 @@ contract MultiSig =
|
|||||||
switch(check_pending(callhash()))
|
switch(check_pending(callhash()))
|
||||||
CheckFail(state') => { state = state' }
|
CheckFail(state') => { state = state' }
|
||||||
CheckOk(state') =>
|
CheckOk(state') =>
|
||||||
if(state.nOwners >= maxOwners) () /* TODO */
|
if(state.nOwners >= maxOwners()) () /* TODO */
|
||||||
else
|
else
|
||||||
let nOwners' = state'.nOwners + 1
|
let nOwners' = state'.nOwners + 1
|
||||||
{ state = state' { owners = Map.insert(nOwners', newOwner, state'.owners)
|
{ state = state' { owners = Map.insert(nOwners', newOwner, state'.owners)
|
||||||
|
@ -1,16 +1,3 @@
|
|||||||
|
|
||||||
/* Contract type */
|
|
||||||
contract VotingType =
|
|
||||||
type state
|
|
||||||
function init : list(string) => state
|
|
||||||
|
|
||||||
function giveRightToVote : address => unit
|
|
||||||
function delegate : address => unit
|
|
||||||
function vote : int => unit
|
|
||||||
function winnerName : unit => string
|
|
||||||
function currentTally : unit => list(string * int)
|
|
||||||
|
|
||||||
/* Contract implementation */
|
|
||||||
contract Voting =
|
contract Voting =
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
Loading…
x
Reference in New Issue
Block a user