Jump to content

Memory layout of a data structure: Difference between revisions

Line 347:
 
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.
 
Aiding in changing the underlying representation at will is the fact that the exposed type&mdash;<tt>rs232</tt>&mdash; is an opaque data type. Instead of exposing the fact of the <tt>bitmap</tt> implementation to the outside world, it is carefully concealed by the implementation. It is impossible for any code using this module to operate on the underlying bitmap with anything other than the API which has been exposed. This means that should it be deemed desirable to instead use an <tt>int</tt> as the underlying representation, this can be done without changing even one byte of client code.
 
=== rs232.m ===
Line 374 ⟶ 376:
:- func rs232_set(rs232, rs232_pin) = rs232.
:- func rs232_clear(rs232, rs232_pin) = rs232.
 
:- pred rs232_is_set(rs232::in, rs232_pin::in) is semidet.
:- pred rs232_is_clear(rs232::in, rs232_pin::in) is semidet.
 
:- func rs232_set_bits(rs232, list(rs232_pin)) = rs232.
Line 391 ⟶ 396:
rs232_set(A, Pin) = unsafe_set(A, to_index(Pin)).
rs232_clear(A, Pin) = unsafe_clear(A, to_index(Pin)).
 
rs232_is_set(A, Pin) :- unsafe_is_set(A, to_index(Pin)).
rs232_is_clear(A, Pin) :- unsafe_is_clear(A, to_index(Pin)).
 
rs232_set_bits(A, Pins) = foldl((func(Pin, B) = rs232_set(B, Pin)), Pins, A).
Line 431 ⟶ 439:
write_string(to_string(Com1), !IO), nl(!IO),
write_string("Com2 bits = ", !IO),
write_string(to_string(Com2), !IO), nl(!IO).,
write_string("Com1 DTR is ", !IO),
( rs232_is_set(Com1, data_terminal_ready) ->
write_string("set.", !IO), nl(!IO)
; write_string("clear.", !IO), nl(!IO) ),
write_string("Com2 DSR is ", !IO),
( rs232_is_clear(Com2, data_set_ready) ->
write_string("clear.", !IO), nl(!IO)
; write_string("set.", !IO), nl(!IO) ).
 
:- end_module rs232_main.
Cookies help us deliver our services. By using our services, you agree to our use of cookies.