ForthMinus

From OpenSimulator

Revision as of 10:35, 22 January 2008 by Alondria (Talk | contribs)

Jump to: navigation, search

Contents

Description

ForthMinus is an alternative scripting engine for OpenSim. It's dialect resembles (loosely) the FORTHprogramming language and it's code runs within a Virtual Machine (VM). It's primary purpose was to test the feasibility of implementing a VM to handle the micro-threading of scripts as well as speed up the development of llFunctions for the main LSL script engine. It currently has some advantages and disadvantages versus the primary script engine (DotNetEngine):

Advantages:

  • Micro-threading - User scripts cannot lock up the Engine's threads. Perpetual loops can be created without fear of the engine becoming unresponsive.
  • State Saving - A ForthMinus script can be state saved thus allowing for script persistence through sim resets.
  • Security - All scripts are ran under the VM opposed to being compiled into CIL and ran in parallel to OpenSim (although AppDomain implements some security measures).

Disadvantages

  • 100% NOT LSL compatible - It does not resemble LSL/C/C# at all.
  • Slower - Since code is executed interpretively, scripts are quite a bit slower than compiled CIL is.

Using ForthMinus

To enable ForthMinus, you need to change the script_engine line within OpenSim.ini to:

script_engine = OpenSim.Region.ScriptEngine.ForthMinus

Language Syntax

Definitions

  • Word - A function or subroutine. These can be user defined, or build in (via libraries).
  • Data Stack - The main repository for data the script will manipulate
  • Execution Stack - The list of commands to process
  • Dictionary - The dictionary holds the user defined words
  • Variables - Variables can store data - however variables are much slower to utilize than the Data Stack.

ForthMinus is a simple language with no explicit grammar. Everything is executed in a postfix (or RPN) method, where the arguments for an operator come before the operator itself. For example, take this simple LSL script of a math problem:

default
{
     state_entry()
     { 
         llSay(0,(string)((30 + 5) / 5));
     }
}

In ForthMinus, the functionaly similar code would be:

30 5 + 5 / 0 llsay
Exec. Stack Data Stack Description
30 5 + 5 / 0 llsay Initial state of program
5 + 5 / 0 llsay 30 Pushes the 30 to the top of the data stack
+ 5 / 0 llsay 30 5 Pushes the 5 to the top of the data stack
5 / 0 llsay 35 The word "+" adds the top two items on the stack and pushes the result (35)
/ 0 llsay 35 5 Pushes the 5 to the top of the data stack
0 llsay 7 The word "/" divides the second to top item by the top item in the data stack, and pushes the result
llsay 7 0 Pushes the 0 to the top of the data stack
llsay says the second top item of the data stack on the channel of the top item.

Another example is a familiar script:

default
{
     state_entry()
     {
          llSay(0,"Hello Avatar!");
     }

     touch_start(integer num)
     {
          llSay(0,"Touched!");
     }
}

Would be this in ForthMinus:

: @touched "Touched!" 0 llsay ;
"Hello Avatar!" 0 llsay


Libraries

LibCore

Word marked with "*" are primarily for testing purposes for sim owners and not end users.

Word Stack Description
dup ( n -- n n ) Duplicates the top item of the stack
. * ( n -- ) Prints the top item of the stack in console
dump * ( -- ) Dumps the VM's current status in console
swap ( n1 n2 -- n2 n1) Swaps the order of the top two items in the stack
savestate * ( n -- ) Saves the VM's state to file n.fmo
words * ( -- ) Lists the primitive words loaded to console
loadlib ( n -- ) Loads the words in n.dll
 : [;] Special Define a user word. The first word following the : in the estack is the name. All words following until ; is the definition of the word
savestack ( ... n -- ) Pops the entire stack into variable n
loadstack ( n -- ... ) Push's the stack saved in variable n
clearstack ( ... -- ) Clears the entire stack
if,[else],then ( n -- ) If n is true, execute words until else or then. If n is false, execute else to then
not ( n -- n ) If n is true, push false, if n is false, push true
> ( n1 n2 -- n ) If n1 > n2, push true else push false
< ( n1 n2 -- n) If n1 < n2, push true else push false
>= ( n1 n2 -- n ) If n1 >= n2, push true else push false
<= ( n1 n2 -- n) If n1 <= n2, push true else push false
= ( n1 n2 -- n ) If n1 == n2, push true else push false
 != ( n1 n2 -- n ) If n1 != n2, push true else push false (technically pushes "= not" to estack)
 ! ( n1 n2 -- ) Saves n1 to variable n2
@ ( n -- n ) Pushes variable n to stack

LibMath

Word Stack Description
+ ( n1 n2 -- n ) Adds n1 and n2 together. If n1 or n2 are strings, result will be a combined string
- ( n1 n2 -- n) Pushes n1 - n2
* ( n1 n2 -- n) Pushes n1 * n2
/ ( n1 n2 -- n ) Pushes n1 / n2
round ( n -- n ) Rounds n to nearest integer
sin ( n -- n ) Pushes the sin of n
cos ( n -- n ) Pushes the cos of n
tan ( n -- n ) Pushes the tan of n
pi ( -- n ) Pushes PI
abs ( n -- n ) Pushes the absolute value of n
sqrt ( n -- n) Pushes the square root of n
pow ( n1 n2 -- n) Pushes n1 to the n2'th power
floor ( n -- n ) Floors n and pushes it
vecmag ( x y z -- n) Pushes the vecmag of vector <x, y, z>
vecnorm ( x y z -- x y z ) Pushes the normalized vector for <x, y, z>
vecdist ( x1 y1 z1 x2 y2 z2 -- n ) Pushes the distance between <x1, y1, z1> and <x2, y2, z2>
Personal tools
General
About This Wiki