# Big Moustache

*Tea for two and two for tea...*

Don't you think that the "{" character looks like a mustache? A whole lot of
them means a big moustache.

This library is a way of compiling fancy *and* fast memory accesses. The syntax
of such memory accesses is:

  <action>{<modifiers>}

For example, "@{c+4}" is the equivalent of "4 + c@", but compiled in efficient
HAL [doc/hal].

That generated HAL is really efficient and is the main reason why Big Moustache
exists. Sure, the syntactic sugar is nice, but it alone isn't worth it. All
those moustaches are really fast.

Not all actions/modifiers combinations make sense. When they don't, their usage
lead to undefined behavior. Incompatibilities are explicitly stated in the
documentation below. The rest is compatible.

Moustaches are for compiling accesses, not interpreting them. That being said,
we make an exception some actions, that is "@" "!" and "@!" which can be used in
interpret mode. That's sometimes quite useful. However, interpret mode
moustaches cannot be used with modifiers "R F A P".

## Target

We call "target" the address or value that the modifiers inside a moustache
designate. By default, and like the HAL does, targets contain a single level of
indirection.

For example, "{'data}" targets the memory at the address that the word "data"
will yield *at the moment the moustache is compiled*. "{}" targets the memory
pointed by the address in the W register *at runtime*. "{&}" targets the W
register directly.

### Managing W

There's a fundamental difference between W and non-W targets. Moustaches will
have a different signature depending on whether they target W or not.

For example, "@{}", which targets W and is the equivalent of a straight "@", has
the signature ( a -- n ). However, "@{R+4}", which targets RSP, has a signature
( -- n ). Similarly, "!{+4}" has a signature ( n a -- ) where "!{'foo}" has a
signature ( n -- ).

The principle is the same for all actions.

## Actions

Possible actions are:

  Access       @ ! @! @A
  Arithmetics  + - swap- * / lshift rshift and or xor = <> < > <= >=
  Execution    execute
  Bind         create value method

As a general rule, actions have the same stack effect as their regular Forth
word counterpart, but operand order varies. When there's a "left" operand, it
will generally be the moustache target. The right operand will either be a
number being popped from PS or a literal supplied in the moustache.

It is also important to remember that moustache targets usually have a level of
indirection. For example, the signature of "-{+4}" isn't actually ( n n -- n ),
but rather ( n a -- n ) and is equivalent to "4 + @ swap -" (in efficient HAL).

### Access actions

The @ ! @! actions are straigtforward and pretty much do the same thing as their
regular word counterpart. @{}

"@{}" can't be used with "#". "@!{}" *can* be used with "#" and will have the
effect of pushing a new element to PS. For example, "@!{'foo}" has the signature
( n -- n ) while "@!{'foo #42}" has ( -- n ).

Neither of "@" "!" or "@!" can be used with "!" or "&".

"@A" is the equivalent of the "@" indirection modifier (see below), that is, it
fetches to the A register instead of the W register.

### Arithmetics actions

Arithmetic actions all follow the same logic and support all the modifiers.
They're the most "regular" of the actions.

One thing to remember is the order of the operands. The target comes first. The
plain english of an arithmetic moustache is "apply 'other' on 'target'", for
example "subtract 'other' from 'target'" or "is 'target' greater than 'other'?".
Here are some examples and their naive equivalents:

  -{&}      --> swap -
  <{&}      --> >
  -{& #42}  --> 42 swap -

### Execute actions

The "execute" action allow indirect calls with offsets. They support only a
select few modifiers. If the target is W, a "drop" will be compiled before the
branch. It is incompatible with "# c w !" modifiers.

### Bind actions

Bind actions have their own paragraphs below.

## Modifiers

Things become interesting when we add modifiers in the mix. Broadly speaking,
they try to expose as much as the HAL machinery as possible, but in terser
semantics.

  Target      R F P A '<val>
  Offset      +<val> -<val>
  Literal     #<val>
  Width       c w s<val> n<val>
  Flags       ! & k ~
  Recall      ><val>
  Indirection @<val>

Modifiers with <val> parameters are parsed with "wordorquote", their whole
content interpreted as Forth code with the expected signature ( -- n ).

Modifiers order doesn't matter except for ">" and "@".

### Target

Target modifiers change the target of the moustache (which is W by default).

"R" is for "RSP". For example, "@{R+4}" will fetch the second element from the
RS.

"F" means "Frame". This is RSP as it was at the beginning of the word, as
tracked by [rcnt] (see below). For example, "{F-4}" is the equivalent of the
"V1" local variable (see below). "{F-16}" is equivalent to "V4". Those paying
attention will notice that it means that "{F}" refers to the word's return
address regardless of the frame size (unless [rcnt] is messed up).

"P" is for "PSP". See "PSP dynamics" below.

"A" means "Address Register" (from the HAL). See paragraph below.

"'" means "Memory address". "<val>" is a hardcoded memory address. It is
important to remember that "<val>" is evaluated at compile time, with its result
being stored as a number in the moustache.

If "<val>" is "@", it's a special value that means "take value from compile-time
PS".

Examples:

+{R#1}         --> r@ 1+
+{R+4 !#1}     --> r> r> 1+ >r >r
+{!'foo}       --> foo +!
W@A @{+4} @{A} --> @+ swap @ swap

### Offset

Offset, in bytes, is specified by the "+" or "-" modifiers. That number of bytes
will be added to the address before the memory access is made.

The "+" modifier has a special parameter: another "+" (example: "create{++}").
When such a parameter is encountered, we add the offset of the previous
moustache to the current one and on top of that, we include the size of that
moustache. This is mostly useful for defining a series of adjacent fields in a
struct. Example:

  create{}    field1 \ at offset 0
  create{++c} field2 \ offset 4, 8-bit
  create{++c} field3 \ offset 5, 8-bit
  create{++w} field4 \ offset 6, 16-bit
  create{++}  field5 \ offset 8, 32-bit

Sometimes, once you're done describing all your fields, you'd like to store your
struct size somewhere. Here's a little trick you can use:

  0 @{++&} const SZ \ SZ=12

See what we did here? This moustache is an interpreted moustache and the
previous moustache is the "field5" one. It means that previous moustache offset
added to its field size correspond exactly to the struct size, which we "freeze"
in the SZ const.

And later, you'd like to extend that struct with more fields? No problem:
"create{+SZ} field6".

That special target also sets the "base target" and "indirection" fields of the
moustache. This is needed for "++" to work with the "'"  and "@" modifiers. This
allows you to have a "singleton" set of fields targeting a hardcoded memory
address. Example:

  create mymem 42 , 54 ,
  create{'mymem} field1
  create{++}     field2
  @{>field2} . \ prints 54

Notice how the @{} didn't need to be preceded by "mymem". That's because
"field2" directly targets "mymem+4".

Sometimes, fields represent arrays and a series of "++" doesn't quit cut it. We
then need to adjust the offset manually:

  create{}      field1 \ at offset 0
  create{++}    arrayof3ints \ offset 4
  create{>>+12} field3

Why not use "++" for "field3"? Well, you could, but you'd have to take the 4
bytes that were automatically added in your calculations, which would mean
"create{+++8} field3", which is a bit less clearer that "{>>+12}" since it
"8" isn't exactly the size of 3 ints.

### Literal

When this modifier is set, the "n" operand of the action is replaced with a
compile-time literal. For example, "-{+4#42}" is the equivalent of
"4 + @ 42 swap -" (but much more efficient, of course).

### Width

A moustache's default width is 4 bytes (native 32-bit access). You can make a
moustache's access with into 8-bit or 16-bit with "c" or "w". It works pretty
much exactly like "8b)" and "16b)". If the moustache has a "c", the access is
8-bit, if it has a "w", it's 16-bit.

The "s<val>" and "n<val>" modifiers are used for describing an array. See
"Working with arrays" below. "s" sets the width of the moustache to an arbitrary
number and represents the size in bytes of a single element of the array. "n"
sets the "nbelem" field of the moustache and represents the number of elements
in the array.

Although the "s" and "n" don't actually set the "&" modifier, it's difficult to
imagine a possibly valid use case for "s" and/or "n" without a "&". As soon as
a moustache width is something else than 1, 2 or 4, indirect access is broken.

### Flags

"!" is the "store" flag. Instead of yielding the result to PS, it will store it
to the same address as specified. For example, "+{!}" is the equivalent of
"+!".

"&" is the "deref" flag. It indicates that instead of working with a source
address, we work on a value directly. For example, "lshift{&#3}" is the
equivalent of "3 lshift". Incompatible with "!".

"k" is the "keep" flag. When set the "argument" of the action (that is, the "not
the target" part of arithmetic actions or the "!" action), which always comes
from PS, is not consumed. For example, "!{k}" is the equivalent of "over swap
!". This only works on arithmetic and "!" actions. Incompatible with "#".

"~" is the "don't save" flag, indicating that this moustache shouldn't be saved
into the "previous moustache" slot, used for the special "++" and ">>"
modifiers.

### The ">" modifier

This modifier allows you to load a moustache previously saved with one of the
Bind actions (create{}, value{}, etc.). This effectively allow you to bind
moustaches to names, for example, as field specifications. This modifier copies
the specified moustache as-is, completely overwriting whatever was there. This
means that the ">" modifier should always be the first one of the moustache.
Example:

  create data 42 le, $1234 le,
  create{c+4} some8bfield
  : foo @{>some8bfield} ;
  foo .x \ prints 00000034

There is also a special recall target for the ">" modifier: another ">"
(example: "create{>>}"). It recalls the last moustache as is.

Note that the concept of "previous moustache" is a compile time concept. Also
note that the ">" target is not a regular "<val>" argument and it must not be
followed by a whitespace.

### The "@" modifier

The "@" modifier words a bit like the ">", that is, it takes another moustache
as a parameter. However, that moustache isn't for the direct access being
described, but rather for an indirection fetch prior to that access.

When a moustache has this modifier, it will generate a "fetch to A register" for
the indirection moustache prior to generating its main access. Example:

  create data 42 , 54 , 1234 ,
  : foo data >r +{@V1 +4} rdrop ;
  12 foo . \ prints 66

It gets even better! You can *inline* indirection moustaches:

  create dataptr data 4 + ,
  : bar +{@{'dataptr} +4} ;
  12 bar . \ prints 1246

It's sometimes useful to access indirections moustaches through the ">>"
mechanism, for example for "increase after fetch" patterns. When using "named"
indirections, you can easily reuse that name, but when using the inlined
indirection, it's trickier. You can't directly use ">>" because the "main"
moustache will have overwritten the "prev" slot. What you can do to work around
that is to use the "~" modifier on the main slot:

  : foo data >r +{@{R} ~} +{>>!#4} +{@{R} } rdrop ;
  12 foo . \ prints 108 (42+54+12)

The "@" modifier can only be used in "compile" mode, not in interpret mode.

A moustache with an indirection has, by default, a "A" target. You *can* assign
it another target after your "@" modifier (except with ">", which explicitly
ignores the recall target if an indirection is present).

## Whitespaces inside moustaches

As a general rule, whitespaces aren't needed inside moustaches. However,
"wordorquote" which is used for parsing "<val>" modifiers, needs a whitespace
boundary if it's not quoted.

However, Big Moustache adds a special treatment for the last modifier allowing
it to not end with a whitespace.

This means that if you only have one "<val>" modifier, you can put it last and
thus avoid whitespaces. If you have more than one, the one that isn't the last
needs a whitespace after its "<val>" unless it's a quoted val.

The "inlined indirection", that is, the "@" modifier followed by "{", must
always have a whitespace following its closing "}".

Special targets ">>" "++" and "'@" don't need to be followed by whitespaces.

Spurious spaces (spaces that aren't required as per the rules above) are
silently ignored.

Examples:

  @{+foo}
  @{+foo #bar}
  @{+"foo bar"#baz}
  @{++c}
  @{>>+4}
  +{@{+4} c+8}

## Stack signature matrix

Keeping up with all possible stack effects for all possible combinations of
actions and modifiers can get dizzying, so here's a matrix to help out.

All arithmetic actions have the same signature and A/F/R/P/' targets also have
the same signature, so only one of them is represented.

         {}        {A}     {k}         {Ak}      {#}     {A#}
@        a -- n    -- n    n/a         n/a       n/a     n/a
!        n a --    n --    n a -- n    n -- n    a --    --
@!       n a -- n  n -- n  n/a         n/a       a -- n  -- n
@A       a --      --      n/a         n/a       n/a     n/a
+        n a -- r  n -- r  n a -- n r  n -- n r  a -- n  n -- r
execute  a --      --      n/a         n/a       n/a     n/a

The store, which only makes sense in arithmetic actions, have these
signatures:

{!}    n a --
{!k}   n a -- n
{!#}   a --
{!A}   n --
{!Ak}  n -- n
{!A#}  --
{!A#k} -- n

## Working with the A register

Exposing HAL's A register is one of the great aspects making moustaches
powerful. It can decrease PS juggling a lot.

The main way through which you'll access the A register is the "@" modifier
described above.

It's useful to remember that indirections can serve more than once! Once you've
placed an indirection in the A register using "@", you can reuse that address in
a following moustache using the "A" target. Just be aware of A lifetime rules
[doc/hal], that is that almost all words will destroy its value!

There is, however, a small list of core words (again, see [doc/hal]) that make
the promise of never touching the A register and those words give you a big
enough sandbox for some really satisfying PS juggling savings.

Moustaches also make the promise of never touching the A register, except of
course for actions/modifiers that explicitly change it.

The S register is extensively used by moustaches and is never preserved. It is
thus not exposed by the moustache API.

## PSP dynamics

Using the "P" target can be tricky and one must be perfectly aware of PSP
dynamics before doing so. Let's use an example PS state:

  4 3 2 1

"1" is W, "2" is PS's top of stack.

The {P} target works exactly like the {R} or the {A} target, that is, in this
example, a moustache {P} would target "2", {P+4} would target "3", {P+8} would
target "4".

So far, so good.

However, actions affect the stack! Now this is tricky. For example, @{P} has a
signature ( -- n ) and !{P} has the stack signature ( n -- ). What does {P}
target? (Quick answer: @{P} targets "1" and !{P} targets "2")

To answer this question, one must be aware of moustache logic when comes the
time to grow or shrink PS: growth happens before the action, shrink happens
after it.

When you think about it, it's logical: when you need to grow PS to accomodate an
action, it *has* to happen beforehand. When you need to shrink PS after having
consumed elements from it, it *has* to happen afterwards.

So, here are a few examples, again with a "4 3 2 1" PS:

Moustache   Target  Stack afterwards

@{P+4}      2       4 3 2 1 2
!{P+4}      3       4 1 2
+{P+4}      3       4 2 3 4
!{P+4 #42}  3       4 42 2 1
+{P+4 #42}  2       4 3 2 1 44
+{P+4 !}    3       4 4 2
+{P+4 !#42} 3       4 44 2 1

When using "P" in an indirection, no adjustment need to be made because this
indirection is a "fetch to A" operation (no stack effect) and happens before the
main action.

## Binding moustaches to names

"create{...} name" evaluates the specified moustache and then saves it to
memory, bound to "name". Calling "name" yields the address of a moustache
structure (that structure is opaque and only partially exposed by the moustache
API).

That address can be used by the ">" to "recall" that moustache in a particular
action.

### value{} and value

value{} binds a "@" action and a moustache to a word. For example,
"value{+4} foo" creates "foo" which is the functional equivalent to "@{+4}".

Values also have "setters" [doc/usage/word] meaning that they can be used with
"to". Doing so is the exact equivalent of using the "!" action.

But there's more: values can be used as saved moustaches. If, for example, you
want to write to the "foo" value above, you can do "!{>foo #42}" and it's going
to work as if "foo" was a "create{}" instead of a "value{}". This is done by
having a special global flag that indicates whether we're currently recalling a
moustache. The "value{}" bind then checks for that global variable and yields
moustache instead of executing it if we're in a "recall" context.

And on top of that, there's also "value" which is the equivalent of
"here# swap , value{'@}". Full example:

  create data 42 ,
  value{'data} myval
  myval . \ prints 42
  !{>myval #54}
  data @ . \ prints 54
  myval . \ prints 54

  42 value otherval
  otherval . \ prints 42
  !{>otherval #54}
  otherval . \ prints 54

Values can be scried [doc/usage/word]. When they are, they yield a pointer to
their moustache.

### Custom values and setters

It's possible to create value{}-like words with custom getters and setters
through the word "}value". This allows things like "bigendian{}" [mem/endian]
and "ioport{}" [drv/pc/ioport].

The custom getter is activated when a "naked call" is made to the value word.
To access the setter, a new word is introduced: to. On regular values, "to" is
equivalent to !{}, but on values with custom hooks, "to" calls the custom
setter.

  42 value foo
  54 to foo         \ Same as "42 !{>foo}"
  : bar 54 to foo ; \ Works too

You create a custom value with "}value". You supply "}value" with a getter
*compiler*, a setter *compiler* as well as a saved moustache and it will create
a find selector [doc/usage/word]. For example, the implementation of "value{}"
is:

  : value{ ['] value!, ['] value@, m<, }value ;

While the "to" mechanism is mostly for values, it's fully generic and can be
used in other context. "to?," compiles a check to be used in a find selector:

  :> ."getting!" ;
  :> ."setting!" ;
  code foo findselector
    litn to?, ifz, swap i) @, then exit,
  foo \ prints "getting!"
  to foo \ prints "setting!"
  : bar to foo ;
  bar \ prints "setting!"

### method{}

method{} is a bound version of execute{}, that is, calling this word is almost
the equivalent of compiling a execute{} with the same moustache. We say "almost"
because unlike a straight execute{}, PS top (the "self" argument) is kept in
place.

A method{} moustache can't be used with "R F A P '" modifiers.

As with value{}s, method{}s can be used as saved moustaches:

  create data 42 , ' abort ,
  : fooimpl ."hello " @ . ;
  method{+4} :foo
  ' fooimpl data !{>:foo}
  data :foo \ prints "hello 42"

## Working with arrays

The "s" and "n" modifiers allows one to describe an array with moustaches. This
allows one to elegantly fit such a field in a struct using the "++" pattern, but
this also allows the use of the "[]" action from [hal/muldiv].

Let's look at an example where we have a struct "Bar" which contains an array of
structs "Foo". We could describe them thus:

  \ Foo
  value{}   foo1
  value{++} foo2
  0 @{++&} const FOOSZ

  \ Bar
  value{} bar1
  value{++&sFOOSZ n42} foos
  value{++} bar2
  0 @{++&} const BARSZ

As you can see, the field "foos" represents an array of 42 "inlined" structs
within the Bar struct. Let's imagine that we have a "Bar" instance named "bar"
and that we want to print the "foo1" field of its 12th "foo" element:

  11 bar []{>foos} foo1 .

This could also work and would be faster if your index is constant:

  bar []{>foos #11} foo1 .

What happens if "foos", instead of being an "inlined" array, is a pointer to an
array? Moustaches, being a direct mapping to HAL parameters, don't support
multiple indirections, so there's no way to describe this in a single moustache.
However, what you can do is to describe a second moustache "foos*" to elegantly
handle that indirection. Let's redefine Bar:

  \ Bar
  value{} bar1
  value{++} foos value{~&sFOOSZ n42} foos*
  value{++} bar2
  0 @{++&} const BARSZ

In these new fields, "foos" is a pointer to an array and "foos*" describe that
array (this time, with no "++" offset). The "~" modifier is used to avoid
destroying our "moustache streak" and be able to continue defining further
fields with "++" in them. How do we use that?

  11 bar foos []{>foos*} foo1 .

And if you're in a tight loop, you can save a PS push/pop in the above pattern
with the A register:

  11 @A{'bar} @A{>foos A} []{>foos* A} foo1 .

## Local variables

It's a common pattern, to avoid PS juggling, to place an element on RS (Return
Stack) and recall that element with r@. It works well, but unfortunately, this
only works with a single element. Another drawback is that this element can be
"buried" by a pattern (a "next" loop for example) that needs to place something
on RS.

A workaround to this is to declare a "private" value near the word and store
temporary values in there. It works too, but because those values are statically
allocated, this can't be done in words that require recursion. Also, it's a bit
verbose.

Local variables are there to the rescue! There are 4 of them: V1 V2 V3 V4. These
words do a simple thing: they reference an element on RS using value{}s. They
are also impervious to being "buried" because they remember their "slot" at
compile time and adjust their compilation accordingly.

In other words, if FRAME is the address in memory of RSP when the word starts
executing and considering the fact that RSP grows "downwards" in memory,
V1=FRAME-4 and V4=FRAME-16.

When using local variables, you are responsible for pushing and popping to/from
RS. Example:

  : foo ( a b c -- ) >r >r >r V1 . spc> V2 . spc> V3 . 2rdrop rdrop ;

  1 2 3 foo \ prints "3 2 1"

  : inc ( a -- a+1 ) >r +{>V1 !#1} V1 rdrop ;
  42 inc . \ prints 43

  \ this works too
  : inc5 ( a -- a+5 ) >r 5 >r begin +{>V1 !#1} next V1 rdrop ;
  42 inc5 . \ prints 47

### Manual [rcnt] adjustments

The "R counter" that determines local variable slots at compile time is
oblivious to conditional code or loops. It's not common to have code that
conditionally maintain separate RS levels (they always need to stay balanced, of
course), but it can happen. For example, in early "exit" paths, we often have to
include a few "rdrop" before the "exit" call. If you have a fancy word that
returns a variable number of arguments, you might end up with >r and r> in
loops. All of this messes up the "R counter". You can manually adjust it through
the [rcnt] variable. For example, if you want your next ">r" to push to V1, you
would precede it with:

  [ 0 [rcnt] ! ]

Another use for manual [rcnt] adjustments is to have local variables to "below"
the word line. For example, if for some reason you'd want "V1" to be bound to
the word's return address, you can assign -4 to [rcnt]:

  : foo [ -4 [rcnt] ! ] $1234 to V1 ; \ returns to address $1234

## Reading moustache documentation

Documentations for units defining publicly accessible moustaches will list them
in a "Fields" section. It will be a list of names with the description of
what the moustache points to. When we refer to a moustache in such
documentation, we will generally mean a "value{}" rather than a "create{}"
because it's offers a more convenient API. If it's not a value{}, it will be
explicitly indicated.

## API

<action>{} *I*
  Execute or compile a moustache.

W@A *I*
  Compile a copy of the W register into the A register.

){} ( -- halop )
  Interpret a moustache and yield the associated halop. For example,
  "){>foo} @," in interpret mode is the equivalent of "@{>foo}" in compile mode.
  If the moustache contains an indirection, it will be compiled by the "){"
  word.

  This word cannot be compiled for fundamental reasons: halops are ephemeral
  because of the literal bank system. If we allowed halops to be "frozen" as
  literals, they would end up referencing an incorrect literal and thus
  miscompile.

  Most of the time, what you want is the offset of a field to encode somewhere.
  You can use "offset{}" for that.

offset{ ( -- n ) *I*
  Reads a moustache and yield its "offset" part.

create{} ( "name" -- )
  Create a new "name" cell, parse enclosed moustache and save it there.

value{} ( "name" -- )
  Like a create{}, but binds a fetch action to the associated name (see
  paragraph above).

}value ( set, get, m -- )
  Compile a "custom value" as described above.
  "set," is a reference to a "setter compiler" word.
  "get," is a reference to a "getter compiler" word.
  "m" is a reference to a saved moustache.

V1 V2 V3 V4
  Built-in value{}s corresponding to F-4 F-8 F-12 F-16.

MOUSTACHESZ ( -- n )
  Size of a moustache struct.

moustache ( -- a )
  Last moustache to have been parsed.

prevmoustache ( -- a )
  Copy of the moustache that was parsed prior to this one.

m< ( -- )
  Parse a moustache from the input stream.

m<, ( -- m )
  Parse a moustache from the input stream and then write it to "here", yielding
  its written address.

val< ( -- n )
  Parse a "<val>" from the input stream.

}) ( -- halop )
  Yield a HAL operand corresponding to the current moustache. This combines the
  "base", "off", "width", "ref" and "applyrcnt" to yield that result.

  For reference, implementation of "@{" is essentially "m< }) @,".

}width) ( halop -- halop )
  Applies current moustache's width to "halop". This is not required if "halop"
  comes from "})", as it's already been applied.

}base) ( -- halop )
  The "base" HAL operand, without anything (offset, ref, etc.) applied to it,
  corresponding to the "base" field of the active moustache. For example, it
  It would return "W)" whether the moustache is "{}" or "{c&+4}".

}addr ( -- a )
  Yields a runtime address corresponding to the current moustache. This also
  resolves indirections in the moustache if there are any.

}move ( m -- )
  Copy moustache "m" to "moustache" buffer.

}compile ( m -- )
  Compile a "}move" of the moustache "m".

?moustache@ ( a -- n )
  Unless the current moustache is a reference, executes @, w@ or c@ depending on
  moustache's width.

moustache! ( n a -- )
  Executes !, w! or c! depending on moustache's width.

?moustachelit ( -- ?n f )
  Yields whether current moustache has a literal and, if it has, yield it as
  "n".

flags ( -- n )
  Yields the whole 32-bit flags field for the active moustache.

base ( -- n )
  Yields the "base" field of the active moustache.

base! ( n -- )
  Sets the "base" field of the active moustache.

## Flags words

The words:

  store ref keep nosave

all have the signature ( -- f ) and yield the flag of the same name for the
active moustache.

## Field words:

The words:

  off lit width nbelem indirection

all have the signature ( -- a ) and yield the address corresponding to the
field of the same name, for the active moustache.

## Implementations details

A moustache is a 24b struct divided in 6 fields:

+00 Flags
+04 Offset
+08 Literal
+0c Width
+10 NbElem
+14 Indirection

Flag bits are organized thus:

b2:0 base (0=W 1=R 2=A 3=' 4=F 5=P 6=S)
b5:3 reserved
b6   has literal
b7   store
b8   ref
b9   keep
b10  nosave

Offset contains the compound result of both "+" and "'" modifiers.

The literal field is only used in conjunction with the "has literal" flag.

Width is the width, in bytes of the moustache. "c" sets it to 1, "w" sets it to
2.

NbElem is the number of elements represented by the moustache.

A moustache has a reset value of 0/0/0/4/1/0.
