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

=head1 SYNOPSIS

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

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

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

=head1 ABSTRACT

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

=head1 DESCRIPTION

=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,[EMAIL PROTECTED]) returns Str of byte {...}

This function takes a [EMAIL PROTECTED] 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
ignored.

sub Pack::pack (Str $template,[EMAIL PROTECTED]) 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

=head2 THE PACK TEMPLATE DESCRIPTION LANGUAGE (PTDL)

=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>]* <Perl6.name> [\( <argument> \)]? }

  rule adjective :w { <Perl6.name> [\( <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

=head3 SEMANTICS

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
discarded.

The following declarations are built in.

 int1
 int2
 int4
 int8
 int16
 int32       (aka int on 32-bit machines)
 int64       (aka int on 64-bit machines)

 uint1       (aka bit) (like vec)
 uint2
 uint4
 uint8       (aka byte)
 uint16
 uint32
 uint64

 rat32
 rat64       (aka rat on most architectures)
 rat128

 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

=cut





-- 
Please excuse my spelling as I suffer from agraphia. See
http://dformosa.zeta.org.au/~dformosa/Spelling.html to find out more.
Free the Memes.

Reply via email to