# Compiler signatures

This unit implements routines to attach [lib/type] signatures to Forth words,
the goal being to allow compilers to interface with those words.

Once a word has been annotated with a signature, it can be called from any
language that support all the types used in that signature.

## Example usage

Most of the time, you'll simply want to annotate a word. Here's how you could,
for example, annotate the word "max ( a b -- n )":

  uint 1 uint uint 2 annotate max

## Signature documentation

Many words in Dusk are annotated through this unit. When they are, the
documentation of such word will show the signature right under the Forth
signature, in this fashion:

  foobar ( a b -- c )
  uint foobar(uint b, uint a);
    Do something foobar-like.

These signatures use the C syntax, but this doesn't mean that these signatures
can only be used in C. They can be used in any language.

When a word contains a character outside the alphanumerical range, its signature
documentation will begin with a backtick:

  void `. (uint n);

This is the signature of the word "." and the backtick indicates that you're
unlikely to be able to call this word naively from your compiled language. In
[comp/c] or [comp/oberon], this means you'll have to use their backtick feature.

## Common signatures

In addition to supplying the mechanism to tag words with signatures, it also
tags some core words:

void abort();
void quit();
void noop();
void emit(uchar c);
void rtype(char* a, uint u);
void stype(char* s);
void `. (uint n);
void `.x (uint n);
void `.x2 (uint n);
void `.x1 (uint n);
void allot(uint n);
void* `allot@ (uint n);
void cfill(uint n, uint u, void *a);
void fill(uint n, uint u, void *a);
void cmove(uint u, void *dst, void *src);
void move(uint u, void *dst, void *src);

uint `le@ (void* a);
uint `wle@ (void* a);
void `le! (void* a, uint n);
void `wle! (void* a, uint n);
uint `be@ (void* a);
uint `wbe@ (void* a);
void `be! (void* a, uint n);
void `wbe! (void* a, uint n);

Additionally, some units that are used during Dusk bootstrapping are annotated
in the comp/sig unit rather than in those units in order to avoid having to pull
comp/sig in the bootstrap stream. Those units are:

* [lib/str]
* [io/stream]
* [fs/core]
* [drv/timer]

## API

### Words

annotate ( ... n ... n "name" -- )
  Create a signature through "signaturetype", then look for "name" in sysdict.
  Then, in [lib/tagl], tag the found execution token with "SIGT" and the created
  signature as a tag value.

annotate< ( ... n ... n -- )
  Like annotate, but apply the same signature to all the names written on the
  rest of line.

findannotated ( name -- ?sig xt-or-0 )
  Find name in sysdict and, if the entry is tagged with "SIGT", yield the found
  xt along with the annotated signature. Otherwise, xt=0 and sig is absent.
