Memory layout of a data structure: Difference between revisions

Line 348:
This is, admittedly, more verbose than the equivalent code would be in, say, C, but it permits things which are more difficult to pull off in such languages. First, the code here is perfectly type safe (despite the use of <tt>'''unsafe'''_set</tt> and <tt>'''unsafe'''_clear</tt>). It is literally impossible to set or clear bits outside of the bounds of the bit array used in the physical representation. It is as easy to set and clear individual bits in the bit array as it is to use bit notation in C, and it's easier to do than when using the safer "integer variable with bitwise operators" technique. Setting and clearing groups of bits is even easier via the <tt>rs232_set_bits/2</tt> function: merely pass in a list of symbolic names. Changing the bitwise representation is a matter of changing the bit numbers in <tt>to_index/1</tt> and possibly changing the size of the bit array in <tt>rs232_bits/1</tt>. Indeed the entire underlying representation and implementation can change without the interface changing at all.
 
=== rs232.m ===
<lang Mercury>
:- module rs232.
Line 401 ⟶ 402:
:- end_module rs232.
</lang>
 
=== rs232_main.m ===
<lang Mercury>
:- module rs232_main.
 
:- interface.
 
:- import_module io.
 
:- pred main(io::di, io::uo) is det.
 
:- implementation.
 
:- import_module bitmap, bool, list, rs232.
 
main(!IO) :-
Com1 = rs232_set_bits(rs232_bits, [data_terminal_ready, data_set_ready]),
Com2 = rs232_clear_bits(rs232_bits(yes), [data_terminal_ready, data_set_ready]),
write_string("Com1 bits = ", !IO),
write_string(to_string(Com1), !IO), nl(!IO),
write_string("Com2 bits = ", !IO),
write_string(to_string(Com2), !IO), nl(!IO).
 
:- end_module rs232_main.
</lang>
 
==== Usage and output ====
$ '''mmc --make rs232_main'''
$ '''./rs232_main'''
''Com1 bits = <9:1400>''
''Com2 bits = <9:FF80>''
 
=={{header|OCaml}}==