Gokutm 1.3 Functions Summary

Goku was a Forth like language first implemented on the 6502 Mircro processor and then ported to the 8086/88 family of Intel processors.

For source, see Goku source. These are a few small programs written in it:

Everything packaged together here: GokuLinux-132.tgz

Goku Core Words

Most of these functions are implemented in native Assembly of the host CPU, some are linked to functions in standard C-language libraries of the underlying operating system and are marked with an asterisk *.
 
+, -, *, / basic 32bit arithmetik functions
% modulo function
|, & bit combination
<<,>> bit shift
# starts a comment to the end of the current line
: noop (no operation) used as seperator in 'module:symbol'
<, <=, <>, =, >, >= comparison functions
! store prefix
@ fetch prefix
[,] index operators (really: 'noop' and '+')
and logical and
accept get input from the console * (based on fgets() for 'stdin')
atoi translate an ascii number to binary 
atof translate an ascii number to floating point (not implemented)
break break loop, flow directive (only compiled)
call call a function at an address
catch save execution address and CPU stack ptr
callLib call a function in a shared library *
clear clear the Goku data stack
compare compare strings
close close a file handle * (based on close())
compile compile Goku source code
concat concat two strings
continue continue loop, flow directive (only compiled)
copy copy strings
create create a Goku word
date translates seconds since 1/1/1970 in to a date/time string
dec decrement value at address
depth get depth of data stack
disp display an integer number
do do loop flow directive (only compiled)
drop drop top of  data stack
dup double top of data stack
else program flow directive (only compiled)
emit emit a character
end close a program flow (only compiled)
eval evaluate/interprete a Goku source string
exit exit the Goku interpreter
fill fill memory
find find a string in another string
free free memory
getb, getc, getw getu, getl get a char, byte, word long frorm address
htoi translate an ascii  hex string to binary
if flow directive (only compiled)
inc increment value at address
init reinitialize Goku startup parameters
itoa translate a binary integer to ascii
length calculate length of string
local declare local variables
loadLib load a shared library *
loadFunc get function pointer froma shared library *
lookup lookup a Goku word in a dictionary
malloc allocate memory from the heap * (based on  calloc(1, n))
max find the maximum of two integers
memcopy copy memory
min find the minimum of two integers
not logical not
or logical or
open open a file * (based on open())
putb, putc, putw, putl write a byte, char, word, long to an address
quit quit Goku
recurse reentry the current function (only compiled)
read read from a file * (based on read())
return return from the current function (only compiled)
sourcePtr get the current source ptr from evaluator/interpreter
seek position in a file * (based on  seek())
stack get a value from the data stack
sysvar get address from system parameters
system execute a shell command
swap swap to values on the data stack
then flow directive (only compiled)
time return elapsed time in milli seconds
token get token from a string
throw jump to saved address restore CPU stack ptr
type type a string of one or more chars on the console
updatePtr update the Goku source ptr in the evaluator/interpreter
while flow directive (only compiled)
write write to a file * (based on write())

Goku Core Definitions

Five of the core words are created using other Goku words. array, define, module, record and variable are called 'compiling' words because they compile the source coming after them until a semicolon is encountered. allocArgs and freeArgs are used when parsing source code when defining new compiling words. load is used to load/evaluate Goku source from files.

All five are frequently used when writing Goku programs. The source for these words can be found in init.goku wich is automatically loaded on startup from /usr/lib/goku/init.goku. This essential file is also reprinted at the end of this manual.
 
 

array character array memory pointer
define compile a Goku word
module declares a different name/module space
record declares a data structure
variable create a word as a variable


 Goku 1.2 Core Reference and Glossary

Goku uses a stack for passing parameters between functions.  The contents of the stack before and after the execution of the function is shown in the title of the function after its name.

Most of the examples are interactive, so they can be typed in to the Goku console command line and executed. In all examples the '>' sign is the Goku console prompt followed by the user input.

The functions 'disp', 'type' and 'showStack' are frequently used in the examples to show the top number on the stack, to type the top string on the stack or to show the whole stack contents. While 'disp' and 'type' are Goku core words the function 'showStack' is defined in the file INIT.GOKU, which is loaded by Goku automatically on startup.
 

Glossary

is a value of '1' for 'true', or '0' for 'false'. Any value which is not '0' will be taken as 'true' in a 'boolean' context. refers to the Goku data stack, which is used to pass parameters between functions. are used interchangable when talking about executable Goku words. Other Goku words are variables or memory pointers. denote a 32 bit integer in Goku strings must end with a binary '0' (zero, like strings in the 'C' language. Strings are represented as their 32 bit memory address is a 32 bit address


+, -, *, /    ( value1 value2 -- result )

The two values on top of the stack ared adde, subtracted, multiplied or divided and the result is left on top of the stack.

Example:


%            (dividend divisor -- quotient rest)

The modulo function returns the quotient and rest of an integer division.

Example:


 |, &            (value1 value2 -- result)

'|' performs a bitwise 'or' while '&' performs a bitwise 'and' between the two values. The result is returned on top of the data stack.

Example:
 


<< , >>        (value1 value2 - result)

The integer in value1 is bit shifted by the number of bits in valu2 and left on the data stack as the result.

Example:


#               starts a comment

all text after the colon ':' is ignored by Goku and taken as a comment.

Example:
 


:                separates module and variable name

used when referring to a word in an other then the current module. The colon ':' is a noop (no operation) operator similar to the leftbracket '[' and has only a visual purpose. See also module.

<, <=, <>, =, >, >=            (value1 value2 -- boolean)

The top two values on the data stack are compared and the boolean result left on the stack. If the comparison is true this value is '1' if the comparison yields false this value is '0'.

Example:


 !        (value  -- )

The '!' stores a value in a variable and clears the value from the data stack. The variable is previously declared using the 'variable' function. '!' is a quicker and shorter form of 'putl' which achieves the same effect. '!' store is frequently used together with fetch '@', which is a shortcut for 'getl'.

Example:


@        ( -- value )

Fetches a value from a variable and puts it on the data stack. The variable has been previously declared using the 'variable' function. '@' is a quicker and shorter from for 'getl' which could achive the same effect.

Example:
 


[,]        index operators

The index operators [,] can be used to index memory pointers or variables. '[' is really a 'no' operator, which does not perform anything and ']' works just like a '+'.

Example:
 


and    ( boolean1 boolean2 -- boolean)

The values in 'boolean1' and 'boolean2' are combined using a logical 'and' and the result is placed on top of the stack. Values of '0' are take as a logical 'false', values other than '0' are taken as a logical true. The result is always a '0' for false or a '1' for true.

Example:
 


accept    ( -- address )

Accepts user input in the console windows until the enter key is pressed. The enterd line is stored at the address left on the data stack. Note, that Goku uses each time the same internal buffer for input from accept. The maximum length of this buffer is specified at memory location system[20] as a long (32 bit) value. The address of the buffer can be found ain system[72]. This buffer is also used by Goku for formatting error messages.

Example:
 


array

Array declares a byte array by creatng a new Goku word and allocating a sepcified amount of memory for it. 'array' is created using other Goku functions, specifically 'create' and 'malloc'. See the file INIT.GOKU for the exact definition. Note the semicolon at the end of the declaration.

Example:

The variable myVector contains now a memory address pointing to 4 bytes of allocated space. The new array variable can be indexed using [], the index operators. The new allocated memory area can be accessed using getb, gec, getw and getl for reading or putb, putw and pul for writing.
  The first for bytes of 'myVector' will now contain the number 12345 in little endian order (lowest byte contains least significant part).

Note, that variables declared with

Seee also the other declarative compiling words 'define', 'variable' and 'load'.


atoi    ( string -- integer)

Parses a string for an intgere and returns the value on the stack.

Example:
 


atof    (atring -- float)

Not implemented in this version


break

Breaks out of a 'while do' loop. Continues executing after the 'end' statement of the 'while do' loop. Note, that 'break' can only be used in compiled functions, it will not work interactively on the command line.

Example:


call    ( address -- ???)

Calls a Goku function specified by its address. Normally a Goku function is called or executed just by entering it's name, but soemtimes it is necessary to refer to a function by it's address, e.g. if the function address is passed as aparameter to another function.

Example:
 

The function timeIt will execute 'fibo' with an argument of 25 and display the time elapsed since it's start. On a Pentium 200Mhz a value of about 30 seconds will be displayed.

catch    ( address -- )

This function saves the execution address of the next instruction and the CPU stack pointer at the address found on the data stack. 8 bytes are nneded to save both values. The values saved with 'catch' can subsequently be used to by 'throw' to force execution to back to the point after the catch statement. 'catch' and 'throw' work similar to 'setjump' and longjump' in the 'C' language.

Example:

The example will continue to type "hello " in the console window.Select File/reset from the console window menu to stop. 'catch' and 'throw' are useful for error handling or other situations where the program has to jump to a previous higher calling level of execution without going through a chain of functions returns. In this case the routine doing the 'throw' could leave a value on the data stack which can be tested after the 'catch' (e.g. an error value).


clear    ( --- )

 This word clears the Goku data stack. This may be useful for error recovery to get a defined state of the data stack.


compare    (address1 address2 -- result)

Compares to strings. If both strings are qeual the result is '0' (zero). If the first string is earlier in the sort order the result will be positive, if later than negative.

Example:
 


compile ( sourceAddress -- codeAddress newSrcAddress)

Compiles the Goku source code and leaves the address of the code and the address where 'compile' stopped in the source code on the data stack.

'compile' finishes when the string finishes (a '0' zero is encountered) or when compile finds a semicolon, which is not part of a 'local' statement. 'compile' automatically allocates space for the new compiled code using 'malloc'.

Example:
 

'compile' is mostly used to define other compiling words. The Goku words 'array', 'define' and 'variable' have all been created using 'compile' and another important Goku word in this context, named 'create'.

See the file INIT.GOKU for the source code for all of them. The example shows the creation of 'define' the most used Goku compiling word to compile new Goku user functions.


concat    ( destAddress sourceAddress -- destAddress )

The string in surce address gets appended to the string in destination address, the address of the destination string is returned on the data stack

Example

> array dest 100;        # allocate space for destination string
> dest "this " concat
> "is very " concat
> "useful" concat type
this is very useful
>

continue

Can only be used inside a 'while' loop, 'continue' jumps to the beginning of the loop.

Example:


copy    (toAddress fromAddress  -- toAddress)

Copies from dromAddress charcaters to toAddress until and including atrailing 0 character in from Address. Leaves the toAddress on the stack.

Example:

array buff 20;
buff "hi there" copy type
Hi there
>

create    (nameAddress type -- contentAddress)

'create' is one of the most important Goku core functions, as it permits the creation of new words in user dictionary. The three predefined words 'define', 'variable'  and 'array' all use 'create' in there body procedures.

Each word in a Goku dictionary has a type and a contents field. There are three types which can be created by the user:
 
 

Type No Description Contents field
0 normal variable integer/address
1 pointer variable address of memory area
2 code address of code
The type field defines the purpose of the word and the contents of the contents field.

Type 0 variables contain a 32bit integer normally reprensenting a number in their contents field. When executing a type 0 word the address of this contents field is put on the stack, (not the contents of it). Words created with 'variable' are of type 0.

Type 1 variables have an address of a memory area in their contents field. When executing a type 1 variable Goku puts the contents of the contents field on to the data stack, which is the address of a memory area. Words created with 'array' are of type 1.

Type 2 variables have an address of a executable piece of code in their contents field. When executing a type 2 variable Goku will execute the code found at that address. Type 2 vraibles are created using 'define'.

There are three other types used internaly: 3 for inline code, -1 for copiled words like 'break', 'if', while etc., and -2 to indicate the start of the core dictionary (used by 'lookup'). See the chapter 'Inside Goku' for a more detailed diskussion od these word types.

Example:

'create' is almost exclusevely used when creating compiling words such as 'define', 'variable' or 'array'. See  the source of INIT.GOKU for more examples on how to use 'create'.


date    ( seconds -- dateString )

Translates number of seconds to a date string starting with 0 at  Jan 1st, 1970  midnight (GMT).

example:

>    0 date type        # executed in California USA, this is 0:00 AM in Greenwich UK 1/1/19970
Wed Dec 31 16:00:00 1969

> 0x7FFFFFFF date type    # rollover date in California USA
Mon Jan 18 19:14:17 2038
 



dec    (valueAddress -- )

Decrements the value found at valueAddress.

Example:

 
variable x;
123 !x
x dec
@x disp
> 122


depth    ( -- depthOfStack )

Calculates the number of values on the Goku data stack and returns that value on the stack.

Example:
 


 disp    ( value -- )dsplayes

Displays the top value on the data stack in the console window.

Example:
 


do

Used in a 'while .. do ..end 'expression. The 'do' part of a loop opos the top value of the data stack and tests it for 0 (zero). In case the value is zero execution continues after the 'end', else the body of the loop is executed.

Example:


drop    ( value -- )

Drops the top value off the data stack, decreases the depth of the data stack by one.

Example:


dup    ( value -- value value )

Duplicxates the tp value on the data stack, increases the depth of the stack by one.

Example:


else

Used in 'if .. then .. else .. end' expression. After evaluating the part between 'if' and 'then' the top of the stack is dropped and tested for 0 (zero). In case of 0 execution continues after the 'else' word, in case of non 0 (zero) execution continues after the 'then' word and then skips after the 'end' word.

Example:


emit ( asciiValue -- )

Takes a value from the top of the data stack and displays it's ASCII representaion in the console window.

Example:

> 65 emit
A
>


Note, that not all values between 0 and 255 are havae a sceen representation depending on the character set used.


end

Used in 'while ... do ... end', 'if ... then .. end' and 'if ... then ... else ... end' expressions. The 'end' words marks the end of a looping of conditional expression. See 'while' and 'if' for examples.

eval     ( stringAddress -- ??? )

Interpretes Goku source code in a string pointed to a memory address on top of the data stack. 'eval' is used internally for interpreting the command line, but can also be used in a program.

Example:

In this example 'eval' is actually used in a nested fashion, because the command line itself is already evaluated by eval. For each nesting level of 'eval' the current Goku source pointer is pushed on an internal stack and can be queried by 'sourcePtr' or updated by 'updatePtr' (see 'compile' and 'define' )

exit

The 'exit' word exists the current evaluation loop. 'exit' is useful in a Goku source file for ending execution (evaluation) of a  file when loading it.


fill    (address byte length -- address )

Fills a memory area with a byte value for certain length.

Example:

Not that the area in 'buff' is declared one byte longer then used during 'fill'. The last byte in buff, which will contain a 0 (zero) from 'malloc' stops 'type' from running into undefined memory.

find    ( keyAddr stringAddr -- positionAddr)

Finds a key string in another string and returns the found address, or -1 if not found, on top of the data stack.
 
 

 free    (memoryPtr -- )

Frees memory previously allocated with malloc.

Example:

> variable memPtr;        # alocate variable
> 1000 malloc !memPtr  # allocate memory and store address in memPtr
......
> @memPtr free            # retrieve address and free memory
The variable 'memPtr' gets created to hold the address for the allocated memory.  When the memory is not used anymore, it should be freed.


getb, getc, getu, getw, getl    ( address -- value )

getb        reads an unsigned 8 bit byte at address
getc        reads a signed 8bit byte at address
getu        reads an unsigned 16 bit word at address
getw       reads a signed 16bit word at address
getl         reads a signed 32bit long at address

Example:

> variable x;
> 222 !x
> x getb disp
-34
> x getc disp
222
>
The example shows the difference between 'getc' and 'getb'. While 'getb' interpretes the byte read as a signed 8bit  integer, 'getc' returns an unsigned integer.

Note, that '!' used in the example works just like 'putl' but executes faster and is faster to write too. Note also, that when using 'getl' with a variable '@' is the better choice as a complement to '!' it executes faster.

Example:

> variable x;
> 123 !x
> x getl disp       # slower
123
> @x disp           # faster
123

htoi    (address -- integer)

Translates a hexadecimal string to an integer. Integers up to 16 hex digits (32 bit) can be converted.

Example:

> "FF" htoi disp
255
>

if

This flow directive can only be used in a compiled context, i.e.: functions defined using 'define'. There are two forms:
if ... then ..end
and
if ... then ... else ... end
The 'then' part pops the top of the data stack and checks it for zero (0). In case of 0, instructions after then are skipped and executuin continues after the 'end' of the 'else' part.

Example:

> define check if 10 < then "small" type end;
> 5 check
small
> 20 check
>
> define checkit if 10 < then "small" type else "big" type end;
> 10 chekit
big
>


inc ( valueAddress -- )

Increment the value found at valueAddress.


Example:
 

variable x;
123 !x
x inc
@x disp
> 124


init

Initializes the Goku data areas and restarts. 'init' is noamally used inside the Goku initialization file INIT.GOKU. No statements should  occur before 'init' except for statements changing system parameters using the 'system' variable pointer. 'init' reallocates the Goku data stack and other internal data areas like input buffer, compiler scratch areas and so forth. See also INIT.GOKU.

 

itoa    ( integer stringAddress -- stringAddress )

This function takes an integer and a pointer to a string area to put the number converted in to a string.

Example:

> array number 16;

> 1234567 number itoa type
1234567
>

length

Calculates the length of a zero terminated string.

Example:

> "hello" length disp
5
> array aString 20;
> aString "Goku" concat length disp
4
>

local

Declares static local variables in compiled Goku source.

Example:

define account
    local balance;
    if dup "deposit" compare 0 = then
        drop @balance + !balance
        return
    end
    if "show" compare 0 = then
        @balance disp
        return
    end;
> "show" account
0
> 123 "deposit" account
> "show" account
123
> 100 "deposit" account
> "show" account
223
>
Locals in Goku are static variables which hold there values between invocations of the defined function. During compilation the values of locals are initialized to 0 (zero).


lookup    ( stringAddress -- dictionaryAddress )

Looks up a word in the user and base dictionary and returns the address of the dictionary entry. 'lookup' starts searching the user dictionary first, then the base dictionary. Both dictionaries are searched from the last to the first entry. If a word exists twice in the user dictionary, because it was defined twice, then 'lookup' will return the entry of the word which was defined last.

'lookup' is mainly used internally by the Goku compiler when parsing source code and has no obvious usage in normal Goku source code.

See the chapter "Inside Goku" for a description of the format for a word entry in a dictionary.


malloc    ( nOfBytes -- address )

Used to allocate memory. A 32 bit pointer is returned on the data stack. 'malloc' calls memory allocation routine of the underlying operating system. Note, that under MS Win32 there are only 65k of allocations are possible. When memory allocated with 'malloc' is no longer used, it can be freed using 'free'.

Example:

> variable memPtr;
> 100 malloc !memPtr;      # allocate 100 bytes and store the addres in memPtr
> @memPtr 'Z' 20 fill type # fill the first 20 bytes with 'Z's and type
ZZZZZZZZZZZZZZZZZZZZ
Often it is more paractical to reserve memory using special memory pointer variables using 'array'
> array memPtr 100;
> memPtr 'Z' 20 fill type
ZZZZZZZZZZZZZZZZZZZZ
'array' creates a pointer variable, which places a memory pointer on the stack when evaluated. Array variables are also easily indexed using '[ ]'. (See array )


max ( value1 value2 -- maxValue )

Finds the bigger of the two values value1 and value2 and puts the result on the stack.

Example:
 

> 3 7 max disp
7
>



memcopy ( fromAddress toAddress nBytes -- toAddress)

Copies bytes from one to another memory address and leaves the address copied to, on the data stack.

Example:

Note, that a trailing zero is supplied when copying to limit the 'type'.



min (value1 value2 - minValue)

Finds the smaller of the two values value1 and value2 and puts the result on the stack.

Example:
 

> 3 7 min disp
3
>



not (value -- logicalValue)

Reverses the value on top of the stack to its logical reverse. All values which are non zero are reversed to zero, all values which are zero are reversed to 1.

Example:

> 123 not disp
0
> 0 not disp
1
>

or (value1 value2 -- logicalValue)

Calculates the logical 'or' from the top two values on the stack. If one or both values differ from zero, the result is 1, else the result is 0.


example:

1 0 or disp
1
<
3 4 or disp
1
>
0 0 or disp
0
>



putb, putw, putl (value address -- )

putb     writes a signed 8 bit value to address
putw    writes a signed 16 bit number to address
putl      writes a signed 32 bit value to address

A value gets written to an address. The byte order for 'putw' and 'put' depends on the underlying hardware. If the value given takes up more bytes then they are to be written, the value gets truncated.

Example:

variable x;
> 255 x putb
> x getb disp
-1
> x getc disp
255
> 0x12340000 x putw
> x getw disp
0
>

quit ( -- )

Quits Goku, returns control to the calling OS.


recurse

Reenters the current function. 'recurse' can only be used in a compiled context. If local variables have to be conserved, they have to be pushed on the stack.

Example:
 

define fibo
    dup
    if 3 < then
        drop 1
    else
        dup 1 - recurse
        swap 2 - recurse
        +
    end;
> 25 fibo disp
75025


The fibonacci algorithm 'fibo' is defined in the file 'std.goku'.


return

Returns from a compiled function.

sourcePtr ( -- sourceCodePtr)

Gets the pointer to the source of the current evaluation level. This function is useful when compiling functions, which do itself compile. The retrieval of the sourcePtr lets a Goku word look 'forward' into the source code stream to evaluate/interprete. This make tghe definition of words possible, which look forward into the source code. Normal Goku words can only act on values/pointers on the stack.

See examples for compile, create and see definitions of variable, array and define in the file 'init.goku'


stack ( position -- value )

Gets a value from a certain stack position and copies it on top of the stack. This function is useful to retrieve values from the stack in a random deliberate fashion.

Example:

> 1 2 3 4 5
> 1 stack disp
5
> 2 stack disp
4
> 5 stack disp
1
>

system ( commandString -- returnValue )

Executes a shell command in 'commandString'.

Example:
 

> "ls -l" system
This will show a directory listing on a UNIX  system.


sysvar ( -- systemAreaPtr)

Puts a pointer to the system area on the stack. Using indices e.g.: 'system[104]' for the version no., system parameters can be retrieved and sometimes changed, to tune Goku for specific purposes. See the file 'init.goku' for a list of readable and writable system locations.

Note, that locations in the system area might change in different versions of Goku.


swap (value1 value2 -- value2 value1)

Swaps the top two value on the stack.

Example:
 

> 10 20 showStack

10 20
> swap showStack

20 10
>


'showStack' is defined in the file 'std.goku'.


then

'then' is a flow control word, which can only be used in a compiled context. See if for an example.


 

time ( -- Seconds)

Puts the time elapsed since system start in thousands of a second on top of the stack.

Example:

> time 1000 / 60 / disp
72
>
The system was started 72 minutes ago.

token ( sourcePtr -- newSourcePtr tokenPtr tokenType)

Parses a source string into tokens. 'token' calls the same routine Goku uses internally to, parse source code. White space and the special characters (  )  [  ]  :  ; are used to break up the source string into tokens. The function puts returns one token at the token address 'tokenPtr'. The token address can also be retrieved in the system[] area. The maximum token size which defaults to 1024 can be configured using a system[] - parameter. One of the following token types is returned:
 
 
description value example
null token 0 end of source
identifier token 1 var1, age, x, y10, phone_no
string token 2 "hello world\n", "\41\42\43"
floating point token 3 1.234, 0.3, -5.95
integer token 4 4765, -987
hexadecimal token 5 0xFF00, 0x3c2d, 0xffffffff
character token  6 'a', 'B', 'C'

Example:

> array source 20;
> source "hello 123" copy
> source token
> disp
1
> type
hello
< type
123
'token' is mostly used in compiling words like define, variable or array to parse source code.


throw ( jumpBufferAddress -- )

Jumps to a previous place in the Golku program saved using the 'catch' function.  See catch for an example.

type ( address -- )

Prints a zero terminated string at address to the the console window or standard out.

Example:

> "hello" type
hello
>

updatePtr (newSourceAddress -- )

Updates the source pointer for enclosing interpreter/evaulation loop. 'updatePtr' is used in compiling Goku words, like define, variable or array. See the file 'std.goku' to see use of 'updatePtr' in defining these words.

while

This flow  directive which can only be used in a compiled context. 'while' is used in the following form:

while ... do ... end

The part between 'while' and 'do' contains code defining the condition under which the part between 'do' and 'end' should be executed. When Goku excutes 'do' it pops and checks the top of the stack. In case of a logical 'true' (any value not zero) the part between 'do' and 'end' gets executed. In case of a logical 'false' (zero) value, Goku skips the 'do' - 'end' part and continues execution after the 'end' part.

Example:
 

define loop
   local x;
   10 !x
   while @x do
       @x disp "," type
       x dec
   end;
> loop
10,9,8,7,6,5,4,3,2,1
>


copyright (c) Lutz Mueller, 1999. All rights reserved.