Files
mercury/tests/valid/ho_func_call.m
Zoltan Somogyi c03b11ca48 Update the style of more test cases.
And updated expected outputs for changed line numbers.
2021-07-27 19:29:21 +10:00

93 lines
2.3 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
%
% Regression test for higher-order function call in code with common
% subexpression; mercury 0.7 failed this test, reporting
% "Software Error: modecheck fails when repeated",
% due to confusion between h.o. _function_ call and h.o. _predicate_ call.
:- module ho_func_call.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
%---------------------------------------------------------------------------%
:- implementation.
:- import_module string.
main(IO, put_stocks(get_stocks(IO))).
:- type maybe(T)
---> yes(T)
; no.
:- type code == int.
:- type qty == int.
:- type stock
---> stock(code, qty).
:- type iostocks
---> ios(io, stocks).
:- type stocks
---> []
; [stock | stocks]
; closure(func(io) = iostocks).
:- inst iostocks == unique(ios(unique, stocks)).
:- inst stocks ==
bound( [] ; [ground | stocks] ; closure(func(di) = is_out is det)).
:- mode is_in == di(iostocks).
:- mode is_out == out(iostocks).
:- func put_stocks(iostocks) = io.
:- mode put_stocks(is_in) = uo is det.
put_stocks(ios(IO, [])) = IO.
put_stocks(ios(IO, [S | T])) = put_stocks(ios(IO1, T)) :-
out_stock(S, IO, IO1).
put_stocks(ios(IO, closure(Func))) = put_stocks(apply(Func, IO)).
:- pred out_stock(stock::in, io::di, io::uo) is det.
out_stock(stock(C, Q), !IO) :-
% io.format("%i %i\n", [i(C), i(Q)]).
io.write_int(C, !IO),
io.write_char(' ', !IO),
io.write_int(Q, !IO),
io.nl(!IO).
:- func get_stocks(io) = iostocks.
:- mode get_stocks(di) = is_out is det.
get_stocks(S0) = ios(S, Stocks) :-
tokenize(MStock, S0, S),
( MStock = no, Stocks = []
; MStock = yes(Stock), Stocks = [Stock | closure(get_stocks)]
).
:- pred tokenize(maybe(stock)::out, io::di, io::uo) is det.
tokenize(S, !IO) :-
io.read_line(CL0, !IO),
( if
CL0 = ok(CL),
string.from_char_list(CL, Line),
string.sub_string_search(Line, " ", Index),
string.split(Line, Index, Left, Right0),
string.first_char(Right0, _, Right),
string.to_int(Left, Code),
string.to_int(Right, Qty)
then
S = yes(stock(Code, Qty))
else
S = no
).