Implement [a..b]
This commit is contained in:
parent
79a928e530
commit
5f733e01dd
@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
- Added the `[a..b]` language construct, returning the list of numbers between
|
||||||
|
`a` and `b` (inclusive). Returns the empty list if `a` > `b`.
|
||||||
### Changed
|
### Changed
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -7,3 +7,10 @@ namespace ListInternal =
|
|||||||
[] => []
|
[] => []
|
||||||
x :: xs => f(x) ++ flat_map(f, xs)
|
x :: xs => f(x) ++ flat_map(f, xs)
|
||||||
|
|
||||||
|
// -- From..to ---------------------------------------------------------------
|
||||||
|
|
||||||
|
function from_to(a : int, b : int) : list(int) = from_to_(a, b, [])
|
||||||
|
|
||||||
|
private function from_to_(a, b, acc) =
|
||||||
|
if (a > b) acc else from_to_(a, b - 1, b :: acc)
|
||||||
|
|
||||||
|
@ -1352,6 +1352,9 @@ infer_infix({RelOp, As})
|
|||||||
T = fresh_uvar(As), %% allow any type here, check in ast_to_icode that we have comparison for it
|
T = fresh_uvar(As), %% allow any type here, check in ast_to_icode that we have comparison for it
|
||||||
Bool = {id, As, "bool"},
|
Bool = {id, As, "bool"},
|
||||||
{fun_t, As, [], [T, T], Bool};
|
{fun_t, As, [], [T, T], Bool};
|
||||||
|
infer_infix({'..', As}) ->
|
||||||
|
Int = {id, As, "int"},
|
||||||
|
{fun_t, As, [], [Int, Int], {app_t, As, {id, As, "list"}, [Int]}};
|
||||||
infer_infix({'::', As}) ->
|
infer_infix({'::', As}) ->
|
||||||
ElemType = fresh_uvar(As),
|
ElemType = fresh_uvar(As),
|
||||||
ListType = {app_t, As, {id, As, "list"}, [ElemType]},
|
ListType = {app_t, As, {id, As, "list"}, [ElemType]},
|
||||||
|
@ -453,12 +453,16 @@ expr_to_fcode(Env, _Type, {list, _, Es}) ->
|
|||||||
lists:foldr(fun(E, L) -> {op, '::', [expr_to_fcode(Env, E), L]} end,
|
lists:foldr(fun(E, L) -> {op, '::', [expr_to_fcode(Env, E), L]} end,
|
||||||
nil, Es);
|
nil, Es);
|
||||||
|
|
||||||
|
expr_to_fcode(Env, _Type, {app, _, {'..', _}, [A, B]}) ->
|
||||||
|
{def_u, FromTo, _} = resolve_fun(Env, ["ListInternal", "from_to"]),
|
||||||
|
{def, FromTo, [expr_to_fcode(Env, A), expr_to_fcode(Env, B)]};
|
||||||
|
|
||||||
expr_to_fcode(Env, _Type, {list_comp, _, Yield, []}) ->
|
expr_to_fcode(Env, _Type, {list_comp, _, Yield, []}) ->
|
||||||
{op, '::', [expr_to_fcode(Env, Yield), nil]};
|
{op, '::', [expr_to_fcode(Env, Yield), nil]};
|
||||||
expr_to_fcode(Env, _Type, {list_comp, As, Yield, [{comprehension_bind, {typed, {id, _, Arg}, _}, BindExpr}|Rest]}) ->
|
expr_to_fcode(Env, _Type, {list_comp, As, Yield, [{comprehension_bind, {typed, {id, _, Arg}, _}, BindExpr}|Rest]}) ->
|
||||||
Env1 = bind_var(Env, Arg),
|
Env1 = bind_var(Env, Arg),
|
||||||
Bind = {lam, [Arg], expr_to_fcode(Env1, {list_comp, As, Yield, Rest})},
|
Bind = {lam, [Arg], expr_to_fcode(Env1, {list_comp, As, Yield, Rest})},
|
||||||
{def_u, FlatMap, _} = resolve_fun(Env, ["List", "flat_map"]),
|
{def_u, FlatMap, _} = resolve_fun(Env, ["ListInternal", "flat_map"]),
|
||||||
{def, FlatMap, [Bind, expr_to_fcode(Env, BindExpr)]};
|
{def, FlatMap, [Bind, expr_to_fcode(Env, BindExpr)]};
|
||||||
expr_to_fcode(Env, Type, {list_comp, As, Yield, [{comprehension_if, _, Cond}|Rest]}) ->
|
expr_to_fcode(Env, Type, {list_comp, As, Yield, [{comprehension_if, _, Cond}|Rest]}) ->
|
||||||
make_if(expr_to_fcode(Env, Cond),
|
make_if(expr_to_fcode(Env, Cond),
|
||||||
|
@ -523,6 +523,10 @@ ast_body({app, _, {typed, _, {con, _, Name}, _}, Args}, Icode) ->
|
|||||||
ast_body({app, _, {typed, _, {qcon, _, Name}, _}, Args}, Icode) ->
|
ast_body({app, _, {typed, _, {qcon, _, Name}, _}, Args}, Icode) ->
|
||||||
Tag = aeso_icode:get_constructor_tag(Name, Icode),
|
Tag = aeso_icode:get_constructor_tag(Name, Icode),
|
||||||
#tuple{cpts = [#integer{value = Tag} | [ ast_body(Arg, Icode) || Arg <- Args ]]};
|
#tuple{cpts = [#integer{value = Tag} | [ ast_body(Arg, Icode) || Arg <- Args ]]};
|
||||||
|
ast_body({app, _, {'..', _}, [A, B]}, Icode) ->
|
||||||
|
#funcall
|
||||||
|
{ function = #var_ref{ name = ["ListInternal", "from_to"] }
|
||||||
|
, args = [ast_body(A, Icode), ast_body(B, Icode)] };
|
||||||
ast_body({app,As,Fun,Args}, Icode) ->
|
ast_body({app,As,Fun,Args}, Icode) ->
|
||||||
case aeso_syntax:get_ann(format, As) of
|
case aeso_syntax:get_ann(format, As) of
|
||||||
infix ->
|
infix ->
|
||||||
@ -541,7 +545,7 @@ ast_body({list_comp, _, Yield, []}, Icode) ->
|
|||||||
#list{elems = [ast_body(Yield, Icode)]};
|
#list{elems = [ast_body(Yield, Icode)]};
|
||||||
ast_body({list_comp, As, Yield, [{comprehension_bind, {typed, Arg, ArgType}, BindExpr}|Rest]}, Icode) ->
|
ast_body({list_comp, As, Yield, [{comprehension_bind, {typed, Arg, ArgType}, BindExpr}|Rest]}, Icode) ->
|
||||||
#funcall
|
#funcall
|
||||||
{ function = #var_ref{ name = ["List", "flat_map"] }
|
{ function = #var_ref{ name = ["ListInternal", "flat_map"] }
|
||||||
, args =
|
, args =
|
||||||
[ #lambda{ args=[#arg{name = ast_id(Arg), type = ast_type(ArgType, Icode)}]
|
[ #lambda{ args=[#arg{name = ast_id(Arg), type = ast_type(ArgType, Icode)}]
|
||||||
, body = ast_body({list_comp, As, Yield, Rest}, Icode)
|
, body = ast_body({list_comp, As, Yield, Rest}, Icode)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user