| /* align */ |
| align(p, 1). |
| align(b1, 1). |
| align(b2, 2). |
| align(b4, 4). |
| align(b8, 8). |
| align(struct(Fs), A) :- |
| phrase(encode_struct(Fs, 0), E), |
| maplist(align, E, As), |
| max_list(As, A). |
| |
| /* size */ |
| size(M, L) :- |
| phrase(encode(M), E), |
| length(E, L). |
| |
| /* pad */ |
| pad(N) --> { N =:= 0 } -> []. |
| pad(N) --> { N > 0 } -> [p], pad(N - 1). |
| |
| /* encode_struct */ |
| encode_struct([], N) --> { N =:= 0 } -> encode(b1). |
| encode_struct([], N) --> { N > 0} -> []. |
| encode_struct([H|T], Offset) --> |
| { |
| align(H, Alignment), |
| Padding is (Alignment - (Offset mod Alignment)) mod Alignment, |
| size(H, Size) |
| }, |
| pad(Padding), |
| encode(H), |
| encode_struct(T, Offset + Size). |
| |
| /* encode */ |
| encode(p) --> [ p ]. |
| encode(b1) --> [ b1 ]. |
| encode(b2) --> [ b2 ]. |
| encode(b4) --> [ b4 ]. |
| encode(b8) --> [ b8 ]. |
| encode(struct(Fs)) --> encode_struct(Fs, 0). |