PDA

View Full Version : SageScript features



JamusPsi
05-12-2009, 12:17 PM
With the new server out of the way, work on SageScript has resumed. I am now much, much closer to a release.

In fact, the prototype of it ended up in the last update to PsiNet because I wasn't thinking, and so you're all running the new (broken, functionless) scripting engine.

As has been mentioned before, SageScript is being built on top of a generic scripting engine library called Stogie. Stogie is a language I've created to be kind of a mutant hybrid of lua, javascript, P-erl, and wizard script (BASIC).

(Why does posting the word "pearl" without an a crash the boards with an error message?)

The idea is that it should run most wizard/sf scripts just fine- but that it can do much, much, much more.

Here are a list of basic features of the language. Please submit feedback or questions!

Variables
The system supports an unlimited number of variables. Variables are referenced with $, and interpolated (used) with %. For instance:

$b = banana

Will set the $b variable to be "banana". You can then:

echo %b

The basic way to remember this is that $b is the variable, and %b is the value.

Variables support references.

$c = $b
$d = %b
echo %c //Echos banana
$c = "candy"
echo %b //Echos candy- $b and $c are the same variable now.
echo %d //Echos banana - $d was set to the VALUE of b, not the reference

Tables
Variables can be tables.

$a = []
$a.fruit = "banana"
$a.animal = "monkey"

echo %a.animal eats the %a.fruit
or
echo %a[animal] eats the %a["fruit"]

Tables can be arbitrarily nested.

$a = []
$a.b =[]
$a.b.c = []
$a.b.c.d = "doggy"
echo %a.b.c.d

Control structures
The language supports a small subset of control structures.

if(%a > 10) {
echo %a
}

if(%a > 10) echo %a

if() {
} else {
}

if() {
} else if() {
} else if() {
} else {
}

for($a = 0; %a < 10; $a = %a + 1) {
echo %a
}

while(%a < 10) {
$a = %a + 1
echo %a
}

break and continue work for loop control as you would expect.

Note that formatting for these control structures is somewhat rigid with respect to newlines and bracket position- this is because the language is mostly interpreted, and newlines are syntactically relevant (I didn't want you to have to end Echo lines with ;)

Evaluation
Simple evaluations can be made. They are made automatically in conditions and assignments, but otherwise must be invoked with the =() syntax.

$a = 1
$b = 3
echo a + b = =(%a + %b)

Operators must be whitespace padded (similar to JSE, again a restriction of how I designed the parser). It supports strings, integers, and decimals, with the following operators:

==, !=, <, <=, >, >=,
*, /, %, +, -
&& ||

It does not support the ?: operator, but you can emulate it using && ||

(a ? b : c) is equivalent to (a && b || c).

Functions
Functions can be defined in a script.

function foo(a, b) {
echo The %a is eating the %b.
}

foo(monkey, banana)
foo(cat, "mouse")

function squared(a) {
return =(%a * %a)
}

Functions can return variable references.

function animal(name, food) {
$result = []
$result.species = %name
$result.food = %food
return $result
}

$monkey = animal("monkey", "banana")
echo %monkey.food

Function nesting

Within a script, functions can be nested. A function can 'see' functions which are direct children, siblings, or parents. (Similar to class scopes in other languages.) This allows a function to define a private function for itself without conflicting with a similarly-named function elsewhere.

Function references
Functions can have a reference taken to them, and these can be passed like anything else.

$func = &animal
$monkey = $func("monkey", "banana")

this in functions
When a function is called as a member of a table, it automatically gets a $this variable.


function animal(species, food) {
$result = []
$result.name=%species
$result.food=%food
$result.eat = &feed

function eat() {
echo %this.name is eating the %this.food
}
}

$ele = animal("elephant", "peanuts")
$ele.eat()

Functions as classes
class is a synonym for function, with the extra ability to be called with the new() function.

$monkey = new(animal, monkey, banana)

This is syntactic sugar, except that new is used to create other objects as well.

Script importing
Within one script, you can import the top-level functions of another script using the IMPORT directive. The function in which the import line occurs can then 'see' all the top-level functions of another script, and call them as normal. This allows scripts to be modulized without the overhead of starting and stopping new script tasks and setting up synchronization between them- you simply call a function in another script.

The IMPORT directive cannot use variables and must use a static filename. However, the import() function can use a variable filename and returns a table with the functions in it, so variable imports are possible.

Live files
Scripts are periodically checked for file timestamp. If the file has been changed since it was loaded, it will reload it, and merge the new code into the currently executing script.

Example:

while(true) {
pause 3
foo()
}

function foo() {
echo "Hello"
}

If you change this script, while it is running, to echo "Goodbye", then the next time foo() is called, it will use the new method. All method references are automatically updated as well.

This should allow a modulized script to have its modules changed without having to restart the whole setup.

Saving and loading data
The saveobject() and loadobject() functions allow you to save a variable to an xml file, and reload them later. Some variables cannot be saved- method references, for example, cannot be saved (as they would have no context when reloaded later). These references will simply disappear, and you'll have to reinsert them yourself.

Events/exceptions
Your script supports try/catch (but not finally). catch catches events/errors. If an error event is thrown but not caught, the script terminates. Plain old events are ignored. Most events are sent automatically, but you can register your own as well, such as:

$onwhisperhook = new(hook, "whispered", regex, "/^(\w+) whispers, /")
$onwhisperhook.enable()

try {
godosomething()
} catch($e, whispered) {
echo %e.captures[0] whispered to you!
exit
}

Special Objects
Note: While the base code of stogie to enable this feature is done, the specific psinet-related functions have NOT. As such, the actual interface is not solid.

The most powerful feature of Stogie is its ability to hook into native C# code. A C# object can publish fields and functions which are exposed to Stogie and can be called like any others can.

For instance, a C# atlasroom object could be queried, then goto() called on it, or the title of that room gotten. This is also how your scripts can access character information- %me.stats[agi], %me[skills[armor use]], %me.mana, %me.maxhealth, etc. If PsiNet can track it, your scripts can use it.

You may also be able to communicate privately between characters- by creating an event, giving it data, changing it to xml, and sending it to another character more or less invisibly- it won't show in your chat window if you don't want it to.

Bhuryn
05-12-2009, 12:25 PM
Special Objects
Note: While the base code of stogie to enable this feature is done, the specific psinet-related functions have NOT. As such, the actual interface is not solid.

The most powerful feature of Stogie is its ability to hook into native C# code. A C# object can publish fields and functions which are exposed to Stogie and can be called like any others can.

For instance, a C# atlasroom object could be queried, then goto() called on it, or the title of that room gotten. This is also how your scripts can access character information- %me.stats[agi], %me[skills[armor use]], %me.mana, %me.maxhealth, etc. If PsiNet can track it, your scripts can use it.

You may also be able to communicate privately between characters- by creating an event, giving it data, changing it to xml, and sending it to another character more or less invisibly- it won't show in your chat window if you don't want it to.

Not sure I am understanding you clearly. Are you saying I can create a c# class in visual studio and instantiate it in stogie, pass information into it, etc.?

JamusPsi
05-12-2009, 12:31 PM
Not sure I am understanding you clearly. Are you saying I can create a c# class in visual studio and instantiate it in stogie, pass information into it, etc.?

Maybe. I haven't decided if I'll allow dll imports.

Stogie supports it, which is exactly how PsiNet will interface with it. If someone were to use Stogie in another application, they would be able to do that. (Stogie will likely be made public as a separate project.)

It's more to note that Stogie can interface with PsiNet almost natively, accessing functions and fields exactly as they are.

Bhuryn
05-12-2009, 01:12 PM
Maybe. I haven't decided if I'll allow dll imports.

Stogie supports it, which is exactly how PsiNet will interface with it. If someone were to use Stogie in another application, they would be able to do that. (Stogie will likely be made public as a separate project.)

It's more to note that Stogie can interface with PsiNet almost natively, accessing functions and fields exactly as they are.

Ah, alright. For what it's worth, and as much fun as I'd have with it, it seems like a dangerous thing to put in some people's hands =).

Xaerve
05-12-2009, 01:18 PM
Really exciting stuff!

Renian
05-12-2009, 01:23 PM
If I could write a C# class and import it into SageScript, that would be awesome.

That said, are you still going to set it up so it won't be able to send system commands? Will we be able to set up scripts to play sounds during various events despite that?