=head1 TITLE

Parrot Forth

=head1 Introduction

This document assumes that you're familiar with Forth. If you aren't,
more help can be found at http://www.forth.org.

Parrot Forth is based on the ANS Forth standard, with some GForth
extensions, as well as some local extensions specifically for
interfacing with the underlying Parrot engine and interacting with
other Parrot code.

=head1 Caveats

Please be aware that Parrot Forth is a work in progress and, as such,
isn't yet done. Not all of the ANS core and core-ext words are in, and
bits and pieces of other sections of the ANS extension word set (such
as some of the floating-point words) are in place.

Parrot forth will eventually provide at least all the core and
core-ext words, with the behaviour caveats as noted later on in this
document.

=head1 Parrot Extensions

This section details the spots where Parrot Forth differs from ANS
forth.

=head2 Parrot variants of standard structures

Internally Parrot is very different from most forths, in part because
of its VM nature and in part through a desire to make it easy for
Parrot Forth to interact with other Parrot languages. This has
resulted in a number of decisions that are, for the most part,
legitimate interpretations of the standard (such as using a combined
data stack) but unusual.

Some, like the lack of double words and single-precision floats, may
break programs that expect to be able to manipulate parts of
values. (As, once you push a doubleword on to the stack you can treat
each half as a separate single-cell value, albeit very
machine-dependently) That should be reasonably unusual, so just don't
do that.

=over 4

=item Combined data stack

Parrot uses a single stack to hold integers, floats, strings, PMCs,
execution tokens, and whatnot. Each element takes a single cell on the
stack.

=item Full PMC usage

All values on the Forth stack are, in fact, PMCs rather than plain
integers, floats, or whatever. All integers are stored in Integer
PMCs, floats in Float PMCs, and parrot strings in PerlString PMCs.

This has a number of unfortunate efficiency issues, but it makes the
implementation much easier.

This also means that Parrot Forth will do autocoercion on data
elements. The following:

  1.2 1.6 + .

will print C<2>, since C<+> is defined as integer addition. Note that
this will not invoke the addition vtable methods on the two operands,
but instead invokes the get_integer method for them. To use the vtable
methods use the p variants of the operands. (C<p+>, C<p-> and their
friends)

=item No doublewords

Parrot integers are 32 bits. The words that act on doubles behave
identically to their single-word variants.

=item No single/double float distinction

All floats are whatever Parrot was compiled with originally, generally
64-bit doubleword floats. All float words that act on single or double
words will act identically.

=item Unsignedness is ignored

Generally all math operations act on integers as if they were signed,
and the engine acts accordingly. Unsigned variants of words act
identically  to their signed counterparts, including returning signed
values where they might occur.

=item Fake memory store

Parrot forth doesn't provide direct access to actual RAM. Memory access
is instead simuated with an array, with each cell in the array holding
a single value.

The array is initially set to hold 64K cells. Each cell may hold a
single value (PMC, integer, float, Parrot String) so this is generally
sufficient.

=item Extended Constants

The C<constant> word associates the following word with the value on
the stack, regardless of its type. C<constant>s, then, can be
integers, Parrot strings, floats, or PMCs provided by external code.

=item Forth Strings

The forth standard only mandates that strings, as used in counted
string things, can hold up to 255 characters. 

=back

=head2 Words that differ from ANS forth

=head2 Extra Parrot words

The following conventions are in effect

C<v> is a stack value

C<n> is a number

C<s> is a parrot string


=over 4

=item p"

This word puts a parrot string on the stack. Parrot strings take up a
single stack cell.

=item ireg (v n -- )

Puts the integer value of V into the register indicated by N.

Note that since this allows direct manipulation of Parrot's registers
it can be dangerous to forth at runtime, as forth makes use of
parrot's registers as it runs. Generally it's wise to stay in the
range 0-15, which are the registers used in parrot's calling conventions.

=item preg (v n -- )

Puts the PMC V into the register indicated by N.

Note that since this allows direct manipulation of Parrot's registers
it can be dangerous to forth at runtime, as forth makes use of
parrot's registers as it runs. Generally it's wise to stay in the
range 0-15, which are the registers used in parrot's calling conventions.

=item nreg (v n -- )

Puts the float value of V into the register indicated by N.

Note that since this allows direct manipulation of Parrot's registers
it can be dangerous to forth at runtime, as forth makes use of
parrot's registers as it runs. Generally it's wise to stay in the
range 0-15, which are the registers used in parrot's calling conventions.

=item sreg (v n -- )

Puts the string value of V into the register indicated by N.

Note that since this allows direct manipulation of Parrot's registers
it can be dangerous to forth at runtime, as forth makes use of
parrot's registers as it runs. Generally it's wise to stay in the
range 0-15, which are the registers used in parrot's calling conventions.

=item invoke ( -- )

Call a Parrot sub. Registers had better be in the correct setup, or
things are likely to die a horrible death.

=item findglobal ( s -- p )

Takes the parrot string S and looks it up in the global table, putting
the corresponding PMC for the symbol on the top of the stack.

=item loadpasm ( s -- )

Load and run the assembly file S. Useful for loading in libraries of
subroutines or interfaces.

=item loadpir ( s -- )

Load and run the PIR file S. Useful for loading in libraries of
subroutines or interfaces.

=item resultP ( -- v )

Take the value in register P5 and put it on the top of the stack

=item resultI ( -- v )

Take the value in register I5 and put it on the top of the stack

=item resultS ( -- v )

Take the value in register S5 and put it on the top of the stack

=item resultN ( -- v )

Take the value in register N5 and put it on the top of the stack

=item s2p ( c-addr u -- s )

Take the cell address and count off the stack and construct a Parrot
ASCII string from it, putting that string on the stack

=item p2s ( s -- c-addr u )

Take the parrot string off the stack and turn it into a Forth counted
string, putting the cell address of the resulting data and the length
on the stack.

=item substr (s n1 n2 -- s )

Extract a substring from parrot string S, from offset N1 for N2
characters, and put the resulting parrot string back on the stack.

=item concat (s s -- s )

Concatenate the two strings on top of the stack and create a new
string, putting the new string on the stack.

=item getparams ( -- v*x n v*x n v*x n v*x n )

Unpack the parameters, as passed in via parrot's calling conventions,
from registers to the Forth stack. The results will be the parameters
topped by a count for each set of parameter types. The registers will
be taken in numeric, string, integer, and PMC order. (So the top word
on the stack is the number of PMC parameters passed)

=item decode-by-sig ( s -- v*x n )

Take the signature S, a parrot string with the function signature, and
pull the parameters out of the registers based on that signature,
properly handling the potential for the parameters to come in without
prototyping. The top word on the stack is the parameter count.

=item export ( xt s -- )

Export execution token XT as name S, in the global parrot namespace. S
should be a parrot string, and fully qualified. This word will be
called with registers set as per Parrot's calling conventions, so
should decode the registers as need be to get its parameters in a
Forth-like state.

=back

=head1 CREDITS

Original Implementation: Jeff Goff

Vicious and Brutal extending: Dan Sugalski