Dragon Forth manual

CONTENTS

Introduction.

"Don't panic" /Tom Zimmer/

Dragon Forth (DF) is a powerful tool for creating applications for Palm OS of any complexity. The name "Forth" means fully compatibility with ANS 94 standard.

The Forth consists of:

It has got two states - compiling and interpreting. From that point of view Forth does not need a distinguish between run-time and design-time.

Development process can be described as

Forth has not got procedures or functions with strong type casting in 'a la pascal' style. But it has got rather more - freedom to control stacks of your PC. Of course you know that all of the computer languages compile a code uses the data stack to transfer parameters to subrountines and return stack to keep addresses to return. Usually a compiler controls parameters, but not in Forth.

Here is an example of addition 2 and 2:

2 2 + .

That means that 2 then another 2 will be pushed onto the data stack. Then command + will leave the result 4.

Or 5 2 - . will give 3.

To determine new subrountines a word ':' is used and ';' to close the definition. For example:

: addTwoAndTwo 2 2 + . ;

The dot after + prints a number from the top of the data stack (4 here).

There are many of superb user's guides devoted to Forth in the internet. For details please see "Online resources" section.

Advantages

This is fast 32bit FORTH system having the following features:

This system is ready for 100% palm development process, you can write your programs anywhere only with help of your palm device.

Now you can think only about your task, we are making all the rest.

Installation

Please install a file dfcons.prc onto your palm to start working with DF.
Then install lib\memoDb.pdb file. It contains all of DF libraries and sources of samples.
Note: previous information in memoPad will be overwritten!

Quick start

DF can keep its source codes in memos or Palm doc databases.

An ability to include memos is built in DF, to include Palm Doc use a library doc.txt (compressed Docs are supported).

Lets review 'Hello' sample.

A Palm OS Forth project consist of source code and resources contain GUI description of your Palm program.

To compile 'hello' sample create new memo, copy there source code from hello.txt file. Then load into your palm .prc file with resources from the sample: hwrsrc.prc.

Now type in DF:

s" hello" included

Or just "hello"

DF will compile some code and launch it without creating independent executable module. For details see "Creating prc files" section.

Description of the core

DF uses an indirect threaded code. It was written in Pila (Palm OS assembler) and SP-Forth. There are 4 segments in the system:

Each of them can be up to 63 kb.

You can remove namespace from the resulting prc, or can use it for dynamic binding.

All of the addresses used is a dataspace relative, 32-bit but not absolute. Palm OS api uses absolute addresses. To convert use words >abs and >rel.

DF uses automatic and efficient type casting when calls Palm OS api functions. But you can use a word systrap anyway.

DF console catches hardware exceptions not to reset often when error occures, very useful for debugging.

32-bit registers used:

A2 - data stack pointer
A3 - instruction pointer
A6 - threaded segment pointer
A7 - return stack pointer
D7 - top of data stack (tos)

For example operation DUP is the only asm instruction: move.l d7, -(a2)

Development process

1. Write your code in memoPad or in any Doc reader/writer. Edit resources in Pilrc+Pila or in "Onboard rsrc edit" http://www.individeo.net
2. Include your source code in the Forth system (you can use console version of DF)
3. Correct errors
4. Go to #1. If the program is ready go to #5
5. If DF was registered, then compile your program with special version of compiler
6. Sell your product

Creating independent PRC files

First, write this program in ANS forth.

Lets for example consider fclock sample.

: go
\ your forth code
;

' go to PilotMain

\ write cfa of go into VECT variable PilotMain.
\ at startup the system will call PilotMain, it means that
\ 'go' will be called at startup

s" fclock" 'abcd' build

\ create prc database with name 'fclock' CreatorID - 'abcd' and
\ DB type - 'appl'

Then we should include resource DB to copy icons, bmps, forms, other
resources to fclock application

lets do it:

'rsrc' 'dima' use-resource

\ open resource DB with CreatorID 'dima' and DB type 'rsrc'
\ Note: we must prepare this DB either in RsrcEdit or in Pilrc+Pila

lets copy resources needed:

'tFRM' 1000 CopyRes
'MBAR' 1000 CopyRes
'tSTR' 1000 CopyRes
'Talt' 1000 CopyRes
'tAIB' 1000 CopyRes
'tAIB' 1001 CopyRes

Thats all. Now we can launch our fclock:

s" fclock" launch

Processing launch codes

See lcodes.txt library and alarm sample.

Steps to create handler of launch codes (not normal launch)

  1. Write your code. You must not use global data - variables, pad, here, s" and so on. But you can use local variables, api's calls, constants, cs". It is Palm OS limitation, not DF.
  2. Set up your handler by word: SetupLCHandler ( cfa -- )
  3. Create prc application
  4. When you reset or change time, your 'cfa' will be called!

And launch_code will for reset be equal 5 for example.
I recommend you to test your code carefully before setting up LC handler!

 

Using of local variables

To use local variables include library "locals".
Local variables (locals) are living while the word is running.
Their names are available only while compiling this word.
You can use any combination of digits and symbols as a name of local variable.

There are two types of locals:
- initialized by values from the data stack
- uninitialized (initialized by zero)

Locals before '\' is initialized by values from the data stack.
Initial value of locals after symbol '\' is zero!

for example:

: test { a b \ c d -- }
\ here variables a and b will be taken from data stack,
\ c and d will be zero
;


Each local variable represents 32-bit number on the return stack.
You may ask: Can I use R@ >R R> DO LOOP with locals?
Definitely yes!
The following definition is quite correct:

: test { \ n }
5 to n
3 0
do n . loop
;


Words for managing locals:

to ( x "name" -- ) - put value x into local variable "name"
at ( "name" -- addr ) - get address of local variable "name"
{ ( "ccc" -- ) - begin definition of local variables

simple example:

: test { foo1 foo2 \ foo3 -- }
foo1 .
foo2 .
foo3 .
at foo3 .
;
1 2 test

Using dynamic strings 'a la perl' (str library)

Lets start from the sample (type it in console):

: test
s" hello from test word"
;

" hi,
world,
{test}
" stype

Hey, what have happend!?
You see that word 'test' was executed and result of it was inserted
in the string! Cool!
You see that you can enter multi-line strings! Cool again!
Yet another sample:

" 5+5={5 5 +}" stype

You can see that '5 5 +' was executed again and result (as a number!)
was inserted in the string. That is, you can insert a number or a string,
str.txt is able to distinguish these two cases.

Sequence between { and } will be executed.
You can use in the string as many {} as you want.
Each string is zero-terminated.

To insert symbol " - use {''}
To insert carriage return - use {crlf}

There are 4 special cases:
{n} - insert into the string value from the top of stack,
ex: 10 " 5+5={n}" stype
{s} - insert into the string 'c-addr u' as string from the top of stack
ex: s" dima" "-={s}=-" stype
{i} - insert DO LOOP cycle index into the string
{j} - insert outer DO LOOP cycle index into the string
{s' ccc'} - is applied when you need to paste string constant.
( you can make the same with {s})

Words for managing strings:

"" ( -- str ) - create blank string
str+ ( c-addr u str -- ) - add 'c-addr u' as string to str
s+ ( str1 str2 -- ) - add str1 to str2
strfree ( str ) - dispose string
str@ ( str -- addr u ) - get usual 'c-addr u' from the string
stype ( str -- ) - type string

Mind, that str.txt uses vocabulary for searching.
It contains "+names on" at the end. It means that vocabulary
will be included in the resulting prc file.

If you use strings but don't use run-time search - disable vocabulary by
"+names off"

note: these strings are dynamic - they are created in the heap.
And you are supposed to release them by strfree.

btw: What will be happend when in {} will be undefined word like: " {xxxzasd}"?
answer: try it as an exercise :)

Online resources