develooper Front page | perl.perl6.language | Postings from July 2005

An idea for doing pack.

Thread Next
David Formosa
July 27, 2005 16:18
An idea for doing pack.
Message ID:

Last night I had an idea about a possable pack API.  Most likely when
Pugs gets signifigently powerfull I will attempt to implement it.
However I would like everyones input, below is a draft of its POD.

=head1 NAME

Pack - (un)pack structures as defined by a Template


  my Pack $template = Pack::compile {uint8 rat32};

  my $string = pack($template, 244, 3.14);

  my @unpack = unpack($template, $string);


This perl library defines a declarative minilanuage that allows the
conversion of Perl6 variables into (and from) a string of bytes.


=head2 MACROS and SUBS

macro Pack::compile ($template) is parsed (/\{ <Pack.template> \}/) {...}

This macro is used to compile a template at compile time.  This may
throw a execution at compile time if there is an error in the template.

sub Pack::eval (Str $template) returns Pack {...}

And this sub will compile a template at runtime.  This may return
undef and set $! if there is an error in the template.

sub Pack::pack (Pack $template,*@list) returns Str of byte {...}

This function takes a *@list of ordinary Perl values and converts them
into a string of bytes according to the $template.  If you procide
more arguments then $template requires, the extra arguments are

sub Pack::pack (Str $template,*@list) returns Str of byte {...}

A convenience function, $template is compiled into a Pack object and
then run on @list;

sub Pack::unpack (Pack $template,Str of byte $expr) returns List {...}
sub Pack::unpack (Str  $template,Str of byte $expr) returns List {...}

These functions do the reverse of Pack::pack


=head3 SYNTAX

The template description language describes the structure of the
string as a sequence of declarations.  Each declaration consists of a
type, an optional argument and zero or more adjectives.  Also each
declaration may be bound to a variable.

grammar {

  rule template :w { [<binding>? <declaration>]* };

  rule binding :w { [<Perl6.variable> | <Perl6.literal>] <":=:"> }

  rule declaration :w { [\: <adjective>]* <> [\( <argument> \)]? }

  rule adjective :w { <> [\( <argument> \)]? }

  rule argument :w { <Perl6.variable> | <Perl6.closure> | <Perl6.literal> }


For example the following are valid templates

$^0 :=: byte
@^_  :=: str(8)
@^_  :=: str($^0)
$^1 :=: rat32


When packing if a declaration is bound to a scalar variable then the
contents of that variable are packed into the return value of pack
according to the nature of that declaration.

Simmerly when unpacking each declaration will set the value of the
scalar it is bound to based on its nature and the value of $expr.

$^number has a special meaning in PTDL $^i is the ith (zero indexed)
item of @list when packing and the ith (zero indexed) item of the
return array when unpacking.

If a declaration is bound to an array, when packing items will be
shifted out of the array and then packed according to the declaration.
Simmerly when unpacking the array will have the declaration's return
values pushed into it.

@^_ has a special meaning in PTDL.  It is an alias to @list when
packing and an alias to the return array when unpacking.  By default a
declaration is bound to @^_ .

If a declaration is bound to a literal then when packing the value of
that literal is packed, when unpacking the unpacked value is

The following declarations are built in.

 int32       (aka int on 32-bit machines)
 int64       (aka int on 64-bit machines)

 uint1       (aka bit) (like vec)
 uint8       (aka byte)

 rat64       (aka rat on most architectures)

 str   A string of bytes
 utf8  A number encoded using the utf8 mapping (doesn't check for bad unicode)
 UTF-8 A codepoint endcoded using UTF-8

 noop   Does nothing (though its adjectives may have side effects)

 hex   A hexadecimal string
 uuencode A uuencoded string
 base64 A base64 encoded string
 base32 A base32 encoded string
 base16 A base16 encoded string
 ber    A ber compressed integer

The following adjectives are built in.

:bigend   Endcode this using bigendian order
:litend   Endcode this using littleendian order
:pad($n)  Pad to $n bytes
:padchar($char)  Pad using $char
:term($char) String is $char terminated
:mvabs    Move to absolute position filling with padchar if defined.
:mvrel    Move to relative position filling with padchar if defined.

For convenience the following declarations are defined.

a($n) => :pad($n) :padchar("\x00") byte
A($n) => :pad($n) :padchar(" ") byte
b($n) => :bigend bit($n)
B($n) => :litend bit($n)
c => int8
C => uint8
d => rat64
f => rat32
h => :bigend hex
H => :litend hex
i => int
I => uint
l => int32
L => uint32
n => :bigend int16
N => :bigend int32
q => int64
Q => uint64
s => int16
S => uint16
u => uuencode
U => UTF-8
v => :litend int16
V => :litend int32
w => ber
x => :pad(1) :padchar("\x00") noop
X => :mvrel(-1) noop
Z($n) => :term("\x00") :pad($n) :padchar("\x00") byte
@($n) => :mvabs($n) :padchar("\x00") noop

For convenience the following adjectives are defined

:network => :bigend
:vax     => :litend


Please excuse my spelling as I suffer from agraphia. See to find out more.
Free the Memes.

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About