mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
One option, --warn-non-contiguous-decls, generates warnings if the
mode declarations of a predicate or function aren't in a contiguous block
immediately following the pred or func declaration. Since this is a rare
kind of "style error", this option is enabled by default.
Two options, --warn-inconsistent-pred-order-clauses and
--warn-inconsistent-pred-order-foreign-procs, warn about inconsistencies
between (a) the order in which predicates (and functions) are declared,
and (b) the order in which they are defined. The two options differ in
their scope. The latter applies to all predicates and functions defined
in the module, while the former applies only to those whose definitions
include Mercury clauses.
Since an exported predicate or function may need nonexported auxiliary
predicates and/or functions, imposing a single order the declarations and
definitions of *all* the predicates and functions in a module is not a good
idea. Instead, both options divide the predicates and functions defined
in a module two groups, the exported and the nonexported, and expect
a consistent order only within each group.
The result is output that looks like this:
time.m:021: Warning: the order of the declarations and definitions of the
time.m:021: exported predicates is inconsistent, as shown by this diff:
time.m:021:
time.m:021: --- declaration order
time.m:021: +++ definition order
time.m:021: @@ -1,7 +1,7 @@
time.m:021: predicate `clock'/3
time.m:021: -predicate `time'/3
time.m:021: predicate `times'/4
time.m:021: function `clk_tck'/0
time.m:021: +predicate `time'/3
time.m:021: function `difftime'/2
time.m:021: predicate `localtime'/4
time.m:021: function `localtime'/1
compiler/options.m:
doc/user_guide.texi:
Add the new options.
compiler/style_checks.m:
A new module that generates the new warnings if warranted.
compiler/check_hlds.m:
compiler/notes/compiler_design.html:
Include and document the new module.
compiler/mercury_compile_front_end.m:
Invoke the new module if any of the three new options is set.
compiler/hlds_pred.m:
Record the item number of every predicate, function, and mode declaration
in the module being compiled. We need this for information for the
new warnings.
compiler/hlds_module.m:
Record the context of the module declaration. We use this context
for warnings about inconsistent order, since there isn't a better one.
compiler/hlds_clauses.m:
Add a mechanism to retrieve the item numbers of a set of clauses
even if they are contiguous.
Document some old data types.
compiler/error_util.m:
Add a new phase for style checks.
compiler/accumulator.m:
compiler/add_class.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/clause_to_proc.m:
compiler/from_ground_term_util.m:
compiler/lambda.m:
compiler/make_hlds.m:
compiler/make_hlds_passes.m:
compiler/mercury_compile.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/stm_expand.m:
compiler/table_gen.m:
compiler/unify_proc.m:
Conform the changes to the HLDS above.
compiler/typecheck_errors.m:
Fix style of error messages.
library/array2d.m:
library/assoc_list.m:
library/benchmarking.m:
library/bit_buffer.write.m:
library/bool.m:
library/builtin.m:
library/construct.m:
library/cord.m:
library/counter.m:
library/float.m:
library/injection.m:
library/lazy.m:
library/lexer.m:
library/ops.m:
library/private_builtin.m:
library/profiling_builtin.m:
library/prolog.m:
library/queue.m:
library/rational.m:
library/require.m:
library/stack.m:
library/std_util.m:
library/store.m:
library/thread.semaphore.m:
library/tree234.m:
library/univ.m:
library/version_store.m:
Move declarations or definitions around to avoid some of the warnings
that we can now generate. (There are many more left.)
Make some minor style improvements in the process.
tests/warnings/inconsistent_pred_order.{m,exp}:
tests/warnings/non_contiguous_decls.{m,exp}:
New test cases to test the new options. They are both copies of
tests/benchmarks/queens.m, with intentionally-screwed-up style.
tests/warnings/Mmakefile:
Enable the new test cases.
tests/warnings/Mercury.options:
Specify the options being tested for the new test cases.
tests/benchmarks/queens.m:
Bring the style of this module up to date (before copying it).
tests/invalid/mode_decl_in_wrong_section.err_exp:
Expect the warnings we now generate.
440 lines
16 KiB
Mathematica
440 lines
16 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ts=4 sw=4 et tw=0 wm=0 ft=mercury
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2007, 2011 The University of Melbourne
|
|
% This file may only be copied under the terms of the GNU Library General
|
|
% Public License - see the file COPYING.LIB in the Mercury distribution.
|
|
%---------------------------------------------------------------------------%
|
|
% File: bit_buffer.write.m.
|
|
% Main author: stayl.
|
|
% Stability: low.
|
|
%
|
|
% A bit buffer provides an interface between bit-oriented output requests
|
|
% and byte-array-oriented streams, storing bits until there are enough bytes
|
|
% to make calling the `put' method on the stream worthwhile.
|
|
%
|
|
% CAVEAT: the user is referred to the documentation in the header
|
|
% of array.m regarding programming with unique objects (the compiler
|
|
% does not currently recognise them, hence we are forced to use
|
|
% non-unique modes until the situation is rectified; this places
|
|
% a small burden on the programmer to ensure the correctness of his
|
|
% code that would otherwise be assured by the compiler.)
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module bit_buffer.write.
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- type write_buffer(Stream, State).
|
|
% <= stream.writer(Stream, bitmap.slice, State).
|
|
|
|
:- type write_buffer == write_buffer(error_stream, error_state).
|
|
:- type io_write_buffer == write_buffer(io.binary_output_stream, io.state).
|
|
|
|
:- inst uniq_write_buffer == ground. % XXX Should be unique.
|
|
:- mode write_buffer_di == in(uniq_write_buffer).
|
|
:- mode write_buffer_ui == in(uniq_write_buffer).
|
|
:- mode write_buffer_uo == out(uniq_write_buffer).
|
|
|
|
% new(NumBytes, Stream, State) creates a buffer which will write to
|
|
% the stream specified by Stream and State in chunks of NumBytes bytes.
|
|
% If NumBytes is less than the size of an integer (given by
|
|
% int.bits_per_int), the size of an integer will be used instead.
|
|
%
|
|
:- func new(num_bytes, Stream, State) = write_buffer(Stream, State)
|
|
<= stream.writer(Stream, byte_index, State).
|
|
:- mode new(in, in, di) = write_buffer_uo is det.
|
|
|
|
% new(NumBytes):
|
|
%
|
|
% Create a buffer which collects all of the bits written, and does
|
|
% not write them to a stream. The bits are collected in chunks of
|
|
% size NumBytes bytes, and are written to a bitmap by
|
|
% `finalize_to_bitmap/1'.
|
|
%
|
|
:- func new_bitmap_builder(num_bytes) = write_buffer.
|
|
:- mode new_bitmap_builder(in) = out is det.
|
|
|
|
% How many bits to be written does the buffer contain?
|
|
%
|
|
:- func num_buffered_bits(write_buffer(_, _)) = num_bits.
|
|
:- mode num_buffered_bits(write_buffer_ui) = out is det.
|
|
|
|
% Return how many bits need to be written to get to a byte boundary
|
|
% in the output stream.
|
|
%
|
|
:- func num_bits_to_byte_boundary(write_buffer(_, _)) = num_bits.
|
|
:- mode num_bits_to_byte_boundary(write_buffer_ui) = out is det.
|
|
|
|
% Write a bit to the buffer.
|
|
%
|
|
:- pred put_bit(bool, write_buffer(Stream, State), write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode put_bit(in, write_buffer_di, write_buffer_uo) is det.
|
|
|
|
% Write the given number of low-order bits from an int to the buffer.
|
|
% The number of bits must be less than int.bits_per_int.
|
|
%
|
|
:- pred put_bits(word, num_bits, write_buffer(Stream, State),
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode put_bits(in, in, write_buffer_di, write_buffer_uo) is det.
|
|
|
|
% Write the eight low-order bits from an int to the buffer.
|
|
% The number of bits must be less than int.bits_per_int.
|
|
%
|
|
:- pred put_byte(word, write_buffer(Stream, State),
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode put_byte(in, write_buffer_di, write_buffer_uo) is det.
|
|
|
|
% Write bits from a bitmap to the buffer.
|
|
% The buffer does not keep a reference to the bitmap.
|
|
%
|
|
:- pred put_bitmap(bitmap, write_buffer(Stream, State),
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode put_bitmap(bitmap_ui, write_buffer_di, write_buffer_uo) is det.
|
|
|
|
:- pred put_bitmap(bitmap, bit_index, num_bits,
|
|
write_buffer(Stream, State), write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode put_bitmap(bitmap_ui, in, in, write_buffer_di, write_buffer_uo) is det.
|
|
|
|
% Flush all complete bytes in the buffer to the output stream.
|
|
% If there is an incomplete final byte it will remain unwritten
|
|
% in the buffer.
|
|
%
|
|
:- pred flush(write_buffer(Stream, State), write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode flush(write_buffer_di, write_buffer_uo) is det.
|
|
|
|
% Pad the buffered data out to a byte boundary, flush it to
|
|
% the output stream, then return the Stream and State.
|
|
%
|
|
:- pred finalize(write_buffer(Stream, State), Stream, State)
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode finalize(write_buffer_di, out, uo) is det.
|
|
|
|
% Copy the data from a non-streamed write_buffer to a bitmap.
|
|
% The output is not padded to an even number of bits.
|
|
%
|
|
:- func finalize_to_bitmap(write_buffer) = bitmap.
|
|
:- mode finalize_to_bitmap(write_buffer_di) = bitmap_uo is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- implementation.
|
|
|
|
/*
|
|
:- interface.
|
|
% A write_buffer can be used as an output stream.
|
|
% XXX These instances don't work because of the duplicated variables
|
|
% in the head.
|
|
%
|
|
:- type write_stream(Stream) ---> write_stream.
|
|
:- instance stream.stream(write_stream(Stream), write_buffer(Stream, State))
|
|
<= stream.stream(Stream, State).
|
|
:- instance stream.output(write_stream(Stream), write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- instance stream.writer(write_stream(Stream), bool,
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- instance stream.writer(write_stream(Stream), bitmap.slice,
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
*/
|
|
|
|
% For a write_buffer, a bit_buffer is allocated that is bits_per_int
|
|
% larger than the size requested. This allows a full word to be
|
|
% written at any time. After each write, the position is checked.
|
|
% If the position is greater than the requested size, a chunk of the
|
|
% requested size is written to the stream. The unwritten bits are
|
|
% then copied to the start of the buffer.
|
|
%
|
|
% We always use a buffer size that is at least the size of a word
|
|
% so that writing a word to the buffer will require at most a single
|
|
% call to `put'. Allowing smaller sizes complicates the code
|
|
% for a case that shouldn't occur in practice.
|
|
%
|
|
% For a bitmap_builder, we store the filled bitmaps in a list rather
|
|
% than writing them to an output stream.
|
|
%
|
|
:- type write_buffer(Stream, State)
|
|
---> write_buffer(
|
|
bit_buffer :: bit_buffer(Stream, State)
|
|
).
|
|
|
|
new(NumBytes, Stream, State) = Buffer :-
|
|
SizeInBits = NumBytes * bits_per_byte,
|
|
Size = int.max(SizeInBits, bits_per_int),
|
|
BM = bitmap.init(Size + int.bits_per_int, no),
|
|
Buffer = write_buffer(new_buffer(BM, 0, Size, yes, Stream, State)).
|
|
|
|
new_bitmap_builder(NumBytes) = Buffer :-
|
|
Size = NumBytes * bits_per_byte,
|
|
BM = bitmap.init(Size + int.bits_per_int, no),
|
|
Buffer = write_buffer(new_buffer(BM, 0, Size, no,
|
|
error_stream, error_state)).
|
|
|
|
num_buffered_bits(write_buffer(Buffer)) =
|
|
Buffer ^ pos +
|
|
foldl((func(BM, N) = N + BM ^ num_bits), Buffer ^ filled_bitmaps, 0).
|
|
|
|
num_bits_to_byte_boundary(Buffer) = NumBits :-
|
|
Pos = Buffer ^ bit_buffer ^ pos,
|
|
Rem = Pos `unchecked_rem` bits_per_byte,
|
|
( if Rem = 0 then
|
|
NumBits = 0
|
|
else
|
|
NumBits = bits_per_byte - Rem
|
|
).
|
|
|
|
put_bit(yes, !Buffer) :-
|
|
put_bits(1, 1, !Buffer).
|
|
put_bit(no, !Buffer) :-
|
|
put_bits(0, 1, !Buffer).
|
|
|
|
put_bits(Bits, NumBits, write_buffer(!.Buffer), write_buffer(!:Buffer)) :-
|
|
BM0 = !.Buffer ^ bitmap,
|
|
Pos0 = !.Buffer ^ pos,
|
|
|
|
% We always make sure there is enough room in the buffer for a full
|
|
% word to be written, so this can't run off the end of the bitmap.
|
|
%
|
|
BM = BM0 ^ bits(Pos0, NumBits) := Bits,
|
|
Pos = Pos0 + NumBits,
|
|
set_bitmap(BM, Pos, !Buffer),
|
|
maybe_make_room(!Buffer).
|
|
|
|
put_byte(Byte, !Buffer) :-
|
|
put_bits(Byte, bits_per_byte, !Buffer).
|
|
|
|
put_bitmap(BM, !Buffer) :-
|
|
put_bitmap(BM, 0, BM ^ num_bits, !Buffer).
|
|
|
|
put_bitmap(BM, Index, NumBits,
|
|
write_buffer(!.Buffer), write_buffer(!:Buffer)) :-
|
|
put_bitmap_2(BM, Index, NumBits, !Buffer).
|
|
|
|
% XXX If we're writing to a list of bitmaps and the user doesn't want
|
|
% to write to the bitmap again, we should just add the bitmap passed
|
|
% by the user to the list of filled bitmaps, if the current buffer
|
|
% bitmap is full enough that we're not wasting too much space.
|
|
%
|
|
:- pred put_bitmap_2(bitmap, bit_index, num_bits,
|
|
bit_buffer(Stream, State), bit_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
:- mode put_bitmap_2(bitmap_ui, in, in,
|
|
write_buffer_di, write_buffer_uo) is det.
|
|
|
|
put_bitmap_2(BM, Index, NumBits, !Buffer) :-
|
|
( if NumBits = 0 then
|
|
true
|
|
else
|
|
BufferBM0 = !.Buffer ^ bitmap,
|
|
Pos = !.Buffer ^ pos,
|
|
Size = !.Buffer ^ size,
|
|
Remain = Size - Pos,
|
|
NumBitsToWrite = int.min(Remain, NumBits),
|
|
BufferBM = copy_bits(BM, Index, BufferBM0, Pos, NumBitsToWrite),
|
|
set_bitmap(BufferBM, Pos + NumBitsToWrite, !Buffer),
|
|
maybe_make_room(!Buffer),
|
|
put_bitmap_2(BM, Index + NumBitsToWrite,
|
|
NumBits - NumBitsToWrite, !Buffer)
|
|
).
|
|
|
|
flush(write_buffer(!.Buffer), write_buffer(!:Buffer)) :-
|
|
UseStream = !.Buffer ^ use_stream,
|
|
(
|
|
UseStream = yes,
|
|
flush_all_to_stream(!Buffer)
|
|
;
|
|
UseStream = no
|
|
).
|
|
|
|
:- pred flush_all_to_stream(bit_buffer(Stream, State)::bit_buffer_di,
|
|
bit_buffer(Stream, State)::bit_buffer_uo) is det
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
|
|
flush_all_to_stream(!Buffer) :-
|
|
( if num_buffered_bits(write_buffer(!.Buffer)) >= bits_per_byte then
|
|
flush_chunk_to_stream(!Buffer),
|
|
flush_all_to_stream(!Buffer)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred flush_chunk_to_stream(bit_buffer(Stream, State)::bit_buffer_di,
|
|
bit_buffer(Stream, State)::bit_buffer_uo) is det
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
|
|
flush_chunk_to_stream(!Buffer) :-
|
|
% Write at most Size bytes at once (this is the output chunk size
|
|
% set in the call to `new').
|
|
Pos = !.Buffer ^ pos,
|
|
Size = !.Buffer ^ size,
|
|
NumBitsToWrite0 = int.min(Size, Pos),
|
|
NumBytes = NumBitsToWrite0 `unchecked_quotient` bits_per_byte,
|
|
( if NumBytes = 0 then
|
|
true
|
|
else
|
|
NumBitsToWrite = NumBytes * bits_per_byte,
|
|
stream.put(!.Buffer ^ stream,
|
|
bitmap.byte_slice(!.Buffer ^ bitmap, 0, NumBytes),
|
|
unsafe_promise_unique(!.Buffer ^ state), NewState),
|
|
Remain = Pos - NumBitsToWrite,
|
|
( if Remain = 0 then
|
|
NewBM = !.Buffer ^ bitmap
|
|
else
|
|
% Copy the remainder to the start of the bitmap.
|
|
% (We know that there are at most int.bits_per_int bits
|
|
% after the flush because that was the size of the bitmap
|
|
% created in `new', so we don't need to use copy_bits here).
|
|
NewBM0 = !.Buffer ^ bitmap,
|
|
NewBM = NewBM0 ^ bits(0, Remain) :=
|
|
NewBM0 ^ bits(NumBitsToWrite, Remain)
|
|
),
|
|
set_all(NewBM, Remain, !.Buffer ^ size, NewState,
|
|
!.Buffer ^ filled_bitmaps, !Buffer)
|
|
).
|
|
|
|
finalize(!.Buffer, Stream, State) :-
|
|
BitsToByte = num_bits_to_byte_boundary(!.Buffer),
|
|
put_bits(0, BitsToByte, !Buffer),
|
|
flush(!Buffer),
|
|
Stream = !.Buffer ^ bit_buffer ^ stream,
|
|
State = unsafe_promise_unique(!.Buffer ^ bit_buffer ^ state).
|
|
|
|
finalize_to_bitmap(write_buffer(Buffer)) = !:BM :-
|
|
NumBits = num_buffered_bits(write_buffer(Buffer)),
|
|
!:BM = bitmap.init(NumBits),
|
|
|
|
% Copy out the filled bitmaps starting at the end of the result bitmap.
|
|
%
|
|
LastBM = shrink_without_copying(Buffer ^ bitmap, Buffer ^ pos),
|
|
copy_out_bitmap(LastBM, NumBits, Index, !BM),
|
|
list.foldl2(copy_out_bitmap, Buffer ^ filled_bitmaps, Index, _, !BM).
|
|
|
|
% Copy the bitmap to the result bitmap, starting at the end.
|
|
%
|
|
:- pred copy_out_bitmap(bitmap::in, bit_index::in,
|
|
bit_index::out, bitmap::bitmap_di, bitmap::bitmap_uo) is det.
|
|
|
|
copy_out_bitmap(FilledBM, !Index, !BM) :-
|
|
Size = FilledBM ^ num_bits,
|
|
( if Size > 0 then
|
|
!:Index = !.Index - Size,
|
|
!:BM = bitmap.copy_bits(FilledBM, 0, !.BM, !.Index, Size)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred maybe_make_room(bit_buffer(Stream, State)::bit_buffer_di,
|
|
bit_buffer(Stream, State)::bit_buffer_uo) is det
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
|
|
maybe_make_room(!Buffer) :-
|
|
( if !.Buffer ^ pos >= !.Buffer ^ size then
|
|
make_room(!Buffer)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred make_room(bit_buffer(Stream, State)::bit_buffer_di,
|
|
bit_buffer(Stream, State)::bit_buffer_uo) is det
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
|
|
make_room(!Buffer) :-
|
|
UseStream = !.Buffer ^ use_stream,
|
|
(
|
|
UseStream = yes,
|
|
flush_chunk_to_stream(!Buffer)
|
|
;
|
|
UseStream = no,
|
|
store_full_buffer(!Buffer)
|
|
).
|
|
|
|
% This must only be called when the buffer has less than a word
|
|
% of space left.
|
|
%
|
|
:- pred store_full_buffer(bit_buffer(Stream, State)::in,
|
|
bit_buffer(Stream, State)::out) is det
|
|
<= stream.writer(Stream, bitmap.slice, State).
|
|
|
|
store_full_buffer(!Buffer) :-
|
|
Pos = !.Buffer ^ pos,
|
|
Size = !.Buffer ^ size,
|
|
OldBM = !.Buffer ^ bitmap,
|
|
State = !.Buffer ^ state,
|
|
|
|
% Double the buffer size at each allocation.
|
|
NewSize = (!.Buffer ^ size) * 2,
|
|
|
|
% Create the new bitmap, copying the left-over bytes from the old one.
|
|
% (We know that there are at most int.bits_per_int bits after the flush
|
|
% because that was the size of the bitmap created in `new', so
|
|
% we don't need to use copy_bits here).
|
|
NewBM0 = bitmap.init(NewSize + int.bits_per_int),
|
|
Remain = Pos - Size,
|
|
NewPos = Remain,
|
|
NewBM = NewBM0 ^ bits(0, Remain) := OldBM ^ bits(Size, Remain),
|
|
FilledBM = shrink_without_copying(OldBM, Size),
|
|
|
|
FilledBMs = [FilledBM | !.Buffer ^ filled_bitmaps],
|
|
|
|
set_all(NewBM, NewPos, NewSize,
|
|
unsafe_promise_unique(State), FilledBMs, !Buffer).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
/*
|
|
** XXX These instances don't work because of duplicated head variables.
|
|
|
|
:- instance stream.stream(write_stream(Stream), write_buffer(Stream, State))
|
|
<= stream.stream(Stream, State)
|
|
where
|
|
[
|
|
(name(_, Name, !Buffer) :-
|
|
BitBuffer0 = !.Buffer ^ bit_buffer,
|
|
State0 = BitBuffer0 ^ state,
|
|
Stream = BitBuffer0 ^ stream,
|
|
name(Stream, StreamName, State0, State),
|
|
Name = "bit_buffer.write.write_buffer(" ++ StreamName ++ ")",
|
|
set_state(State, BitBuffer0, BitBuffer),
|
|
!:Buffer = write_buffer(BitBuffer)
|
|
)
|
|
].
|
|
:- instance stream.output(write_stream(Stream), write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State)
|
|
where
|
|
[
|
|
(flush(_, !Buffer) :-
|
|
flush(!Buffer)
|
|
)
|
|
].
|
|
:- instance stream.writer(write_stream(Stream), bool,
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State)
|
|
where
|
|
[
|
|
(put(_, Bit, !Buffer) :- put_bit(Bit, !Buffer))
|
|
].
|
|
:- instance stream.writer(write_stream(Stream), bitmap.slice,
|
|
write_buffer(Stream, State))
|
|
<= stream.writer(Stream, bitmap.slice, State)
|
|
where
|
|
[
|
|
(put(_, Slice, !Buffer) :-
|
|
put_bitmap(Slice ^ slice_bitmap, Slice ^ slice_start_bit_index,
|
|
Slice ^ slice_num_bits, !Buffer)
|
|
)
|
|
].
|
|
*/
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module bit_buffer.write.
|
|
%---------------------------------------------------------------------------%
|