01-31-2005 23:24
[***** TO FORUM MOD, THIS SCRIPT IS 13 SEPERATE SUBSCRIPTS, THUS WON'T FIT UNDER ONE POST. I WILL POST THE FOLLOW AS A MESSAGE ON THE THREAD, IF THAT WORKS*****]
Okay, I was bored one day and decided to try something "different" and write a programming language in LSL. While not the first one (SL Lisp was the first), it is (to my knowledge) the first programming language written in LSL that can do more than basic math (although it can do that also). It is modelled after the Forth programming language, although I had to take some liberties in changing some of it's commands (for example, memory mapping would be too slow in LSL, so I cheated an created a string variable type).
It does feature logic (if/else/then, <, >, =, <>, etc) as well as a basic loop (do [blahblah] loop). It allows defining new words - ': test .( Hello World! ) ;'. The language is extendable in that one could also add new core words in LSL and add it to it's dictionary. It also features an exec function, which allows it to execute a hunk of code stored in a string. :)

First I'll post the list of primitive words it understands:

CODE

CORE WORDS INPLEMENTED:
. ( N -- , print number on top of stack )
.( ( -- , Prints what is between '.(' and terminated by ')' )
.s ( -- , Prints the stack depth and the stack )
+! ( -- , Prepends a string to a var )
! ( -- , Stores a string into a variable EX: $( foo ) $foo ! )
!+ ( -- , Appends a string to a var )
$( ( -- , Notates a string, terminated by ')' )
@ ( -- , Prints the value of a string Ex: $foo @ )
: ( -- , Used to define following word as what follows ended by ; )
; ( -- , Used to terminate a word definition )
+ ( n1 n2 -- result , Adds n1 to n2 and pushes the result )
* ( n1 n2 -- result , Multiplies n1 to n2 and pushes the result )
/ ( n1 n2 -- quotient , Divides n1 by n2 leaving the quotient )
?dup ( n -- n n | 0 , duplicate only if non-zero, '|' means OR )
- ( n1 n2 -- result, Subtracks n2 from n1 and pushes the result )
> ( n1 n2 -- -1|0 , If n1 is larger than n2, push true (-1) else false (0) )
< ( n1 n2 -- -1|0 , If n1 is smaller than n2 push true else false )
= ( n1 n2 -- -1|0 , If n1 is equal to n2 push true else false )
0= ( n -- -1|0 , If n equals 0, push true else false )
0< ( n -- -1|0 , if n is less than 0 push true else false )
1+ ( n -- n+1 , Adds 1 to the top of stack and pushes result )
1- ( n -- n-1 , Subtracts 1 from the top of stack and pushes result )
2drop ( a b -- , remove pair )
2dup ( a b -- a b a b , duplicate pair )
2over ( a b c d -- a b c d a b , leapfrog pair )
2swap ( a b c d -- c d a b , swap pairs )
abs ( n -- abs(n) , absolute value of n )
and ( x1 x2 -- x3 , logical bit operator )
debug ( n -- , n switch turns debuger on or off )
depth ( -- n , Pushes the size of the stack )
dic ( n -- , Changes to dictionary n )
do ( n -- , Does what is between 'do' and 'loop' n times )
drop ( a -- , remove item from the stack )
dup ( n -- n n , DUPlicate top of stack )
dumpdict ( -- , Dumps the definitions in the current dictionary)
else ( -- , Does what is between 'else' and 'then' if previous 'if' was false )
emit ( n -- , Displays ASCII character n )
empty ( ... -- , Empties the stack )
exec ( -- , Dumps a string to the run stack )
fd ( n -- , Moves object n units forward )
getpos ( -- x y z , Pushes the position of the object, in movement units )
gettime ( -- n , Pushes the runing time into the stack )
gox ( n -- , move n movement units on the x axis )
goy ( n -- , move n movement units on the y axis )
goz ( n -- , move n movement units on the z axis )
grab ( INTERNAL USE ONLY )
if ( n -- , Does what is between 'if' and 'else' or 'then' if n is true )
loop ( -- , Used to terminate a do )
max ( n1 n2 -- n1|n2 , pushes the larger between n1 and n2 )
min ( n1 n2 -- n1|n2 , pushes the smaller between n1 and n2 )
ms ( n -- , Sleeps for n ms )
mod ( n1 n2 -- remainder , Divides n1 by n2 and leaves the remainder )
movescale ( n -- , Sets the movement units scale )
negate ( n -- -n , negate value, faster then -1 * )
nip ( a b -- b , remove second item from stack )
onattact ( -- , Attaches a word to the attach event )
onrez ( -- , Attaches a word to the rez event )
ontouch ( -- , Attachss a word to the touch event )
over ( a b -- a b a , copy second item on stack )
pick ( xu ... x0 u -- xu ... x0 xu ) Copy xu to top of stack
pop ( INTERNAL USE ONLY )
push ( INTERNAL USE ONLY )
random ( n -- [0 - n] , random number from 0 to n )
reset ( -- , Resets the engine )
roll ( xu ... x0 u -- xu-1 ... x0 xu ) Rotate xu to top of stack
rot ( a b c -- b c a , ROTate third item to top )
rotx ( n -- , Rotates n degrees along the x axis )
roty ( n -- , Rotates n degrees along the y axis )
rotz ( n -- , Rotates n degrees along the z axis )
rt ( n -- , Rotates object n degrees on he z axis )
setcolor ( r g b -- , Sets color of object where number is 0 (none) to 100 (full))
swap ( a b -- b a , swap top two items on stack )
then ( -- , Used to terminate an if ... else ... then clause )


Below is a few example words/programs:

CODE

: hello .( Hello world! ) ; ( -- ) Hello world example
: shape dup 360 swap / swap do 2dup rt fd loop 2drop ; ( n1 n2 -- ) Draw a shape with n2 sides and n1 units length per side.
: tosscoin 1 random if .( Heads ) else .( Tales ) then ; ( -- ) Flips a coin
: lt negative rt ; ( n -- ) Turn n degrees to the left
: bk negative fd ; ( n -- ) Move n units forward
: true -1 ; ( -- n ) Push true
: false 0 ; ( -- n ) Push false


One uses the engine by saying the code to process, prepended by 4th. (For example:
CODE

4th 1 1 + .

will cause the engine to add 1 and 1 and then print the result.

Following is the code for the engine....