==============================
   Thune Scripting System
==============================


.. sectnum::
.. contents::


Overview
========

Thune is an experimental interpreted language mixing ideas from Forth
and Rebol.

Language features include:

   * Stack based evaluator.
   * Garbage collected datatype system with prototype based objects.
   * Written in C to work well as an embedded scripting language.
   * Small (but not tiny) binary & run-time enviroment.


.. Evaluation
   ----------
   Thune uses postfix notation


Scripts
=======

Comments
--------

Single line comments begin with a semi-colon.

Block comments are the same as C block comments.  They begin with '``/*``' and
continue through '``*/``'.  Unlike C, block comments can be nested.

Comment examples:

::

   ; line comment

   2 4 add  ; result is 6

   /*
     Block comment
   */


Data Stack
==========

Thune has a data stack which may be manipulated with many typical Forth
operations.  However, the stack stores 16-byte cells, similar to Rebol
values, rather than register sized words.


Datatypes
=========

===========  ==========
Datatype     Examples
===========  ==========
unset!
none!        none
datatype!    logic! int!/decimal!
logic!       true false
word!        hello big-time .s
lit-word!    'hello 'big-time '.s
set-word!    :hello :big-time :.s
get-word!    hello: big-time: .s:
block!       []  [a b c]
paren!       ()  (a b c)
array!       #[1 2 3]
function!    [2 add] proc :inc2
call!       
int!         1 455 -22
decimal!     3.05  -4.
coord!       0,255,100  -1, 0, 0 
vec3!        0.0,255.0,100.0  -1.0, 0, 0 
char!        'a' '^-'
string!      "hello"  {hello}
binary!      #{01afed}  #{00 33 ff a0}
select!      obj/x my-block/2
set-select!  :obj/x :my-block/2
slice!
context!
===========  ==========


Strings
-------

Multi-line strings are contained within curly braces.

String examples:

::

   "alpha"

   {This string
   spans multiple lines.}


Slice
-----

A range within a binary!, string!, or block! can be represented with a slice.

::

    "Hello world" :s
    slice! s make .                  ; "Hello world"
    slice! s next dup 4 skip make .  ; "ello"

To move the start of the slice use *prev* & *next*, as with a series.
To move the end of the slice use *slice.prev* & *slice.next*.


Array
-----

Arrays hold a series of 32-bit numbers using less memory than a block!.

All numbers in an array are either integers or floating point values.  If
any number is specified as a decimal!, all numbers will be floating point.


Coord
-----

Integer coordinate that is handy for specifying screen coordinates, colors,
IP-4 network address and such.

A coord! can hold up to 6 16-bit integers.

::

   640,480       ; screen coordinate
   255,10,0      ; rgb triplet
   192,168,0,1   ; IP-4 network address


Vec3
----

Vec3 stores 3 floating point values.


Functions
---------

Functions can be defined in two ways: as procedures or as functions.

Procedures are simply blocks of code which can be evaluated.  Any number of
values may be removed from or pushed onto the stack by a procedure.

::

    ; Here is a procedure
    ["Hello World" print] proc :hello

Functions are blocks of code bound to local arguments and variables, and may
return either one value or no value.
Function arguments are taken from the stack and local variables are
initialized to 'none.  These local values are declared in a signature block.
Functions cannot access values on the stack placed there before the function
was invoked.
When a function reaches the end or returns, the top stack value (if any
has been put there) will be copied to the stack position at the top before
the function call (minus any arguments).

::

    ; Here is a function with two arguments and one local variable.
    [arg1 arg2 | var1 -- ret]
    [
        ; arg1 & arg2 hold what were the top two items on the stack.
        ; var1 is none.

        ; TODO: Write this function body.
    ] func :my-function

Function argument types can be limited by following the argument name with
a datatype in the signature block.

::

    [blk block!  count int!/decimal! -- "Argument type example"]
    [
        ; ...
    ]
    func


Contexts
--------

::

    context! [
      "John"  :name
      44      :age
      'farmer :job
    ] make :my-object
    

.. The Evaluator
   Contexts & Binding


Defined Words
=============


The following abbreviations are used:

============  ===================
Abbreviation  Meaning
============  ===================
TOS           Top of data stack
EOL           End of line
============  ===================



Data Stack
----------

=======  =================  =================
Word     Stack Usage        Function
=======  =================  =================
.        (val -- )          Remove value on top of stack and print it.
.s       ()                 Show values on stack.
dup      (a -- a a)         Duplicate value on top of stack.
dup2     (a b -- a b a b)   Duplicate top 2 values.
drop     (a -- )            Remove value on top of stack.
swap     (a b -- b a)       Switch the two values on the top of stack.
over     (a b -- a b a)     Copy second item on stack to the top of the stack.
nip      (a b -- b)         Remove second value on stack.
tuck     (a b -- b a b)     Copy top value under second value.
rot      (a b c -- b c a)   Rotate third value to top.
rot.r    (a b c -- c a b)   Rotate top of stack to third position.
=======  =================  =================


Flow Control
------------

========  =========================  ============================
Word      Stack Usage                Function
========  =========================  ============================
ift       (logic -- )                Evaluate next value if true.
iff       (logic -- )                Evaluate next value if false.
if/C      (val val -- )              Evaluate next value if comparison is true.
if/keep   (val -- [val])             Evaluate next value if true, else drop.
either    (logic t-val f-val -- )    Evaluate either t-val or f-val.
forever   (block -- )                Evaluate block until exception thrown.
iter      (ser body -- )             Iterate over series.
iter/N    (ser body -- )             Iterate over series with skip.
proc      (body -- )                 Create procedure.
func      (sig body -- )             Create function with local values.
return    ()                         Leave function.
recurse   ()                         Start function from beginning.
do        (a -- )                    Evaluate.
select    (data options -- match)    Choose option which matches data.
case      (data options -- )         Evaluate option which matches data.
throw     (val -- val)               Throw exception.
try       (body catch -- )           Try body and catch exception.
break     ( -- 'break)               Break from forever & iter.
error     (message -- error)         Throw error.
verify    (a type -- a)              Throw error if datatype does not match.
verify/N  (a1-aN t1-tN -- a1-aN)     Throw error if datatypes do not match.
========  =========================  ============================


Flow Helpers
~~~~~~~~~~~~

========  =========================  ============================
Word      Stack Usage                Function
========  =========================  ============================
each      (ser body -- )             Iterate over series and take first element.
each.set  (ser words body -- )       Iterate over series and assign elements.
while     (body cond -- )            Evaluate body while cond is true.
loop      (block n -- )              Repeat block **n** times.
loop.to   (block n limit -- )        Repeat block **n** to **limit** times.
proc.env  (env body -- proc)         Create procedure with private context.
func.env  (env sig body -- func)     Create function with private context.
========  =========================  ============================


Data Manipulation
-----------------

==========  ========================  =================
Word        Stack Usage               Function
==========  ========================  =================
make        (type proto [p2] -- val)  Create value.
as          (val type -- val)         View value as a similar type.
type?       (val -- type)             Replace value with datatype of value.
type?.word  (val -- word)             Replace value with datatype word.
is-type?    (val type -- logic)       True if value is of specified type.
set         (val word -- )            Assign value to word.
set         (val word ctx -- )        Add word to context.
get         (word -- val)             Retrieve value referenced by word.
get         (word ctx -- val)         Retrieve value from context.
bind        (block ctx -- block)      Bind block to context.
infuse      (block ctx -- block)      Replace words with context values.
lift-local  (block -- block)          Rebind words to copy of local context.
reduce      (val -- rval)             Replace with evaluated values.
copy        (a -- r)                  Copy value.
copy.part   (ser limit -- r)          Copy part of a series.
mark.eol    (block -- block)          Set EOL flag for current cell.
parse       (data rules -- pos)       Parse string or block.
==========  ========================  =================


Data Helpers
~~~~~~~~~~~~

==========  ========================  =================
Word        Stack Usage               Function
==========  ========================  =================
context     (def -- context)          Create context.
parse.some  (data rules -- )          Parse string or block.
==========  ========================  =================


Series
------

==========  ======================  =================
Word        Stack Usage             Function
==========  ======================  =================
append      (ser val -- ser)        Append value to series.
append.cat  (ser val -- ser)        Join value to series.
insert      (ser val -- ser)        Insert value to series.
remove      (ser -- ser)            Remove value at current series position.
clear       (ser -- ser)            Remove all elements.
head        (ser -- ser)            Move position to series start.
tail        (ser -- ser)            Move position just past series end.
head?       (ser -- logic)          True if series is at the start.
tail?       (ser -- logic)          True if series is past the end.
index?      (ser -- int)            Position in series.
length?     (ser -- int)            Length of series.
prev        (ser -- ser)            Decrement start of series.
next        (ser -- ser)            Increment start of series.
skip        (ser n -- ser)          Increment start of series by **n**.
slice.prev  (slice -- slice)        Decrement end of slice.
slice.next  (slice -- slice)        Increment end of slice.
pick        (ser index -- val)      Fetch an element from a series.
poke        (ser val index -- ser)  Set an element of a series.
first       (ser -- val)            Fetch first value in series.
second      (ser -- val)            Fetch second value in series.
third       (ser -- val)            Fetch third value in series.
last        (ser -- val)            Fetch last value in series.
find        (ser pat -- ser)        Find pattern in series.
find.last   (ser pat -- ser)        Find pattern in series starting from end.
match       (ser pat -- ser)        Move position to end of pattern.
trim        (str -- str)            Remove whitespace from start and end.
==========  ======================  =================


Series Helpers
~~~~~~~~~~~~~~

==========  ======================  =================
Word        Stack Usage             Function
==========  ======================  =================
empty?      (ser -- logic)          Same as tail?.
map         (ser comb -- )          Transform each element of a series.
split-path  (full -- path file)     Split full path into path & file.
dirize      (str -- str)            Ensure trailing slash is present.
==========  ======================  =================


Math
----

===========  =================  =================
Word         Stack Usage        Function
===========  =================  =================
inc          (num -- num)       Increment int!
dec          (num -- num)       Decrement int!
add          (a b -- sum)       a + b
sub          (a b -- diff)      a - b
mul          (a b -- product)   a * b
div          (a b -- quotient)  a / b
and          (a b -- int)       a & b
or           (a b -- int)       a | b
xor          (a b -- int)       a ^ b
abs          (n -- abs)         Absolute value
negate       (n -- n)
complement   (val -- val)
to-rad       (deg -- rad)       Convert degrees to radians.
to-deg       (rad -- deg)       Convert radians to degrees.
sin          (n -- r)           Sine
cos          (n -- r)           Cosine
tan          (n -- r)           Tangent
arcsin       (n -- r)           Arcsine
arccos       (n -- r)           Arccosine
arctan       (n -- r)           Arctangent
sqrt         (n -- r)           Square root
random       (max -- n)         Generate random number.
random       (n 'seed -- )      Seed random number generator.
===========  =================  =================


Vector Math
~~~~~~~~~~~

These functions operate on vec3!/coord!.

===========  ======================  ======================
Word         Stack Usage             Function
===========  ======================  ======================
dot          (v1 v2 -- dot)          Vector dot product.
cross        (v1 v2 -- cross)        Vector cross product.
normalize    (vec -- vec)            Make vec3 unit length.
===========  ======================  ======================


Math Helpers
~~~~~~~~~~~~

==========  ========================  =================
Word        Stack Usage               Function
==========  ========================  =================
limit       (n min max -- n)          Limit number to a range.
==========  ========================  =================


Input/Output
------------

===========  ======================  ======================
Word         Stack Usage             Function
===========  ======================  ======================
read         (file -- data)          Read file.
read         (file part -- data)     Read beginning of file.
write        (port data -- port)     Write data to port.
load         (file -- code)          Read script from file.
delete       (file -- )              Remove file.
rename       (file new -- )          Rename file.
print        (val -- )               Print reduced value to console.
prin         (val -- )               Print reduced value to console (no eol).
prin.pack    (val -- )               Print reduced value without spaces.
console.out  (str -- )               Print to console (stdout).
open         (url [opt] -- port)     Open port.
close        (port -- )              Close port.
seek         (port pos -- port)      Set port stream position.
getenv       (name -- var)           Get environment variable.
system.run   (cmd -- status)         Execute program.
to-hex       (int -- int)            Flag integer to display in hexadecimal.
to-dec       (int -- int)            Flag integer to display in decimal.
checksum     (bin type -- digest)    Compute 'crc16 or 'sha1 checksum.
===========  ======================  ======================


Pre-defined Helpers
-------------------

==========  ===========================
Word        Definition
==========  ===========================
yes, on     true
no, off     false
eol         '^/'
pi          3.14159265358979323846
==========  ===========================

