SGScript - description
This is a programming language that is made to be fast, accessible and simple.
ctrl.DReset();
foreach( at, item : speech )
{
distfromlast = speech.size - at - 1;
a = 0.9 * pow( 0.7, distfromlast );
ctrl.DCol( 0.9, a );
ctrl.DText( item.text,
x + padding, y + padding + lineheight / 2,
HALIGN_LEFT, VALIGN_CENTER );
y += lineheight;
}
It is similar to many but the exact combination makes it unique in comparison to others. Thus, it might be best to describe it in comparison to others, especially the ones that heavily influenced the development of SGScript.
It adds dynamic typing and built-in serialization to C. Unlike Lua, it has C-like syntax and proper 0-based indexing and advanced object model, and much more versatile error handling. It has the consistency you'd want after working with PHP, and is considerably more lightweight. It untangles some of the mess JavaScript has introduced, and gives coroutines for a considerable boost in power of expression. And, unlike Python, SGScript won't care as much about formatting.
You can find more about the differences at the "Why SGScript?" page.
The language supports:
if/else
, while
, for
, do/while
, foreach
- 10 variable types: null, bool, int, real, string, function, C function, object, pointer, thread
- Multi-level break/continue
- Multiple return values
- First-class functions and ability to attach variables to functions (creating closures)
- Coroutines (with threading & sync primitives)
The standard library includes:
- array, dict, map
- math, string, I/O, O/S and formatting functions
eval
, file import, DLL import, coroutines
- coroutines/threads, events, sync/race
Why SGScript?
Native serialization
[+] SGScript, Python
[-] JavaScript, Lua, Squirrel
Without any extra work, most of the data can be converted to a byte buffer so that it could be stored in a file or sent over a network and later converted back again. Languages that don't have it will require extra effort to get it and make sure it works with all kinds of custom objects. How much extra effort? Well, try googling for "lua serialize userdata". I didn't find a single way. SGScript - easy: https://github.com/snake5/sgscript/blob/6e9349a5a1ef5210ee440301b889f9afd78291be/ext/sgsxgmath.c#L248
Reference counted memory management support
[+] SGScript, Python, Squirrel
[-] JavaScript, Lua
This is a preferred method to garbage collection since it releases resources as soon as possible, avoiding random stalls throughout the game and thus providing a smooth gameplay experience. There are algorithms that reduce these stalls (incremental/generational garbage collection) but, given enough objects, they will be noticeable again. Source: http://sealedabstract.com/rants/why-mobile-web-apps-are-slow/
Coroutines
[+] SGScript, Lua, Squirrel, Python
[-] JavaScript (only generators are supported)
True cooperative multitasking allows the direction of timed events to be greatly simplified. SGScript goes one step further and also provides helper constructs (thread, subthread, sync, race) to make things as simple as possible for the user.
Custom native objects with complex links
[+] SGScript, Python, JavaScript (partial support)
[-] Lua, Squirrel
These are objects that can be created in C/C++, with special interfaces that support operator overloading, serialization, debug printing, conversions, cloning, type name and iterator retrieval, index and property retrieval. If not used, this feature has no cost, however it helps greatly with defining fast and accessible interfaces by encapsulating native resource management and access. To see what SGScript objects are all about, check the previous GitHub link, there's quite a lot of them.
Native arrays
[+] SGScript, Python, Squirrel, JavaScript (partial support)
[-] Lua
Native arrays (not to be confused with arrays that contain native data types, that is a subset of these) offer increased performance and memory-friendly storage over arrays made from hash tables. Array stores size as uint32, capacity as uint32 and values (16 bytes + extended data in SGScript) x size. A table would store all the same + keys (16 bytes + extended data) + hash array (size may differ but it's generally another array with size, capacity and a list of hash and index values). When arrays are considered, less (memory usage) is more (capacity).
Map support (all non-string/number keys)
[+] SGScript, Python, JavaScript (requires the support of an extension)
[-] Lua, Squirrel (some types are not supported in both)
The ability to map any variable to any other variable provides extended metadata storage possibilities - it can be stored without modifying the original variable.
m = map();
m[ sprite_obj ] = { high = 5 };
Game math library
[+] SGScript, Python, Lua, JavaScript
[-] Squirrel
A library with vector/matrix objects and functions for games. Not having to rewrite at least the bindings for it saves a lot of time.
Native debugging/profiling facilities
[+] SGScript, Python, JavaScript (support differs between JS engines)
[-] Lua, Squirrel
Introspective debugging and time/memory usage profiling can help resolve various issues found. SGScript supports call stack time, instruction time and call stack memory usage profilers out-of-the-box. At any point, all data can be dumped via the built-in output facilities that can be rerouted to any file or parser.
They are written in C to ensure a practically minimal performance impact while profiling. Significantly less than if the profiler was written in Lua, which is the main solution there.
There's also access to some stats in SGScript so it is easy to see, for example, how many new allocations were done each frame.
Advanced native function argument parsing facilities.
[+] SGScript, Python
[-] Lua, Squirrel, JavaScript
Every modern scripting engine should have a function that parses and validates function arguments according to a specification and puts the data in the specified locations. With bigger functions it saves you from writing a lot of boilerplate code.
SGScript:
SGSFN( "fmt_string_parser" );
if( !sgs_LoadArgs( C, "?m|ii", &off, &bufsize ) ) // in case of type mismatch, emits a warning
return 0; // ... and returns here to continue execution
float x =luaL_checknumber(L,1); // in case of type mismatch, emits a fatal error, cannot continue script execution after this function call
float y =luaL_checknumber(L,2); // same here
const char* str=luaL_checkstring(L,3); // same here
Non-fatal error messaging facilities without exceptions
[+] SGScript
[-] Python, Lua, Squirrel, JavaScript
This feature allows you to try and continue execution after a failed function call or intercept the error for debugging with the option of continuing later anyway. This is useful when code is published and there's a necessity to avoid going back to bug fixing immediately, before gathering more information about the state of the program.
Why exceptions don't fit the criteria: they force the code to break out of the original execution path, thus severely reducing the usefulness of error suppression with logging.
name = string_cut( other.name ); // warning: missing argument 2; after call, name = null
// name gets printed somewhere as 'null' or is invisible due to some other function not accepting null for a string
// everything else works
Built-in introspective pretty-printing (variable dumps)
[+] SGScript, Python, JavaScript
[-] Lua, Squirrel
This is a very useful feature to have when you need to debug data (i.e. always). Simply passing a variable to some function (for example, printvar) prints some useful information about it - the type, contents, linked resources.
Warning suppression on missing property access
[+] SGScript, Python (requires exception handling code)
[-] Lua, Squirrel, JavaScript (no warnings about it at all)
This feature allows to specify, per-read, whether the property is expected to be there or not.
a = obj.prop; // expected, emits a warning if not found
b = @obj.prop; // might not be there, no error
This also works for many other actions, like function calls and assignments.
Custom native iterators
[+] SGScript, Python
[-] JavaScript, Lua, Squirrel
An extension for custom native objects, it allows to create objects that can be foreach'ed through.
foreach( entry : io_dir( "." ) ) println( entry ); // prints the contents of current directory
Dual access dictionaries
[+] SGScript, Lua, JavaScript, Squirrel
[-] Python
The ability to access simple dictionaries just like any other object visually and syntactically reduces code complexity.
a.b = x; // simple
a["b"] = x; // not so simple
Explicit closures
[+] SGScript
[-] Lua, JavaScript, Squirrel, Python
Explicit closures (specifying which local variables to pass over to the newly defined function) make it easier to read code using closures and prevents closure-related accidents, like having a variable changed unexpectedly.
Multi-index/property-set operation without temporary tables
[+] SGScript
[-] Lua, JavaScript, Squirrel, Python
Simplifying code further without the introduction of sub-optimal memory access patterns.
SGScript:
obj.{ // object name written only once, accessed only once
a = 1, // property write
b = 2, // property write
c = 3, // property write
d = 4, // property write
};
Lua, method 1:
obj.a = 1 // property write
obj.b = 2 // property write
obj.c = 3 // property write
obj.d = 4 // property write
// object name written four times, accessed possibly four times (depending on compiler)
Lua, method 2:
for k, v in pairs({ a = 1, b = 2, c = 3, d = 4 }) do // create table, property write x4, function call, create closure
obj[ k ] = v // object access x4, property write x4
end
C-like syntax
[+] SGScript, JavaScript, Squirrel
[-] Lua, Python
With the overwhelming majority of code being written in C-like languages (http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html), having a compatible syntax helps when you need to copy code - there's simply less changes to perform.
Indices start at 0
[+] SGScript, JavaScript, Squirrel, Python
[-] Lua
Even though it is argued that 1-based indexing may help someone understand code better (which is actually hard to prove), I have a few arguments to make against it:
- Array index is generally the distance (or as programmers would rather say, offset) from first element. 1 - 1 = 0. Not a distance from 0th element that doesn't even exist. Not the first element itself because elements have no keys in arrays.
- Programming languages don't exist in a vacuum. Almost every other programming language treats indices as distances (offsets). Going against the grain makes it hard to interpret both languages at once for comparison or interface design. Whoever has to write that binding, has to keep in mind this difference for every array access made in the binding area. This is brain power not spent well.
- Similarly to previous argument, this difference makes porting code from other languages harder.
Code samples - SGScript
Statements
print "Text";
println( "!" );
b = rand();
Comments
// this is a comment that ends with the line
/* this type of comment
can be more than
one line long
*/
Basic calculations
a = 1, b = 2, c = 5;
d = a + b * c - b / a;
a += 3.14;
c = "eye" $ "sight" // stitch (concatenate) strings together!
d = "Ocean's " $ 11;
Comparison
if( c > 5 )
print "as expected";
y = x <= 8.8; // result of comparison can be assigned!
Useful shortcuts
a += 1; // short for a = a + 1
a++; // short for a += 1
a--;
a = if( b > 5, 10, 20 ); // short for if( b > 5 ){ a = 10; } else { a = 20; }
Control flow
if( a > b )
{
print "something happens only if a is greater than b";
}
else
print "...and here the opposite is true";
while( a > b )
{
print "something happens as long as a is greater than b";
a--; // but not for too long, as we see
}
// or maybe ...
do
{ // first we do
print a;
}
while( a++ < 10 ); // then we check
More useful shortcuts
for( i = 0; i < 10; i++ )
print i;
// .. is the short form for ..
i = 0;
while( i < 10 )
{
print i;
i++;
}
for(;;) // this is not going to stop...
print "x";
More control flow
x = 5;
for(;;)
{
print x;
x--;
if( x < 0 )
break; // this says that we don't want to continue staying in the loop
}
// << this is where "break" leads us, right after the loop
// this goes through a list
foreach( fruit : [ "apple", "orange", "banana" ] )
println( fruit );
// .. of 2 items ..
list = { "1" = "apple", "2" = "orange", "3" = "banana" };
foreach( number, fruit : list )
println( number $ ". " $ fruit );
Functions
// cornerstore of reusable code
function square( x )
{
return x * x;
}
print square( 5 );
function print_quoted( text )
{
print '"' $ text $ '"';
}
print_quoted( "It works!" );
Objects
a = [ 1, 2, "three" ];
a[2] = 3;
a[1]++;
d = {
name = "test",
text = "hello",
};
d.name = "test, edited";
d.text $= ", world!";
println( d.text ); // hello, world!
Interesting stuff
printvar( x ); // tells you all you want to know about "x"
// emits an error with the given message if the first argument is false
assert( x > 5, "x must be greater than 5" );
// returns the type name
typeof( x );
// universal external code loader
include "math", "string", "something";
Code samples - the C API
Primary operations
// create the context
sgs_Context* C = sgs_CreateEngine();
// load the built-in math library
sgs_LoadLib_Math( C );
// load a file
sgs_ExecFile( C, "script.sgs" );
// call a global function with 0 arguments, expecting 0 values returned
sgs_GlobalCall( C, "myFunction", 0, 0 );
// destroy the context
sgs_DestroyEngine( C );
Data in, data out
sgs_Context* C = sgs_CreateEngine();
sgs_LoadLib_Math( C );
// push a variable on the stack
sgs_PushReal( C, 3.14 );
// call a global function with 1 argument, expecting 1 value returned
sgs_GlobalCall( C, "sin", 1, 1 );
// check the returned value
printf( "returned value: %f\n", sgs_GetReal( C, -1 ) );
// clean the stack
sgs_SetStackSize( C, 0 );
Variable types
SGScript has 10 primary variable types:
null
: the 'lack of a better value' type
bool
: boolean, true/false
int
: signed integer
real
: floating point number
string
: byte buffer
(SGS) function
: function that was defined in and compiled from SGScript code
C function
: function defined in C code
object
: the extension type and container for complex built-in types
ptr
: the pointer type
thread
: the context/thread/coroutine type
Extended variable types (built on object
):
array
: a dynamically allocated variable array
dict
: a map/table structure where variables are mapped to string keys
map
: a map/table structure where variables are mapped to variable keys
class
: object that uses two other objects to build its interface
closure
: a callable object consisting of another callable and several variables
event
: an object that allows to stop a thread
Conversion rules
from \ to | bool | int | real | string | ptr |
null | false | 0 | 0.0 | "null" | NULL |
bool | - | 0/1 | 0.0/1.0 | "false"/"true" | NULL/0x1 |
int | 0 => false, otherwise true | - | - | - | cast |
real | 0.0 => false, otherwise true | round to nearest | - | sprintf %g | cast |
string | empty => false, otherwise true | *1 | *1 | - | char* |
func | true | 0 | 0.0 | "function" | NULL |
cfunc | true | 0 | 0.0 | "C function" | NULL |
object *2 | true | 0 | 0.0 | "object" | data ptr. |
ptr | NULL => false, otherwise true | cast | cast | sprintf ptr(%p) | - |
thread | true | cast | cast | sprintf thread(%p) | cast |
- "-" means the conversion is not necessary, does not affect data or the effect of conversion should be immediately obvious
- *1) see Numeric string parsing rules for more info
- *2) these are the default values, overrides can be provided in CONVERT function and type name for string
Code structure
Code can contain constants, identifiers, expressions and statements. Statements usually include expressions but expressions can also include statements, specifically - function expressions.
Constants
Available constant formats:
type | subtype | examples |
null | - | null |
bool | - | true, false |
int | decimal | 1413, -583, 0 |
int | binary | 0b0101, 0b11 |
int | octal | 0o644, 0o1, 0o77 |
int | hexadecimal | 0x1f, 0xCA5 |
real | basic | 0.14, -25.48 |
real | scientific | 1.5e-5, 1e+10 |
string | normal | "text", '1\n2' |
string | unescaped* | """text""", '''1\2''' |
*) unescaped strings don't parse their contents at all, and the ending markers (""" or ''') cannot be escaped
Identifiers
Identifiers can contain letters (a-z, A-Z), numbers (0-9) or underscores ("_") but they cannot begin with a number.
Special keywords and hardcoded constants:
name | type | usage |
this | special identifier, read-only | method context retrieval |
_G | special identifier, read/write | global environment access |
_R | special identifier, read-only | global registry access |
_F | special identifier, read-only | current function retrieval |
_T | special identifier, read-only | current thread retrieval |
null | constant | constant |
true | constant | constant |
false | constant | constant |
var | restricted keyword | variable declaration |
global | restricted keyword | variable declaration |
class | special identifier | class declaration |
new | restricted keyword | class instantiation |
thread | restricted keyword | thread control |
subthread | restricted keyword | thread control |
sync | restricted keyword | thread control |
race | restricted keyword | thread control |
defer | restricted keyword | destruction statement helper |
function | restricted keyword | function definition |
use | restricted keyword | function definition |
if | restricted keyword | "if" statement |
else | restricted keyword | "if/else" statement |
do | restricted keyword | "do/while" statement |
while | restricted keyword | "while", "do/while" statements |
for | restricted keyword | "for" statement |
foreach | restricted keyword | "foreach" statement |
break | restricted keyword | "break" statement |
continue | restricted keyword | "continue" statement |
return | restricted keyword | "return" statement |
print | function command | "print" function |
println | function command | "println" function |
yield | function command | "yield" function |
include | function command | "include" function |
Expressions
Expressions can be categorized in many different ways: type of action, appearance, whether it also assigns the value somewhere or if its purpose has a special meaning.
There are 5 types of action for expressions in SGScript: arithmetic, bitwise, logical, comparison and special.
expression | appearance | type of action | assign | # in. |
add | A + B | arithmetic | no | 2 |
subtract | A - B | arithmetic | no | 2 |
multiply | A * B | arithmetic | no | 2 |
divide | A / B | arithmetic | no | 2 |
modulo | A % B | arithmetic | no | 2 |
pre-increment | ++ A | arithmetic | self | 1 |
pre-decrement | -- A | arithmetic | self | 1 |
post-increment | A ++ | arithmetic | self | 1 |
post-decrement | A -- | arithmetic | self | 1 |
add-assign | A += B | arithmetic | yes | 2 |
subtract-assign | A -= B | arithmetic | yes | 2 |
multiply-assign | A *= B | arithmetic | yes | 2 |
divide-assign | A /= B | arithmetic | yes | 2 |
modulo-assign | A %= B | arithmetic | yes | 2 |
bitwise AND | A & B | bitwise | no | 2 |
bitwise OR | A | B | bitwise | no | 2 |
bitwise XOR | A ^ B | bitwise | no | 2 |
left shift | A << B | bitwise | no | 2 |
right shift | A >> B | bitwise | no | 2 |
bitwise AND-assign | A &= B | bitwise | yes | 2 |
bitwise OR-assign | A |= B | bitwise | yes | 2 |
bitwise XOR-assign | A ^= B | bitwise | yes | 2 |
left shift-assign | A <<= B | bitwise | yes | 2 |
right shift-assign | A >>= B | bitwise | yes | 2 |
bitwise invert | ~ A | bitwise | no | 1 |
logical AND | A && B | logical | no | 2 |
logical OR | A || B | logical | no | 2 |
first-not-null | A ?? B | logical | no | 2 |
logical AND-assign | A &&= B | logical | yes | 2 |
logical OR-assign | A ||= B | logical | yes | 2 |
first-not-null-assign | A ??= B | logical | yes | 2 |
logical invert | ! A | logical | no | 1 |
less than | A < B | comparison | no | 2 |
less than or equal | A <= B | comparison | no | 2 |
greater than | A > B | comparison | no | 2 |
greater than or equal | A >= B | comparison | no | 2 |
equal | A == B | comparison | no | 2 |
not equal | A != B | comparison | no | 2 |
strict equality | A === B | comparison | no | 2 |
strict inequality | A !== B | comparison | no | 2 |
raw comparison | A <=> B | comparison | no | 2 |
error suppression | @ A | special | no | 1 |
declare-local | var A | special | maybe | any |
declare-global | global A | special | maybe | any |
array literal | [ A, B, .. ] | special | no | any |
dict. literal | {A=1,B=2,..} | special | no | any |
map literal | map{[A]=B} | special | no | any |
assign | A = B | special | yes | 1 |
concatenate | A $ B | special | no | 2 |
concatenate-assign | A $= B | special | yes | 2 |
concatenate | A .. B | special | no | 2 |
concatenate-assign | A ..= B | special | yes | 2 |
property | A . B | special | maybe | 2 |
index | A [ B ] | special | maybe | 2 |
multi-index-assign | A[]<dict.lit> | special | yes | any |
multi-property-assign | A.<dict.lit> | special | yes | any |
function call | A ([B,..]) | special | no | <=256 |
comp. function call | O!A ([B,..]) | special | no | <=256 |
function definition | function A.. | special | maybe | 0 |
inline if | if(A,B,C) | special | no | 3(2) |
subexpression | ( A[, ..] ) | special | maybe | any |
thread-call | thread f() | special | maybe | <=256 |
subthread-call | subthread f() | special | maybe | <=256 |
new-call | new f() | special | maybe | <=256 |
Some notes on the special cases:
- [increment,decrement] pre-increment and pre-decrement operators return the modified value, post- operators - the original one
- [logical] all logical operators except 'logical invert' (which returns bool) set/return one of the two operands passed
- [equality] strict (in)equality operators are the same as their non-strict counterparts with one difference: they do type checking, for example
5 == 5.0
would return 'true' and 5 === 5.0
would return 'false'
- [declare] declarations only actually set the data if they include the assignment expression, otherwise only the type is internally noted for other references
- [declare] variables can be redeclared as long as they maintain their access level
- [property,index] whether property or index expressions set data depends if they're on the receiving (left) end of an assignment expression
- [inline if] 3 inputs are required, 2 are actually used (as if
if(A){return B;}else{return C;}
was used)
- [subexpression] subexpressions can set data if they are set up like this: <subexpression> = <function-call> - this is the way to read more than one return value from a function
- [error suppression] the
@
operator disables warnings, errors and any other messages for as long as the subexpression is executed, this is mostly useful for things like reading a property or calling a function that may not exist, in cases where that isn't an error
- [dict./map literal] 3 types of keys are supported: string, identifier (interpreted as string), variable ("[ <expression> ] = <value>")
- [function] the full function definition expression syntax:
function <name> ( <args> ) [ use ( <use-list> ) ]
, followed by either { ... }
or = ... ;
. <name>, <args> and the 'use' block are all optional.
- [multi-set] operator returns
A
, that is, the object itself
- [thread]
thread
/subthread
commands support all kinds of calls (f()
, o.f()
, o!f()
)
- [new]
new
supports only the basic calls (f()
, o.f()
), and this
is not passed (as it would refer to the newly created instance)
compatible function call / inheritance call / global method call ( O!A ([B,..])
)
CFC is created to encourage users to reduce memory usage without sacrificing clarity of code. Object and its processing function can reside in different locations (like class instance / inherited class) and still be easily accessible.
Properties:
- uses the same symbol as logical inversion operator
- usage: simplified & optimized calling of non-integrated compatible functions
- instead of
comp_func.call( object, arg1 )
(removed since 1.4) write object!comp_func( arg1 )
- instead of putting functions with data / class interfaces, requiring additional memory usage, allows to easily keep them separate
- simplify inheritance-like code models to the extent permitted by a dynamic language
Example WITHOUT:
function create_object()
{
object = { x = 0, y = 0 };
function object.move( x, y ){ this.x = x; this.y = y; @this.move_callback(); }
function object.tick( delta ){ this.move( this.x + delta, this.y ); }
return object;
}
Example WITH:
function Object_Move( x, y ){ this.x = x; this.y = y; @this.move_callback(); }
function create_object()
{
object = { x = 0, y = 0 };
function object.tick( delta ){ this!Object_Move( this.x + delta, this.y ); }
return object;
}
Now, by itself it may not mean much, however let's see what happens if the following code is used:
for( i = 0; i < 100; ++i )
objects.push( create_object() );
Without the usage of a global method, there's a key 'move' in each object that points to the function. In real software there may be no less than 10 such keys in many instances of many objects. And if there are no overrides planned for it, there's no need for it to be there but we can't really move it. Classes are an option that involves a few more allocations and it requires more memory to use them. Using .call/sys_call
or replacing this
with an argument would sacrifice readability and the option to relocate functions, as well as performance, this being a double call. This is where CFC comes in - syntax allows to clearly state the object and function used, and the required interface for the object to be compatible with said function.
Statements
There are 4 statement types in SGScript:
Container statements
There are two types of container statements: expression statements and block statements.
- Expression statements contain zero or more expressions, separated by commas (",") and ending with semicolons (";").
- Block statements contain zero or more statements.
Format:
- expression statement:
<expression>[, <expression>[, <expression> ...]] ;
- block statement:
{ [<statement>[, <statement>...]] }
Examples:
a = 5;
a = 1, b = 2;
Control flow statements
These statements decide which code gets executed when. They include loops (while, for, foreach, do/while), the if/else construct, break/continue/return.
Formats:
- if/else:
if( <expression> ) <statement> [ else <statement> ]
- while:
while( <expression> ) <statement>
- for:
for( <expression-list>; <expression-list>; <expression-list> ) <statement>
- foreach:
foreach( [<identifier>,][<identifier>] : <expression> ) <statement>
- do/while:
do <statement> while( <expression> )
- break:
break <N>;
- continue:
continue <N>;
- return:
return <expression-list>;
- defer:
defer <statement>
Examples:
if( a )
{
print( "a is true" );
}
else
print( "a is not true" );
while( b > 0 ) b--;
defer
is a special case since it moves the given statement to the end of the block (however that is reached). This can be useful for resource acquisitions:
rsrc = acquire_resource();
defer release_resource( rsrc );
if( work_with( rsrc ) )
return; // release_resource is called here
more_work_with( rsrc );
// .. and here
Declaration statements
Statements that begin with "var", "global", "function" or "class" declare and set variables.
Examples:
var x = 5, y = 6, z;
global World = null;
function fn(){ INFO( "'fn' was called" ); }
class C
{
var s = 1;
function f(){ INFO( "'C.f' was called" ); }
}
Function call statements
These statements are converted directly to function calls. Currently, 'include' and 'print' functions are available as statements.
Formats:
- include:
include [<file1>[, <file2>...]];
- for each entry, a function call is generated
- print:
print [<string>[, <string>...]];
- one function call is generated for all items
Examples:
include "io", "string";
print "Count: ", count;
Built-in accessors
There are several built-in accessors for the variable types that are available.
name | variable type | accessor type | description |
length | string | property | returns the length of the string, in bytes |
char. at | string | index | returns the character from the specified position |
apply | SGS/C function | property | function that allows to specify "this" & arg. array |
was_aborted | thread | property | returns if thread was aborted |
not_started | thread | property | returns if coroutine was not started yet |
running | thread | property | returns if thread is currently running |
can_resume | thread | property | returns if thread is not finished (can be resumed) |
end_on | thread | property | function that can specify an event to end the thread |
resume | thread | property | function that can resume the thread (see co_resume) |
abort | thread | property | function that can abort the thread (see abort) |
Classes
Basic class
class SampleClass // create a class
{
// static member variable (can be read from both class definition and instance)
global StaticVariable = 5;
// the default construction function
function __construct( x )
{
// instance member variable (can be read only from class instance, not definition)
this.c = x;
}
// static construction function
function Create( x )
{
return new SampleClass( x );
}
function SampleMethod( a, b ) // "SampleClass.SampleMethod" is the name that will show up in debug output
{
return a + b + this.c; // usage of "this" turns the function into a method
}
function SampleFunction( a, b )
{
return a + b;
}
}
// instances of class
inst1 = new SampleClass( 123 );
inst2 = SampleClass.Create( 456 );
// inspect instance 1, instance 2 and the underlying interface of instance 1
printvar( inst1, inst2, metaobj_get( inst1 ) );
Inheritance
// class A - base class
class A
{
function func()
{
println( "base" );
}
}
// class B - inherits from A
class B : A
{
function func()
{
this!A.func();
println( "override" );
}
}
instA = new A();
instB = new B();
instA.func(); // prints "base"
instB.func(); // prints "base", then "override"
Overloadable operators/interfaces (Metamethods):
- basic math: +, - (both unary and binary), *, /, %
- comparison
- conversions to
bool
and string
- typeof string retrieval
- cloning
- function call
Numeric string parsing rules
">>>" means "until any other symbol has been found" (the text is too dense for exact repetition)
The string is not a number if no numeric characters (0-9) could be parsed. (for example, "+" isn't a number but "0x" is)
- if string begins with 0b and has at least 3 characters, try to read a binary integer
- >>>, 0 or 1 adds the specified bit to the integer
- if string begins with 0o and has at least 3 characters, try to read an octal integer
- >>>, characters 0-7 add the specified 3 bits to the integer
- if string begins with 0x and has at least 3 characters, try to read a hexadecimal integer
- >>>, characters 0-9, a-f and A-F add the specified 4 bits to the integer
- otherwise, try to read a decimal number
- do a test to see if the number is not an integer
- skip the sign character (+ or -)
- skip the 0-9 characters
- if e, E or . is found, try to read a real value
- read the sign character (+ or -)
- >>>, characters 0-9 add the specified decimal number to the whole part
- if the dot character (.) is found, read the fractional part
- >>>, characters 0-9 add the specified decimal number to the fractional part
- if at least 3 more characters can be found and the first is "e" or "E", read the exponent part
- read the sign character (+ or -)
- >>>, characters 0-9 add the specified decimal number to the exponent part
- otherwise, try to read the integer
- read the sign character (+ or -)
- >>>, characters 0-9 add the specified decimal number to the integer
C API reference
The interface that it defines is one of the driving forces of SGScript. It is heavily influenced by Lua, while also adding some features of PHP (Zend Engine) and Python.
The most important difference is in error handling and triggers: errors detected in C can easily be non-fatal. Just like with PHP, minor errors are emitted as warnings that also propagate invalid (null) values throughout the system to effectively disable the subsequent calls and notify whoever is interested of the exact trail of errors. Furthermore, this behavior can be modified by using protected calls (pcall function) in SGScript and custom messaging callbacks in C.
The virtual machine supports:
- Operator overloading
- On-demand garbage collection
- Full introspection of machine state
- Type registration for simplified cross-library data reuse
Constants and types
This part of the documentation describes the various types and definitions used in the C API.
Main types
Return types:
- SGSRESULT [int]: output code (success = 0, failure: < 0 )
- SGSBOOL [int]: simplified output code (success = 1, failure = 0)
- SGSONE [int]: always returns 1
- SGSZERO [int]: always returns 0
Virtual machine / language types:
- sgs_Bool [int32_t]: boolean value
- sgs_Int [int64_t]: integer
- sgs_Real [double]: real (floating point) value
- sgs_SizeVal [int32_t]: size type
- sgs_CFunc [int ( sgs_Context* )]: C function type
- sgs_ObjInterface [struct]: object interface description
- sgs_Variable [struct]: the combined variable type
System types:
- sgs_Context [struct]: the virtual machine
- sgs_StackFrame [struct]: the function call info object
Interface data types:
- sgs_RegFuncConst [struct { const char*, sgs_CFunc }]: function registration unit
- sgs_RegIntConst [struct { const char*, sgs_Int }]: integer registration unit
- sgs_RegRealConst [struct { const char*, sgs_Real }]: real value registration unit
- sgs_ScriptFSData [struct { void*, const char*, void*, size_t }]: virtual file system request data
Interface function types:
- sgs_MemFunc [void* ( void* userdata, void* ptr, size_t size )]: memory interface function
- sgs_OutputFunc [void ( void* userdata, sgs_Context* C, const void* buf, sgs_SizeVal size )]: output function
- sgs_MsgFunc [void ( void* userdata, sgs_Context* C, int code, const char* text )]: messaging function
- sgs_HookFunc [void ( void*, sgs_Context*, int )]: debug hook function
- sgs_ScriptFSFunc [SGSRESULT ( void*, sgs_Context*, int, sgs_ScriptFSData* )]: virtual file system function
Error codes
These are the default meanings for error codes that are honored throughout the API.
- Generated by the C API
- SGS_SUCCESS: operation was successful
- SGS_ENOTFND: item was not found
- SGS_ECOMP: compile error
- SGS_ENOTSUP: operation is not supported
- SGS_EINVAL: invalid value was passed
- SGS_EINPROC: process was interrupted
- Generated by SGScript VM
- SGS_INFO: information about potential issues and state of the system
- SGS_WARNING: non-fatal issues
- SGS_ERROR: fatal issues
- SGS_APIERR: API usage errors
- SGS_INTERR: internal errors
- any other integer may be defined and returned by other interfaces
Variable type codes
- SGS_VT_NULL: null
- SGS_VT_BOOL: boolean
- SGS_VT_INT: integer
- SGS_VT_REAL: real value
- SGS_VT_STRING: string
- SGS_VT_FUNC: SGS function
- SGS_VT_CFUNC: C function
- SGS_VT_OBJECT: object
- SGS_VT_PTR: pointer
- SGS_VT_THREAD: thread/coroutine/context
Messaging system
Messages are combinations of importance code and a null-terminated string that holds the message itself. The messaging system's purpose generally is to notify about problems and allow handling them to some extent.
The C API has a function for sending messages - sgs_Msg - and two for dealing with the current callback - sgs_SetMsgFunc / sgs_GetMsgFunc.
The sgs_Msg function basically generates the full string from the format string and calls the callback that is currently set. Due to the data association and accessibility, various systems can be implemented on top of it:
Logging
All messages can simply be logged. For the most simple approach, the sgs_StdOutputFunc callback can be used with any FILE* for the data pointer.
A limited amount of exception handling
This system can be used to break out of any point in SGS code up until the last C function. For this, pcall can be used together with a callback that calls abort when necessary.
Debugging
On each warning or error, debugging code can be triggered. It can be an interactive console debugger (as implemented in ext/sgs_idbg), it could also be code that dumps the relevant state and sends it to the developer.
Hidden data collection
Similarly to exception handling, pcall can be used also for gathering messages otherwise skipped by the system. The sub-zero importance range is generally hidden - there's 2^31 values to use to mark special messages - however, sys_replevel or sgs_Cntl with SGS_CNTL_(SET_)MINLEV must be used to enable that range.
Iterator system
Iterators are objects that enable sequential, ordered traversal of object contents, allowing to read up to 2 variables at each position: the key and the value.
The C API has several functions used to deal with iterators. There are essentially three kinds of functions: initialization ( sgs_PushIterator, sgs_GetIterator ), advancing ( sgs_IterAdvance ) and data retrieval ( sgs_IterPushData, sgs_IterGetData ).
Iterator starts at the pre-first position (-1 in terms of indices), so nothing can be read initially, before the first advance. This allows to implement iterator handling with rather simple code:
initialize;
while( advance > 0 )
{
retrieve key and/or value;
..do something else..;
}
free;
A more real example follows:
// assuming iterable object is at the top of the stack
sgs_PushIterator( C, sgs_StackItem( C, -1 ) );
while( sgs_IterAdvance( C, sgs_StackItem( C, -1 ) ) > 0 )
{
sgs_StackIdx ssz = sgs_StackSize( C );
sgs_IterPushData( C, sgs_StackItem( C, -1 ), 1, 1 ); // push both key and value
sgs_SetStackSize( C, ssz ); // restore stack to have iterator at -1 again
}
sgs_Pop( C, 1 ); // pop the iterator
Another example using pointers:
sgs_Variable iterator, iterable, key, value;
// .. assuming iterable is initalized here ..
sgs_GetIterator( C, iterable, &iterator );
while( sgs_IterAdvance( C, iterator ) > 0 )
{
sgs_IterGetData( C, iterator, NULL, &value );
// .. use value ..
sgs_Release( C, &value );
sgs_IterGetData( C, iterator, &key, &value );
// .. use key and value ..
sgs_Release( C, &key );
sgs_Release( C, &value );
}
sgs_Release( C, &iterator );
// .. release the iterable or not, depending on how it was initialized ..
Garbage collection system
The garbage collector currently implemented is a basic stop-the-world mark-and-sweep algorithm that goes over all objects and recursively marks them as available.
The marking is done on the variable named redblue
, which contains 0 or 1 and in all avaiable objects is synced with the same variable for the context. On each pass, the bit is flipped for all available objects, so all objects that didn't have the bit flipped can be safely removed.
The garbage collector is invoked with sgs_GCExecute in the C API and gc_collect in SGScript.
Sub-objects are marked as available in the GCMARK callback with sgs_GCMark(Array) / sgs_ObjGCMark functions.
Metamethods
List of available metamethods:
__getindex
- When called: on sub-index/property retrieval
- Arguments: key
- Return value: any
__setindex
- When called: on setting sub-indices/properties
- Arguments: key, value
- Return value: none
__typeof
- When called: on type string retrieval (typeof / sgs_TypeOf)
- Arguments: none
- Return value: type string
__clone
- When called: on cloning operation (clone / sgs_Clone)
- Arguments: none
- Return value: the item to return as the cloned object
__tobool
- When called: on bool value retrieval
- Arguments: none
- Return value: bool
__tostring
- When called: on string value retrieval
- Arguments: none
- Return value: string
__negate
- When called: on negation (
-obj
)
- Arguments: none
- Return value: the negated object
__add
- When called: on addition (
var1 + var2
) when one of the variables has this interface defined
- Arguments: operands A and B (types are not restricted)
- Return value: the product of addition
__sub
- When called: on subtraction (
var1 - var2
) when one of the variables has this interface defined
- Arguments: operands A and B (types are not restricted)
- Return value: the product of subtraction
__mul
- When called: on multiplication (
var1 * var2
) when one of the variables has this interface defined
- Arguments: operands A and B (types are not restricted)
- Return value: the product of multiplication
__div
- When called: on division (
var1 / var2
) when one of the variables has this interface defined
- Arguments: operands A and B (types are not restricted)
- Return value: the product of division
__mod
- When called: on modulo (
var1 % var2
) when one of the variables has this interface defined
- Arguments: operands A and B (types are not restricted)
- Return value: the product of modulo
__compare
- When called: on comparison (
var1 + var2
) when one of the variables has this interface defined
- Arguments: operands A and B (types are not restricted)
- Return value: the result of comparison (real value indicating < 0 if A<B, > 0 if A>B, = 0 if A=B)
__call
- When called: on function call
- Arguments: arguments from the original call
- Return value: any
Closures
Closures are a combination of one callable and some variables. They are meant to simplify interfaces and code around places where it was important for functions to have access to call-invariant (same on every call) data.
Closures can be created from both SGScript and the C API, though both options have their limitations.
- In SGScript, closures can be created by letting functions "use" a variable, e.g. by writing
function func( args ) use( closures ){ ..body.. }
Memory management
- sgs_DefaultMemFunc - example memory management callback
- sgs_Memory - allocate/reallocate/free memory
- sgs_Malloc - allocate specified amount of memory
- sgs_Free - free a previously allocated memory pointer
- sgs_Realloc - allocate/reallocate/free memory (requires implicit sgs_Context* C)
- sgs_Alloc - allocate object (requires implicit sgs_Context* C)
- sgs_Alloc_n - allocate an array of objects (requires implicit sgs_Context* C)
- sgs_Alloc_a - allocate object + additional memory (requires implicit sgs_Context* C)
- sgs_Dealloc - free a previously allocated memory pointer (requires implicit sgs_Context* C)
Introspection / debugging helpers
Execution control
- sgs_XFCall - call variable as function
- sgs_XCall - call variable as function without
this
passed to it
- sgs_XThisCall - call variable as function function with
this
passed to it
- sgs_FCall - call variable as function
- sgs_Call - call variable as function without
this
passed to it
- sgs_ThisCall - call variable as function function with
this
passed to it
- sgs_GlobalCall - call a global function
- sgs_Abort - abort the execution of the previous SGS functions up to the last C function before them
- sgs_Cntl - set and/or retrieve various states in the system
Variable initialization
- sgs_MakeNull - initialize variable to a null variable
- sgs_MakeBool - initialize variable to a boolean variable
- sgs_MakeInt - initialize variable to an integer
- sgs_MakeReal - initialize variable to a real value
- sgs_MakeCFunc - initialize variable to C function
- sgs_MakePtr - initialize variable to a pointer variable
- sgs_InitStringBuf - initialize variable to a new char buffer
- sgs_InitString - initialize variable to a new string
- sgs_InitObjectPtr - initialize variable to an existing object and acquire it
- sgs_InitThreadPtr - initialize variable to a thread (context/coroutine) and acquire it
- sgs_CreateObject - initialize variable to a new object
- sgs_CreateObjectIPA - initialize variable to a new object with additional memory allocated in-place for the internal data pointer
- sgs_CreateArray - initialize variable to a new array, optionally using the specified number of pushed items on stack
- sgs_CreateDict - initialize variable to a new dict, optionally using the specified number of pushed items on stack
- sgs_CreateMap - initialize variable to a new map, optionally using the specified number of pushed items on stack
- sgs_CreateEvent - initialize variable to a new event
- sgs_CreatePooledEventBuf - initialize variable to a new or existing pooled event (by name in buffer)
- sgs_CreatePooledEvent - initialize variable to a new or existing pooled event (by C-string name)
Argument handling
- sgs_ArgErrorExt - emit an argument type mismatch error with additional formatting options
- sgs_ArgError - emit an argument type mismatch error
- sgs_FuncArgError - emit an argument type mismatch error (alias for states where
this
variable is hidden)
- sgs_MethodArgError - emit an argument type mismatch error (alias for states where
this
variable is NOT hidden)
- sgs_LoadArgsExtVA - parse the stack as an argument list with additional options (for custom wrapper functions)
- sgs_LoadArgsExt - parse the stack as an argument list with additional options
- sgs_LoadArgs - parse the stack as an argument list
- sgs_ParseMethod - the
this
object variable handling function, using the macro is preferred to this
- SGS_PARSE_METHOD - automagically handle a
this
object variable regardless of the way its passed
- sgs_Method - unhide the first variable on stack if there is a hidden
this
variable
- sgs_HideThis - hide the first variable on stack if the stack already doesn't contain a hidden
this
variable
- sgs_ForceHideThis - hide the first variable even if it wasn't previously hidden before unhiding
- sgs_ArgCheck_Object - argument parsing function for parsing any objects
- sgs_ObjectArg - returns the additional integer argument for object interface function calls
Virtual machine operations
- sgs_Assign - release the current variable and acquire-assign to it from the source
- sgs_ArithOp - run an arithmetic operation (+,-,*,/,%) on two variables to generate a third one
- sgs_IncDec - increment or decrement the specified variable
- sgs_Compare - check if both variables compare equal to each other
- sgs_EqualTypes - check if both variables have the same type and object interface (if both are objects)
- sgs_TypeOf - convert the topmost variable on stack to a type name string
- sgs_DumpVar - convert the topmost variable on stack to a string that contains detailed info about its contents
- sgs_GCExecute - run the garbage collection system to remove all unreachable objects
- sgs_StringConcat - concatenate two or more variables into a string
- sgs_CloneItem - clone the topmost stack item if it's mutable
- sgs_RegSymbol - register a persistent item (symbol) by the specified prefix/name
- sgs_GetSymbol - map name to a registered variable or variable to name using the symbol table
- sgs_Serialize(Ext) - serialize the given variable by converting it recursively to a byte stream
- sgs_Unserialize(Ext) - unserialize the given variable from a byte stream
- sgs_SerializeObject - specify the unserialization function and argument count to use for the object
- sgs_SerializeObjIndex - serialize an object's property/index
- sgs_SerializeSGSON - serialize the given variable into a text format
- sgs_UnserializeSGSON(Ext) - unserialize the given variable from a byte stream
String helpers
- sgs_PadString - return a string with two spaces appended to all newline characters
- sgs_ToPrintSafeString - return a string with all non-printable (except space), non-ASCII characters converted to a character hex code
- sgs_StringConcat - concatenate two or more variables into a string
Container helpers
- sgs_IsArray - return if variable is of
array
type
- sgs_IsDict - return if variable is of
dict
type
- sgs_IsMap - return if variable is of
map
type
- sgs_ArraySize - return array size or -1 if variable is not an array
- sgs_ArrayPush - push the last
count
variables on stack to the end of the array var
, then pop them from the stack
- sgs_ArrayPop - pop the last
count
variables off the end of the array var
, optionally return them
- sgs_ArrayErase - remove the specified variable range [`at`,`at`+`count`) from array
var
- sgs_ArrayFind - return the first position of item
what
in array var
or -1 if item was not found
- sgs_ArrayRemove - remove first/all occurrence(s) of
what
in array var
- sgs_Unset - unset the specified index of the given
dict
/map
variable, return if successful
Data retrieval & conversion
- sgs_GetBoolP - return the boolean version of the variable
- sgs_GetIntP - return the integer version of the variable
- sgs_GetRealP - return the real value version of the variable
- sgs_GetPtrP - return the pointer version of the variable
- sgs_ToBoolP - convert variable to a boolear value and return it
- sgs_ToIntP - convert variable to an integer and return it
- sgs_ToRealP - convert variable to a real value and return it
- sgs_ToPtrP - convert variable to a pointer and return it
- sgs_ToStringBufP - convert variable to a string, returning size
- sgs_ToStringP - convert variable to a string
- sgs_ToStringBufFastP - convert variable to a string, preventing possible recursion and returning size
- sgs_ToStringFastP - convert variable to a string, preventing possible recursion
- sgs_IsObjectP - check if variable is an object and has the specified interface pointer
- sgs_IsTypeP - check if variable is of specified registered type
- sgs_IsCallableP - check if variable is callable (SGS function, C function or object with CALL impl.)
- sgs_ParseBoolP - validate conversion, optionally return boolean value from variable, if possible
- sgs_ParseIntP - validate conversion, optionally return integer value from variable, if possible
- sgs_ParseRealP - validate conversion, optionally return real value from variable, if possible
- sgs_ParseStringP - validate conversion, optionally return string or buffer from variable, if possible
- sgs_ParseObjectPtrP - validate conversion, optionally return object pointer from variable, if possible
- sgs_ParsePtrP - validate conversion, optionally return pointer from variable, if possible
- sgs_ArraySize - retrieve size of array variable, if possible
- sgs_GetBool - return the boolean version of the variable on stack
- sgs_GetInt - return the integer version of the variable on stack
- sgs_GetReal - return the real value version of the variable on stack
- sgs_GetPtr - return the pointer version of the variable on stack
- sgs_ToBool - convert variable on stack to a boolear value and return it
- sgs_ToInt - convert variable on stack to an integer and return it
- sgs_ToReal - convert variable on stack to a real value and return it
- sgs_ToPtr - convert variable on stack to a pointer and return it
- sgs_ToStringBuf - convert variable on stack to a string, returning size
- sgs_ToString - convert variable on stack to a string
- sgs_ToStringBufFast - convert variable on stack to a string, preventing possible recursion and returning size
- sgs_ToStringFast - convert variable on stack to a string, preventing possible recursion
- sgs_IsObject - check if variable on stack is an object and has the specified interface pointer
- sgs_IsType - check if variable on stack is of specified registered type
- sgs_IsCallable - check if variable on stack is callable (SGS function, C function or object with CALL impl.)
- sgs_IsArray - return if variable is of
array
type
- sgs_IsDict - return if variable is of
dict
type
- sgs_IsMap - return if variable is of
map
type
- sgs_ParseBool - validate conversion, optionally return boolean value from variable on stack, if possible
- sgs_ParseInt - validate conversion, optionally return integer value from variable on stack, if possible
- sgs_ParseReal - validate conversion, optionally return real value from variable on stack, if possible
- sgs_ParseString - validate conversion, optionally return string or buffer from variable on stack, if possible
- sgs_ParseObjectPtr - validate conversion, optionally return object pointer from variable on stack, if possible
- sgs_ParsePtr - validate conversion, optionally return pointer from variable on stack, if possible
- sgs_ArraySize - retrieve size of array variable on stack, if possible
- sgs_GlobalBool - retrieve global by name as bool
- sgs_GlobalInt - retrieve global by name as integer
- sgs_GlobalReal - retrieve global by name as real
- sgs_GlobalStringBuf - retrieve global by name as string buffer
- sgs_GlobalString - retrieve global by name as string
- sgs_GetStringPtrP - get string pointer from variable pointer
- sgs_GetStringSizeP - get string size from variable pointer
- sgs_GetObjectStructP - get object pointer from variable pointer
- sgs_GetObjectDataP - get data pointer of object variable pointer
- sgs_GetObjectIfaceP - get interface pointer of object variable pointer
- sgs_SetObjectDataP - set data pointer of object variable pointer
- sgs_SetObjectIfaceP - set interface pointer of object variable pointer
- sgs_GetStringPtr - get string pointer from variable on stack
- sgs_GetStringSize - get string size from variable on stack
- sgs_GetObjectStruct - get object pointer from variable on stack
- sgs_GetObjectData - get data pointer of object variable on stack
- sgs_GetObjectIface - get interface pointer of object variable on stack
- sgs_SetObjectData - set data pointer of object variable on stack
- sgs_SetObjectIface - set interface pointer of object variable on stack
- sgs_ObjSetMetaObj - set meta-object of an object
- sgs_ObjGetMetaObj - retrieve meta-object of an object
- sgs_ObjSetMetaMethodEnable - enable or disable metamethod support for an object
- sgs_ObjGetMetaMethodEnable - check if metamethod support is enabled for an object
String generation helper interface
sgs_CreateEngine [function alias]
sgs_Context* sgs_CreateEngine()
Returns a new scripting engine context.
- Alias to
sgs_CreateEngineExt( sgs_DefaultMemFunc, NULL )
.
sgs_CreateEngineExt [function]
sgs_Context* sgs_CreateEngineExt( sgs_MemFunc memfunc, void* mfuserdata )
Returns a new scripting engine context, attached to the specified allocator.
sgs_DestroyEngine [function]
sgs_DestroyEngine( sgs_Context* C )
Destroys the passed context and frees all memory associated to it.
- All execution state, object and any other engine-allocated pointers will be invalid after this call.
sgs_RootContext [function]
sgs_RootContext( sgsContext* C )
Returns the root context of the engine.
- Root context is the context that was returned from sgs_CreateEngine / sgs_CreateEngineExt.
- Root context is useful because it can only be destroyed last, so it's persistent.
- If C = NULL, function returns NULL.
sgs_ForkState [function]
sgs_Context* sgs_ForkState( sgs_Context* C, int copystate )
Creates a copy of the execution state.
- If
copystate
is nonzero, all stacks (variable, closure, call) are copied as well, creating an exact duplicate.
sgs_ReleaseState [function]
sgs_ReleaseState( sgs_Context* C )
Releases the execution state, possibly destroying the VM.
- If the freed state is the last one that exists, function behaves exactly as sgs_DestroyEngine.
sgs_PauseState [function]
SGSBOOL sgs_PauseState( sgs_Context* C )
Suspends the execution state, prompting the VM to return control to caller.
- A state cannot be suspended if call stack contains C functions or unusual constructs (at the moment some object interface calls may not work either).
- This function can be used in a C function that was called from a SGS function.
sgs_ResumeState*** [functions]
SGSBOOL sgs_ResumeStateRet( sgs_Context* C, int args, int* outrvc )
Resumes the execution state, passing arguments and retrieving the number of returned values.
SGSBOOL sgs_ResumeStateExp( sgs_Context* C, int args, int expect )
Resumes the execution state, passing arguments and retrieving the specified number of returned values.
- Returns true if state was suspended and thus subsequently resumed.
args
must be bigger than or equal to the stack size.
outrvc
can be NULL.
sgs_ResumeState [function alias]
SGSBOOL sgs_ResumeState( sgs_Context* C )
Resumes the execution state.
- Alias to
sgs_ResumeStateExp( C, 0, 0 )
.
sgs_CreateSubthread [function]
void sgs_CreateSubthread( sgs_Context* T, sgs_Context* C, sgs_Variable* out, sgs_StkIdx args, int gotthis )
Creates a thread (managed coroutine) with a starting function.
T
is the parent thread (use sgs_RootContext for a global thread and same as C
for a local thread).
C
contains the function and arguments.
- If
out
is NULL
, new thread is pushed to C
's stack, otherwise it is assigned to that variable.
args
and gotthis
specify how to interpret the values pushed on stack (function expects args + (gotthis?1:0) + 1
values).
- Thread is started before returning from this function.
sgs_ProcessSubthreads [function]
int sgs_ProcessSubthreads( sgs_Context* C, sgs_Real dt )
Advances all subthreads belonging to this state, using the given delta time.
- Every subthread is resumed, waiting timers are advanced.
sgs_EventState [function]
SGSBOOL sgs_EventState( sgs_Context* C, sgs_Variable evt, int state )
Sets the event state.
- Function returns the previous state of the event.
evt
must be the event object.
state
can be one of these values: SGS_TRUE
, SGS_FALSE
or SGS_QUERY
.
SGS_QUERY
doesn't modify the state, only returns it.
sgs_EndOn [function]
void sgs_EndOn( sgs_Context* C, sgs_Variable ev, int enable )
Associates or detaches the event from thread end set.
- end_on is the SGScript version of this function.
ev
can be any object, it should be an object with the "convert to bool" behavior implemented, such as the event object.
- The thread will interpret
true
as a request to stop.
sgs_ExecString [function alias]
SGSRESULT sgs_ExecString( sgs_Context* C, const char* str )
Compiles and executes a string of text.
- Leaves the stack the same as it was before the call.
- Alias to
sgs_ExecBuffer( C, str, SGS_STRINGLENGTHFUNC( str ) )
.
- Theoretically bytecode is supported but it will most probably be trimmed by the string length function, unless a different string termination mark is used, and a different string length function to detect it is set.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was not recognized
sgs_ExecBuffer [function alias]
SGSRESULT sgs_ExecBuffer( sgs_Context* C, const char* buf, sgs_SizeVal size )
Compiles and executes a buffer of text or bytecode.
- Leaves the stack the same as it was before the call.
- Alias to
sgs_AdjustStack( C, 0, sgs_EvalBuffer( C, buf, sz ) )
.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was not recognized
sgs_EvalString [function alias]
SGSRESULT sgs_EvalString( sgs_Context* C, const char* str )
Compiles and executes a string of text, leaving the return values on stack and returning their count.
- To ignore return values, use sgs_ExecString.
- Alias to
sgs_EvalBuffer( C, str, SGS_STRINGLENGTHFUNC( str ) )
.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was not recognized
sgs_EvalBuffer [function]
SGSRESULT sgs_EvalBuffer( sgs_Context* C, const char* buf, sgs_SizeVal size )
Compiles and executes a buffer of text or bytecode, leaving the return values on stack and returning their count.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was not recognized
sgs_ExecFile [function alias]
SGSRESULT sgs_ExecFile( sgs_Context* C, const char* filename )
Compiles and executes a file containing script text or bytecode.
- Leaves the stack the same as it was before the call.
- Alias to
sgs_AdjustStack( C, 0, sgs_EvalFile( C, filename ) )
.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was not recognized
- SGS_ENOTSUP: attempted to load a binary (no additional error is printed)
sgs_EvalFile [function]
SGSRESULT sgs_EvalFile( sgs_Context* C, const char* filename )
Compiles and executes a file containing script text or bytecode, leaving the return values on stack and returning their count.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was not recognized
- SGS_ENOTSUP: attempted to load a binary (no additional error is printed)
sgs_Include [function alias]
SGSBOOL sgs_Include( sgs_Context* C, const char* name )
Includes an item by the specified name, returning if completed successfully.
- A C version of the
include
SGS function.
- Alias to
sgs_IncludeExt( C, name, NULL )
.
sgs_IncludeExt [function]
SGSBOOL sgs_IncludeExt( sgs_Context* C, const char* name, const char* searchpath )
Includes an item by the specified name, optionally looking in the places specified by the search path, returning if completed successfully.
- a C version of the include SGS function
searchpath
overrides SGS_PATH for the time of execution
sgs_Compile [function]
SGSRESULT sgs_Compile( sgs_Context* C, const char* buf, size_t size, char** outbuf, size_t* outsize )
Compile a buffer of SGScript code, returning the compiled code buffer on success.
- A C version of compile_sgs SGS function.
outbuf
must be freed after usage with one of the relevant memory handling functions.
outbuf
and outsize
will only contain valid buffer (pointer and size) on success.
- All info/warning/error messages are passed to the Messaging system.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was too big
- SGS_EINPROC: failed to serialize bytecode
sgs_DumpCompiled [function]
SGSRESULT sgs_DumpCompiled( sgs_Context* C, const char* buf, size_t size )
Dump compiled bytecode or SGScript code buffer to stdout.
- Code is compiled before dumping if SGScript code is passed.
- In that case, all info/warning/error messages are passed to the Messaging system.
Error codes:
- SGS_ECOMP: compiler error
- SGS_EINVAL: passed data was too big
sgs_LoadLib_*** [functions]
void sgs_LoadLib_Fmt( sgs_Context* C )
void sgs_LoadLib_IO( sgs_Context* C )
void sgs_LoadLib_Math( sgs_Context* C )
void sgs_LoadLib_OS( sgs_Context* C )
void sgs_LoadLib_RE( sgs_Context* C )
void sgs_LoadLib_String( sgs_Context* C )
Loads the library into the specified context
Fmt
: string formatting library
IO
: input/output library
Math
: math library
OS
: operating system info (date/time, environment, locale, terminal access) library
RE
: regular expression library
String
: string handling library
sgs_Reg***Consts [function]
void sgs_RegFuncConsts( sgs_Context* C, const sgs_RegFuncConst* list, int size )
void sgs_RegIntConsts( sgs_Context* C, const sgs_RegIntConst* list, int size )
void sgs_RegRealConsts( sgs_Context* C, const sgs_RegRealConst* list, int size )
Loads the specified list of constants in the context.
- The end of list can be specified in two ways:
- set the size to
sizeof(list)/sizeof(list[0])
;
- set the size to -1 and end the list with
SGS_RC_END()
;
- using both at the same time should be reserved to special cases only.
sgs_Make*** [functions]
sgs_Variable sgs_MakeNull()
sgs_Variable sgs_MakeBool( sgs_Bool value )
sgs_Variable sgs_MakeInt( sgs_Int value )
sgs_Variable sgs_MakeReal( sgs_Real value )
sgs_Variable sgs_MakeCFunc( sgs_CFunc func )
sgs_Variable sgs_MakePtr( void* ptr )
Returns a variable instance of the specified type.
- Since these are basic types, they don't need to be freed.
- sgs_Bool is transformed to 0/1, everything else is unchanged.
sgs_Init*** [functions]
void sgs_InitStringBuf( sgs_Context* C, sgs_Variable* out, const char* str, sgs_SizeVal size )
void sgs_InitString( sgs_Context* C, sgs_Variable* out, const char* str )
void sgs_InitObjectPtr( sgs_Variable* out, sgs_VarObj* obj )
void sgs_InitThreadPtr( sgs_Variable* out, sgs_Context* T )
Initialize a variable to the specified type.
- Since these are reference-counted types, they need to be released manually.
- To allocate an uninitialized string buffer, use sgs_InitStringAlloc.
sgs_Create*** [functions]
SGSONE sgs_CreateObject( sgs_Context* C, sgs_Variable* out, void* data, sgs_ObjInterface* iface )
void* sgs_CreateObjectIPA( sgs_Context* C, sgs_Variable* out, sgs_SizeVal added, sgs_ObjInterface* iface )
Creates a new object.
SGSONE sgs_CreateArray( sgs_Context* C, sgs_Variable* out, sgs_SizeVal numitems )
Creates an array from numitems
last items on the stack, pops those items.
SGSONE sgs_CreateDict( sgs_Context* C, sgs_Variable* out, sgs_SizeVal numitems )
Creates a dict from numitems
last items on the stack, pops those items.
SGSONE sgs_CreateMap( sgs_Context* C, sgs_Variable* out, sgs_SizeVal numitems )
Creates a map from numitems
last items on the stack, pops those items.
SGSONE sgs_CreateEvent( sgs_Context* C, sgs_Variable* out )
Initialize variable to a new event.
SGSONE sgs_CreatePooledEventBuf( sgs_Context* C, sgs_Variable* out, sgs_Variable dict, const char* str, sgs_SizeVal size )
Initialize variable to a new or existing pooled event (by name in buffer).
SGSONE sgs_CreatePooledEvent( sgs_Context* C, sgs_Variable* out, sgs_Variable dict, const char* str )
Initialize variable to a new or existing pooled event (by C-string name).
- If
out
is unspecified, the new variable is pushed on the stack instead.
- sgs_CreateObjectIPA stands for "initialize object, allocate memory in-place":
- it means that the
added
memory space will be appended to the end of object allocation;
- this allows to allocate all object data for most objects with just one allocation, instead of two;
- the allocated memory will be returned and also available via sgs_GetObjectData(P).
sgs_Push*** [functions]
SGSONE sgs_PushNull( sgs_Context* C )
SGSONE sgs_PushNulls( sgs_Context* C, int count )
SGSONE sgs_PushBool( sgs_Context* C, sgs_Bool value )
SGSONE sgs_PushInt( sgs_Context* C, sgs_Int value )
SGSONE sgs_PushReal( sgs_Context* C, sgs_Real value )
SGSONE sgs_PushStringBuf( sgs_Context* C, const char* str, sgs_SizeVal size )
SGSONE sgs_PushString( sgs_Context* C, const char* str )
SGSONE sgs_PushCFunc( sgs_Context* C, sgs_CFunc func )
SGSONE sgs_PushObject( sgs_Context* C, void* data, sgs_ObjInterface* iface )
void* sgs_PushObjectIPA( sgs_Context* C, sgs_SizeVal added, sgs_ObjInterface* iface )
SGSONE sgs_PushPtr( sgs_Context* C, void* ptr )
SGSONE sgs_PushObjectPtr( sgs_Context* C, sgs_VarObj* obj )
SGSONE sgs_PushVariable( sgs_Context* C, sgs_Variable* var )
Pushes the data on the stack, as a new entry, appended to the end.
To push objects, use sgs_Create*** functions.
To allocate an uninitialized string buffer, use sgs_PushStringAlloc.
- sgs_Bool is transformed to 0/1 before pushing, everything else is unchanged.
- sgs_PushVariable will increment the reference count of strings, SGS functions and objects.
- Most functions here always return 1 (SGSONE), making them suitable for a "return sgs_Push***" construct.
sgs_StoreVariable [function]
void sgs_StoreVariable( sgs_Context* C, sgs_Variable* var )
Copy the topmost item of the current stack frame to the specified place, acquire it and pop it.
sgs_Pop [function]
void sgs_Pop( sgs_Context* C, int count )
Pops count
variables off the current frame of the stack.
sgs_PopSkip [function]
void sgs_PopSkip( sgs_Context* C, int count, int skip )
Pops count
variables off the current frame of the stack, skipping the last skip
elements.
sgs_InsertVariable [function]
void sgs_InsertVariable( sgs_Context* C, int pos, sgs_Variable var )
Inserts a variable var
at a given index pos
of the current stack frame, increasing its reference count.
sgs_PushItem [function alias]
void sgs_PushItem( sgs_Context* C, sgs_StkIdx item )
Copy an item from the current stack frame and append it to the end of the stack.
- Alias of
sgs_PushVariable( C, sgs_StackItem( C, item ) )
.
sgs_GetIndex [function]
SGSBOOL sgs_GetIndex( sgs_Context* C, sgs_Variable obj, sgs_Variable idx, sgs_Variable* out, int isprop )
Retrieve index/property idx
from the specified variable obj
to the position out
, specifying retrieval type via isprop
, return if successful.
- On failure, out is set to a
null
variable.
sgs_SetIndex [function]
SGSBOOL sgs_SetIndex( sgs_Context* C, sgs_Variable obj, sgs_Variable idx, sgs_Variable val, int isprop )
Set index/property idx
in the specified variable obj
to the value val
, specifying type via isprop
, return if successful.
sgs_PushIndex [function]
SGSBOOL sgs_PushIndex( sgs_Context* C, sgs_Variable obj, sgs_Variable idx, int isprop )
Retrieve and push index/property idx
from the specified variable obj
, specifying retrieval type via isprop
, return if successful.
- On failure,
null
is pushed to stack.
sgs_PushProperty [functions]
SGSBOOL sgs_PushProperty( sgs_Context* C, sgs_Variable var, const char* name )
Load and push the property of the variable var
in the current stack frame, return if successful.
- On failure,
null
is pushed to stack.
sgs_SetProperty [functions]
SGSBOOL sgs_SetProperty( sgs_Context* C, sgs_Variable var, const char* name, sgs_Variable val )
Set the property name
of variable var
to val
, return if successful.
sgs_PushNumIndex [function]
SGSBOOL sgs_PushNumIndex( sgs_Context* C, sgs_Variable var, sgs_Int idx )
Load and push the integer index idx
of the variable obj
, return if successful.
- On failure,
null
is pushed to stack.
sgs_SetNumIndex [function]
SGSBOOL sgs_SetNumIndex( sgs_Context* C, sgs_Variable var, sgs_Int idx, sgs_Variable val )
Set the index idx
of variable var
to val
, return if successful.
sgs_GetGlobal [function]
SGSBOOL sgs_GetGlobal( sgs_Context* C, sgs_Variable idx, sgs_Variable* out )
Retrieve a global variable by index idx
to position out
.
- On failure, out is set to a
null
variable.
sgs_SetGlobal [function]
SGSBOOL sgs_SetGlobal( sgs_Context* C, sgs_Variable idx, sgs_Variable val )
Set global variable idx
to val
.
- When setting
_G
(environment superglobal), val
must be of dict
/map
type or the function will fail.
sgs_PushGlobalByName [function]
SGSBOOL sgs_PushGlobalByName( sgs_Context* C, const char* name )
Push the global variable name
on the stack, return if successful.
- On failure,
null
is pushed to stack.
sgs_GetGlobalByName [function]
SGSBOOL sgs_GetGlobalByName( sgs_Context* C, const char* name, sgs_Variable* out )
Retrieve the global variable name
, return if successful.
- On failure, out is set to a
null
variable.
sgs_SetGlobalByName [function]
SGSBOOL sgs_SetGlobalByName( sgs_Context* C, const char* name, sgs_Variable val )
Set global variable name
to val
.
- When setting
_G
(environment superglobal), val
must be of dict
/map
type or the function will fail.
sgs_Registry [function]
sgs_Variable sgs_Registry( sgs_Context* C, int subtype )
Retrieve a table from registry.
subtype
can be one of:
- SGS_REG_ROOT: registry root (
_R
);
- SGS_REG_SYM: symbol table (
_R["$sym"]
);
- SGS_REG_INC: included file table (
_R["$inc"]
).
sgs_GetEnv [function]
void sgs_GetEnv( sgs_Context* C, sgs_Variable* out )
Retrieve the global environment variable (_G).
sgs_SetEnv [function]
void sgs_SetEnv( sgs_Context* C, sgs_Variable* var )
Set a global environment variable from the variable var
.
- Only
dict
/map
types are accepted.
sgs_PushEnv [function]
void sgs_PushEnv( sgs_Context* C )
Retrieve and push the global environment variable (_G).
sgs_PushPath [function]
SGSBOOL sgs_PushPath( sgs_Context* C, sgs_Variable var, const char* path, ... )
Push the variable specified by starting point var
and traversal path path
, return if successful.
The safety of this function is similar to that of the printf
family of functions. Be explicit in what types you pass to the variable argument list to avoid errors.
- The syntax of
path
: a list of letters, specifying a sub-variable to request (o,p,s,i,k,n).
Table of accepted letters
letter | property? | variable arguments | virtual machine access mode / description |
o | yes | SizeVal | integer property |
p | yes | C string | string property |
s | yes | SizeVal, buffer | special string property |
i | no | SizeVal | integer index |
k | no | C string | string index |
n | no | SizeVal, buffer | special string index |
- Legend:
- SizeVal: sgs_SizeVal / int32_t
- C string: null-terminated char* string
- buffer: char* byte array, size is specified in the previous argument
- property?: if yes, property access is used (object.property), otherwise index access is used (object[index])
sgs_StorePath [function]
SGSBOOL sgs_StorePath( sgs_Context* C, sgs_Variable var, sgs_Variable val, const char* path, ... )
Set value val
to variable specified by starting point var
and traversal path path
.
The safety of this function is similar to that of the printf family of functions. Be explicit in what types you pass to the variable argument list to avoid errors.
- The syntax of
path
is the same as with sgs_PushPath.
- The last item on the path (or in the case of an empty path, the starting point) is accessed with a store operation, the rest - with a push operation.
sgs_Store***Consts [functions]
void sgs_StoreFuncConsts( sgs_Context* C, sgs_Variable var, const sgs_RegFuncConst* list, int size )
void sgs_StoreIntConsts( sgs_Context* C, sgs_Variable var, const sgs_RegIntConst* list, int size )
void sgs_StoreRealConsts( sgs_Context* C, sgs_Variable var, const sgs_RegRealConst* list, int size )
Loads the specified list of constants in the specified variable.
- The end of list can be specified in two ways:
- set the size to
sizeof(list)/sizeof(list[0])
;
- set the size to -1 and end the list with
SGS_RC_END()
;
- using both at the same time should be reserved to special cases only.
sgs_ArgErrorExt [function]
int sgs_ArgErrorExt( sgs_Context* C, int argid, int method, const char* expect, const char* expfx )
Prints the argument type mismatch error.
expfx
- prefix of expect
, put exactly before this for things like 'strict '.
- Always returns 0 so it can be used to return and print an error in the same statement.
sgs_ArgError [function]
int sgs_ArgError( sgs_Context* C, int argid, int expect, int is_strict )
Prints the argument type mismatch error.
- Always returns 0 so it can be used to return and print an error in the same statement.
sgs_***ArgError [function aliases]
int sgs_FuncArgError( sgs_Context* C, int argid, int expect, int is_strict )
int sgs_MethodArgError( sgs_Context* C, int argid, int expect, int is_strict )
Prints the argument type mismatch error.
- Always returns 0 so it can be used to return and print an error in the same statement.
- Alias to
sgs_ArgError( C, argid, Func/Method => 0/1, expect, is_strict )
.
sgs_LoadArgsExt(VA) [function]
SGSBOOL sgs_LoadArgsExt( sgs_Context* C, int from, const char* cmd, ... )
SGSBOOL sgs_LoadArgsExtVA( sgs_Context* C, int from, const char* cmd, va_list* args )
Parse the stack items and retrieve their data according to cmd
, starting from item from
.
- For anything function requires, pass the value; for anything it returns - the pointer to the value.
cmd
is a string consisting of one-character commands.
- The commands are grouped into two kinds: control commands and parsing commands.
- Function returns whether all required arguments have been parsed successfully;
- thus, if function returns < 1, state of outputs is somewhat unknown unless filled with defaults;
- it is guaranteed that all arguments will be parsed from first (specified) forward, not in any other way;
null
values in optional arguments are skipped (this may not apply to custom checking functions).
control commands
?
-- only check, do not write the result and do not require a pointer to write the data to
!
-- enable strict parsing for the next item (requires exactly the type specified
-
,+
-- enable (-) or disable (+) treating integers as signed (default = true)
|
-- mark the point where required arguments end and optional arguments begin
#
-- do range checking on integer arguments (min/max of the required types)
^
-- clamp the argument to the range of the required type
~
-- ignore ranges and chop out-of-range integers (default)
<
-- move argument pointer 1 item back (cannot move it before 0)
>
-- move argument pointer 1 item forward
@
-- specify that this is a method (argument 0 = 'this'; shifts argument indices on error printing by -1)
.
-- specify the end of argument list (how many arguments are expected)
parsing commands
n
-- check for null
(returns SGSBOOL = 1, always strict)
b
-- check for bool
(returns sgs_Bool)
c
-- check for int
(returns int8_t or uint8_t, depending on sign settings, may check ranges)
w
-- check for int
(returns int16_t or uint16_t, depending on sign settings, may check ranges)
l
-- check for int
(returns int32_t or uint32_t, depending on sign settings, may check ranges)
q
-- check for int
(returns int64_t or uint64_t, depending on sign settings, may check ranges)
i
-- check for int
(returns sgs_Int, may check ranges)
I
-- check for int
(returns int or unsigned int, depending on sign settings, may check ranges)
f
-- check for real
(returns float)
d
-- check for real
(returns double)
r
-- check for real
(returns sgs_Real)
s
-- check for string
(returns char*)
m
-- check for string
(returns char* string and sgs_SizeVal size)
p
-- check for func/cfunc/object with CALL
(callables) (returns SGSBOOL = 1)
y
-- check for thread
(returns sgs_Context*)
a
-- check for array
(returns sgs_SizeVal size, use -1 as starting value to check optional arguments)
t
-- check for dict
(returns sgs_SizeVal size, use -1 as starting value to check optional arguments)
h
-- check for map
(returns sgs_SizeVal size, use -1 as starting value to check optional arguments)
o
-- check for specific object
(requires sgs_ObjInterface* interface, returns <type>* data - the data pointer)
*
-- check for any object
(returns sgs_ObjInterface* interface)
&
-- check for pointer
(returns void* data - the pointer)
v
-- check for any (non-null if strict, returns sgs_Variable data)
x
-- call a custom checking function (requires sgs_ArgCheckFunc, everything else depends on function)
sgs_LoadArgs [function alias]
SGSBOOL sgs_LoadArgs( sgs_Context* C, const char* cmd, ... )
Parse the stack items and retrieve their data according to cmd
, starting from item 0.
- For more info on syntax and usage, refer to sgs_LoadArgsExt(VA).
- Alias to
sgs_LoadArgsExt( C, 0, cmd, ... )
.
sgs_ParseMethod [function]
SGSBOOL sgs_ParseMethod( sgs_Context* C, sgs_ObjInterface* iface, void** ptrout, const char* name );
Implements method parsing.
- If object of the right type is first in the stack, its data pointer is received.
- Function also registers its name to
name
.
SGS_PARSE_METHOD [function alias]
SGSBOOL SGS_PARSE_METHOD( sgs_Context* C, sgs_ObjInterface* iface, T*& ptrout, ident objname, ident methodname )
Method parsing macro.
- If object of the right type is first in the stack, its data pointer is received.
- Function also registers its name to "objname.methodname".
sgs_Method [function]
SGSBOOL sgs_Method( sgs_Context* C )
Unlock the 'this' variable, return if the function was called as a method (and thus variable was unlocked).
- Method calls look like this: "object.method(...)".
sgs_(Force)HideThis [functions]
SGSBOOL sgs_HideThis( sgs_Context* C )
SGSBOOL sgs_ForceHideThis( sgs_Context* C )
Hide the 'this' variable, return if successful.
- sgs_ForceHideThis attempts to hide the first item on stack even if it didn't belong to the call, sgs_HideThis only does it if it belongs to the call and was hidden before.
- The hiding method is stack offset pointer shift.
sgs_ArgCheck_Object [function]
int sgs_ArgCheck_Object( sgs_Context* C, int argid, va_list* args, int flags )
Argument parsing function for parsing any objects.
- To be used with sgs_LoadArgs and related functions.
- Strictness controls whether
null
is accepted.
- Returned value: sgs_VarObj* (expects sgs_VarObj** argument for it).
sgs_ObjectArg [function]
int sgs_ObjectArg( sgs_Context* C )
Returns the additional integer argument to an object interface function call.
- For
getindex
and setindex
: if argument is nonzero, property is requested, zero - index.
sgs_XFCall [functions]
int sgs_XFCall( sgs_Context* C, int args, int gotthis )
Call the function with the arguments on stack, returning variables on stack and their count.
- Refer to sgs_FCall for additional documentation.
sgs_X(This)Call [function aliases]
int sgs_XCall( sgs_Context* C, int args )
int sgs_XThisCall( sgs_Context* C, int args )
Call the function with the arguments on stack, returning variables on stack and their count.
- Aliases to sgs_XFCall, for the first function
gotthis = 0
, for the second gotthis = 1
.
sgs_FCall [functions]
int sgs_FCall( sgs_Context* C, int args, int expect, int gotthis )
Call the function with the arguments on stack, returning the expected number of variables on stack.
args
: the primary variables to be passed to the function, in the same order they are in the stack.
expect
: the number of variables to be left after a successful call.
gotthis
: whether the function is a method and an additional argument needs to be passed as the 'this' value before others.
- Return value of function is the original number of returned values on stack from this call.
After a successful call, all arguments will be popped off the stack and the expected number of variables will appear in their place. If the underlying callable does not return enough values, 'null' variables will be pushed instead. If the number of returned values is bigger than expected, only the first expected return values will stay on the stack.
- Expected stack structure:
- [function]
- (if gotthis != 0) [this]
- [argument] x
args
- A callable is one of the following:
- SGS function
- C function
- object with CALL interface function defined
To check if function call was aborted, see sgs_Cntl / SGS_CNTL_GET_ABORT.
To find out if execution state was suspended in this call, see sgs_Cntl / SGS_CNTL_GET_PAUSED.
sgs_(This)Call [function aliases]
void sgs_Call( sgs_Context* C, int args, int expect )
void sgs_ThisCall( sgs_Context* C, int args, int expect )
Call the function with the arguments on stack, returning the expected number of variables on stack.
- Aliases to sgs_FCall, for the first function
gotthis = 0
, for the second gotthis = 1
.
sgs_GlobalCall [function]
SGSBOOL sgs_GlobalCall( sgs_Context* C, const char* name, int args, int expect )
Call the global variable name
as a function.
sgs_TypeOf [function]
void sgs_TypeOf( sgs_Context* C, sgs_Variable var )
Return the type name string of the specified variable.
- Object type sources are processed in the following order:
- Metamethod
__typeof
;
sgs_ObjInterface::name
;
- If both methods failed, just return 'object'.
sgs_DumpVar [function]
void sgs_DumpVar( sgs_Context* C, sgs_Variable var, int maxdepth )
Convert the variable to a highly informative string that should display its contents, up to maxdepth
depth.
- If object does not have the DUMP interface function implemented, only its pointer in memory and reference count are displayed.
sgs_GCExecute [function]
void sgs_GCExecute( sgs_Context* C )
Call the garbage collector on the VM.
- This procedure may take some time if the object graph is big.
- During the procedure, the GCMARK interface functions of objects are invoked for the objects visible from entry points (like stack and global tables).
sgs_DebugDumpVarExt [functions]
const char* sgs_DebugDumpVarExt( sgs_Context* C, sgs_Variable var, int maxdepth )
Push a string containing variable data and return const char* to it.
- If
maxdepth
is negative, variable is converted to a normal string (sgs_ToString) instead of dump string (sgs_DumpVar).
sgs_DebugDumpVar [function alias]
const char* sgs_DebugDumpVar( sgs_Context* C, sgs_Variable* var )
Push a variable dump string and return const char* to it.
sgs_DebugPrintVar [function alias]
const char* sgs_DebugPrintVar( sgs_Context* C, sgs_Variable var )
Push a string, converted from variable and return const char* to it.
sgs_PadString [function]
void sgs_PadString( sgs_Context* C )
Replace the topmost variable of current stack frame with a string variable where two spaces are appended after every newline.
sgs_ToPrintSafeString [function]
void sgs_ToPrintSafeString( sgs_Context* C )
Replace the topmost variable of current stack frame with a string where all non-printable (except space), non-ASCII characters converted to a character hex code.
sgs_StringConcat [function]
void sgs_StringConcat( sgs_Context* C, int args )
Concatenate the args
number of topmost string variables in the current stack frame.
- If
args
= 0, empty string is pushed.
sgs_CloneItem [function]
void sgs_CloneItem( sgs_Context* C, sgs_Variable var )
Push a copy of the specified stack item.
Even though operations with functions and strings succeed, functions and strings are not actually cloned since they are immutable.
- Function will fail if any object attempted to be cloned does not support cloning.
sgs_RegSymbol [function]
void sgs_RegSymbol( sgs_Context* C, const char* prefix, const char* name, sgs_Variable var )
Register a persistent item (symbol) by the specified prefix/name.
- Symbols are used for serialization to map unserializable and persistent items in both ways, to preserve their linkage in the serialized data.
- At least one of (
prefix
, name
) must be set to a non-empty string. If both are set, they are concatenated in the given order.
- This function is equivalent to sym_register in the SGScript API.
sgs_GetSymbol [function]
SGSBOOL sgs_GetSymbol( sgs_Context* C, sgs_Variable var, sgs_Variable* out )
Map name to a registered variable or variable to name using the symbol table.
- This function is equivalent to sym_get in the SGScript API.
sgs_Serialize(Ext) [functions]
void sgs_Serialize( sgs_Context* C, sgs_Variable var )
Serialize the given variable (convert to a byte stream).
void sgs_SerializeExt( sgs_Context* C, sgs_Variable var, int mode )
Same as above, also allows to specify serialization mode.
sgs_Serialize
is alias of sgs_SerializeExt( C, var, SGS_SERIALIZE_DEFAULT )
- Function pushes a string variable on stack if serialization was at least minimally successful, otherwise
null
is pushed.
- Default serialization mode is 2 or the current mode inside object serialization callback.
- The following variable types can be serialized:
- symbols (variables that can be found in the symbol table);
- null, bool, int, real, string, func (SGS function);
- objects with the SERIALIZE interface function defined.
sgs_Unserialize(Ext) [functions]
SGSBOOL sgs_Unserialize( sgs_Context* C, sgs_Variable var )
Unserialize the given variable (decode the byte stream).
SGSBOOL sgs_UnserializeExt( sgs_Context* C, sgs_Variable var, int mode )
Same as above, also allows to specify serialization mode.
Be mindful of the data sources you use - calls to any global function can be placed in the byte stream.
sgs_Unserialize
is alias of sgs_UnserializeExt( C, var, SGS_SERIALIZE_DEFAULT )
- To make sure only the right functions can be called, the global environment can be replaced with sgs_SetEnv.
sgs_SerializeObject [function]
void sgs_SerializeObject( sgs_Context* C, sgs_StkIdx args, const char* func )
Specify the unserialization function and argument count to use for the object.
sgs_SerializeObjIndex [function]
void sgs_SerializeObjIndex( sgs_Context* C, sgs_Variable key, sgs_Variable val, int isprop )
Serialize an object's property/index.
- This function is used to serialize structures that may contain references to other variables...
- ...which leave them open to producing a self-referential construct that normal tree serialization cannot handle.
- Only supported by serialization modes 1 and 2 (binary).
- Mode 1 support does not actually allow serializing self-referential structures.
- For usage examples, see source code in
sgs_std.c
.
sgs_SerializeSGSON [function]
void sgs_SerializeSGSON( sgs_Context* C, sgs_Variable var, const char* tab )
Serialize the given variable into a text format.
- This is similar to
sgs_SerializeExt
with mode = 3, only difference being the tab
argument.
tab
allows to specify the string used for tabs
- if
tab
is NULL
, the text output is tightly packed, without any extra spaces
sgs_UnserializeSGSON(Ext) [functions]
void sgs_UnserializeSGSON( sgs_Context* C, const char* str )
Unserialize the given variable from a byte stream.
void sgs_UnserializeSGSONExt( sgs_Context* C, const char* str, size_t size )
Allows to pass a string buffer to the parsing function.
sgs_UnserializeSGSON
is alias to sgs_UnserializeSGSONExt( C, str, SGS_STRINGLENGTHFUNC( str ) )
- This is the same as creating a string variable and calling
sgs_UnserializeExt( C, <var>, 3 )
sgs_Assign [function]
void sgs_Assign( sgs_Context* C, sgs_Variable* var_to, sgs_Variable* var_from )
Acquire var_from
, release var_to
, copy var_from
to var_to
.
sgs_ArithOp [function]
void sgs_ArithOp( sgs_Context* C, sgs_Variable* out, sgs_Variable* A, sgs_Variable* B, int op )
Perform the specified operation on variables A and B, returning the value on out
.
This function prints errors, exactly like VM would (internally there are the same functions).
- This function can perform 6 operations, which are specified by passing the following values to
op
:
- SGS_EOP_ADD: +
- SGS_EOP_SUB: - (binary)
- SGS_EOP_MUL: *
- SGS_EOP_DIV: /
- SGS_EOP_MOD: %
- SGS_EOP_NEGATE: - (unary, uses only
A
)
sgs_IncDec [function]
void sgs_IncDec( sgs_Context* C, sgs_Variable* out, sgs_Variable* A, int inc )
Increment or decrement the specified variable A
to the output out
.
This function prints errors, exactly like VM would (internally there are the same functions).
- If inc is non-zero, variable is incremented; otherwise it is decremented.
sgs_Compare [function]
int sgs_Compare( sgs_Context* C, sgs_Variable* v1, sgs_Variable* v2 )
Return the difference between variables, as int -1/0/1.
sgs_EqualTypes [function]
SGSBOOL sgs_EqualTypes( sgs_Variable* v1, sgs_Variable* v2 )
Return if types of both variables are exactly equal.
- Both type variables and interface pointers (only if both variables are objects) are checked for equality.
sgs_Get*** [functions]
sgs_Bool sgs_GetBool( sgs_Context* C, sgs_StkIdx item )
sgs_Int sgs_GetInt( sgs_Context* C, sgs_StkIdx item )
sgs_Real sgs_GetReal( sgs_Context* C, sgs_StkIdx item )
void* sgs_GetPtr( sgs_Context* C, sgs_StkIdx item )
Return an item from the current stack frame, converted to the specified type.
sgs_Bool sgs_GetBoolP( sgs_Context* C, sgs_Variable* var )
sgs_Int sgs_GetIntP( sgs_Context* C, sgs_Variable* var )
sgs_Real sgs_GetRealP( sgs_Context* C, sgs_Variable* var )
void* sgs_GetPtrP( sgs_Context* C, sgs_Variable* var )
Return the value of the specified variable, converted to the specified type.
- If
item
is out of bounds, 0 is returned.
sgs_To*** [functions]
sgs_Bool sgs_ToBool( sgs_Context* C, sgs_StkIdx item )
sgs_Int sgs_ToInt( sgs_Context* C, sgs_StkIdx item )
sgs_Real sgs_ToReal( sgs_Context* C, sgs_StkIdx item )
void* sgs_ToPtr( sgs_Context* C, sgs_StkIdx item )
Return an item from the current stack frame, converted in-place to the specified type.
sgs_Bool sgs_ToBoolP( sgs_Context* C, sgs_Variable* var )
sgs_Int sgs_ToIntP( sgs_Context* C, sgs_Variable* var )
sgs_Real sgs_ToRealP( sgs_Context* C, sgs_Variable* var )
void* sgs_GetPtrP( sgs_Context* C, sgs_Variable* var )
Return the value of the specified variable, converted in-place to the specified type.
- In ***P functions previous variable is properly released before conversion takes place and reacquired afterwards.
- In-place conversion means that if the function succeeds, the variable will have the requested type.
sgs_ToStringBuf(Fast)(P) [functions]
char* sgs_ToStringBuf( sgs_Context* C, sgs_StkIdx item, sgs_SizeVal* outsize )
char* sgs_ToStringBufFast( sgs_Context* C, sgs_StkIdx item, sgs_SizeVal* outsize )
Return an item from the current stack frame, converted in-place to string.
char* sgs_ToStringBufP( sgs_Context* C, sgs_Variable* var, sgs_SizeVal* outsize )
char* sgs_ToStringBufFastP( sgs_Context* C, sgs_Variable* var, sgs_SizeVal* outsize )
Return the value of the specified variable, converted in-place to string.
- In ***P functions previous variable is properly released before conversion takes place and reacquired afterwards.
- If
item
is out of bounds or conversion fails, NULL is returned.
- The 'fast' version uses type name conversion on object, instead of string conversion - this is to avoid recursion while generating a short description about object contents.
- Length of string is returned to the value that
outsize
points to.
sgs_ToString(Fast)(P) [function aliases]
char* sgs_ToString( sgs_Context* C, sgs_StkIdx item )
char* sgs_ToStringFast( sgs_Context* C, sgs_StkIdx item )
Return an item from the current stack frame, converted in-place to string.
char* sgs_ToStringP( sgs_Context* C, sgs_Variable* var )
char* sgs_ToStringFastP( sgs_Context* C, sgs_Variable* var )
Return the value of the specified variable, converted in-place to string.
- In ***P functions previous variable is properly released before conversion takes place and reacquired afterwards.
- These are aliases of sgs_ToStringBuf(Fast)(P) with the third argument set to NULL.
sgs_RegisterType [function]
SGSBOOL sgs_RegisterType( sgs_Context* C, const char* name, sgs_ObjInterface* iface )
Register a type interface by mapping it to a name.
sgs_UnregisterType [function]
SGSBOOL sgs_UnregisterType( sgs_Context* C, const char* name )
Unregister a type interface by its name.
sgs_FindType [function]
sgs_ObjInterface* sgs_FindType( sgs_Context* C, const char* name )
Finds the type interface that is mapped to the specified name or returns NULL if that type name cannot be found.
sgs_PushInterface [function]
SGSONE sgs_PushInterface( sgs_Context* C, sgs_CFunc igfn )
Push a cached/generated object.
- If object is not in cache, it is generated from the specified function.
sgs_InitInterface [function]
void sgs_InitInterface( sgs_Context* C, sgs_Variable* var, sgs_CFunc igfn )
Initialize a variable to a cached/generated object.
- If object is not in cache, it is generated from the specified function.
sgs_IsObject(P) [functions]
SGSBOOL sgs_IsObject( sgs_Context* C, sgs_StkIdx item, sgs_ObjInterface* iface )
Returns whether the specified stack item item
is an object with the interface pointer iface
.
- If
item
is out of bounds or not an object or doesn't have the specified interface, 0 is returned.
SGSBOOL sgs_IsObjectP( sgs_Context* C, sgs_Variable* var, sgs_ObjInterface* iface )
Returns whether the specified variable var
is an object with the interface pointer iface
.
sgs_IsType(P) [function aliases]
SGSBOOL sgs_IsType( sgs_Context* C, sgs_StkIdx item, const char* type )
Returns whether the specified stack item item
is an object of the specified type.
- Alias of
sgs_IsObject( C, item, sgs_FindType( C, type ) )
.
SGSBOOL sgs_IsTypeP( sgs_Context* C, sgs_Variable* var, const char* type )
Returns whether the specified variable var
is an object of the specified type.
- Alias of
sgs_IsObjectP( C, var, sgs_FindType( C, type ) )
.
sgs_IsCallable(P) [functions]
SGSBOOL sgs_IsCallable( sgs_Context* C, sgs_StkIdx item )
Returns whether the specified stack item item
is callable.
- If
item
is out of bounds, 0 is returned.
SGSBOOL sgs_IsCallableP( sgs_Variable* var )
Returns whether the specified variable var
is callable.
- Callable variables are either SGS functions or C functions or objects with the CALL interface implemented.
sgs_IsNumericString [function]
SGSBOOL sgs_IsNumericString( const char* str, sgs_SizeVal size )
Checks if the string is convertible to an integer/real.
- More info at @<Numeric string parsing rules>.
sgs_Parse*** [functions]
SGSBOOL sgs_ParseBool( sgs_Context* C, sgs_StkIdx item, sgs_Bool* out )
SGSBOOL sgs_ParseInt( sgs_Context* C, sgs_StkIdx item, sgs_Int* out )
SGSBOOL sgs_ParseReal( sgs_Context* C, sgs_StkIdx item, sgs_Real* out )
SGSBOOL sgs_ParseString( sgs_Context* C, sgs_StkIdx item, char** out, sgs_SizeVal* size )
SGSBOOL sgs_ParseObjectPtr( sgs_Context* C, sgs_StkIdx item, sgs_ObjInterface* iface, sgs_VarObj** out, int strict )
SGSBOOL sgs_ParsePtr( sgs_Context* C, sgs_StkIdx item, void** out )
Attempts to parse the specified item of the current stack frame, returning whether parsing was successful.
SGSBOOL sgs_ParseStringP( sgs_Context* C, sgs_Variable* var, char** out, sgs_SizeVal* size )
Attempts to parse the specified variable, returning whether parsing was successful.
- The parsing rules:
- for
sgs_ParsePtr
, unlike every other parsing function, only null/ptr types are considered valid;
- for
sgs_ParseObjectPtr
, only objects with the specified interface iface
are valid unless strict = 0, then null
is valid too;
- if
item
is out of bounds, fail;
- if item has the type
null
, func
or cfunc
, fail;
- if item is of
string
type and bool
is requested, fail;
- if item is of
string
type and int
/real
is requested, try to convert;
- everything else succeeds.
sgs_Global*** [functions]
sgs_Bool sgs_GlobalBool( sgs_Context* C, const char* name )
sgs_Int sgs_GlobalInt( sgs_Context* C, const char* name )
sgs_Real sgs_GlobalReal( sgs_Context* C, const char* name )
char* sgs_GlobalStringBuf( sgs_Context* C, const char* name, sgs_SizeVal* outsize )
char* sgs_GlobalString( sgs_Context* C, const char* name )
Retrieve a global variable, converted to the specified type.
sgs_GlobalString[Buf] pushes the variable on the stack to be able to reliably return the string pointer
- If variable is not found, 0 / NULL is returned.
- If string cannot be parsed (variable is null or a function), NULL is returned.
- This is done because converting these values does not yield useful results with global variables.
sgs_PushIterator [functions]
SGSBOOL sgs_PushIterator( sgs_Context* C, sgs_Variable var )
Create and push an iterator from the specified variable, return if successful.
- On failure, null is pushed.
- See Iterator system for more info about iterators.
sgs_GetIterator [functions]
SGSBOOL sgs_GetIterator( sgs_Context* C, sgs_Variable var, sgs_Variable* out )
Create an iterator from the specified variable, return if successful.
- On failure, out receives a null variable.
- See Iterator system for more info about iterators.
sgs_IterAdvance [functions]
SGSBOOL sgs_IterAdvance( sgs_Context* C, sgs_Variable var )
Advance the iterator to the next position, returning if the current position is still in range.
- This is the way it's expected to be usually called:
while( sgs_IterAdvance( C, var ) ){ ... sgs_IterPushData ... }
.
- See Iterator system for more info about iterators.
sgs_IterPushData [functions]
void sgs_IterPushData( sgs_Context* C, sgs_Variable var, int key, int value )
Load and push data associated with the current position.
key
and value
are booleans that specify if the respective value should be returned.
- First the key is pushed, then the value.
- If neither
key
nor value
are expected, the call succeeds and doesn't push anything.
- See Iterator system for more info about iterators.
sgs_IterGetData [functions]
void sgs_IterGetData( sgs_Context* C, sgs_Variable var, sgs_Variable* key, sgs_Variable* value )
Load data associated with the current position.
key
and value
are variables where the data is written if the pointer is not NULL.
- If neither
key
nor value
are expected, the call succeeds and doesn't retrieve anything.
- See Iterator system for more info about iterators.
sgs_IsArray [function]
SGSBOOL sgs_IsArray( sgs_Variable var )
Return if variable is of array
type.
sgs_IsDict [function]
SGSBOOL sgs_IsDict( sgs_Variable var )
Return if variable is of dict
type.
sgs_IsMap [function]
SGSBOOL sgs_IsMap( sgs_Variable var )
Return if variable is of map
type.
sgs_ArraySize [functions]
sgs_SizeVal sgs_ArraySize( sgs_Variable var )
Check if the specified stack item or variable is an array and return its size or -1 if variable is not an array.
sgs_ArrayPush [function]
void sgs_ArrayPush( sgs_Context* C, sgs_Variable var, sgs_StkIdx count )
Push the last count
variables on stack to the end of the array var
, then pop them from the stack.
sgs_ArrayPop [function]
void sgs_ArrayPop( sgs_Context* C, sgs_Variable var, sgs_StkIdx count, SGSBOOL ret )
Pop the last count
variables off the end of the array var
, optionally return them.
- If
ret
!= 0, variables are pushed on the stack before removal.
sgs_ArrayErase [function]
void sgs_ArrayErase( sgs_Context* C, sgs_Variable var, sgs_StkIdx at, sgs_StkIdx count )
Remove the specified variable range [`at`,`at`+`count`) from array var
.
sgs_ArrayFind [function]
sgs_SizeVal sgs_ArrayFind( sgs_Context* C, sgs_Variable var, sgs_Variable what )
Return the first position of item what
in array var
or -1 if item was not found.
sgs_ArrayRemove [function]
sgs_SizeVal sgs_ArrayRemove( sgs_Context* C, sgs_Variable var, sgs_Variable what, SGSBOOL all )
Remove first/all occurrence(s) of what
in array var
.
sgs_Unset [function]
SGSBOOL sgs_Unset( sgs_Context* C, sgs_Variable var, sgs_Variable key )
Unset the specified index of the given dict
/map
variable, return if successful.
sgs_StackSize [function]
sgs_StkIdx sgs_StackSize( sgs_Context* C )
Return the size of the current stack frame.
sgs_SetStackSize [function]
void sgs_SetStackSize( sgs_Context* C, sgs_StkIdx size )
Resizes the current stack frame to fit the specified amount of items.
- If the current number of items is less than needed, stack is null-variable-padded at the end.
- If the current number of items is more than needed, the unnecessary amount of items is popped.
sgs_SetDeltaSize [function]
void sgs_SetDeltaSize( sgs_Context* C, sgs_StkIdx diff )
Resizes the current stack frame to the [size+diff] size.
- If diff is positive, stack is null-variable-padded at the end.
- If diff is negative, the specified number of items are popped.
- If amount of items to be popped is bigger than size, function fails.
sgs_AdjustStack [function]
SGSRESULT sgs_AdjustStack( sgs_Context* C, int expected, int ret )
Resizes the current stack frame by expected
- ret
, returns ret
Used with sgs_Eval** functions to create their sgs_Exec** counterparts.
sgs_AbsIndex [function]
sgs_StkIdx sgs_AbsIndex( sgs_Context* C, sgs_StkIdx item )
Attempt to convert a negative stack index into a positive one.
This function can still return negative values - make sure that valid values are passed to it or check if the returned value is in the range [ 0; stack_frame_size ).
sgs_IsValidIndex [function]
SGSBOOL sgs_IsValidIndex( sgs_Context* C, sgs_StkIdx item )
Return whether the specified stack index points to an item in the current stack frame.
- Both positive (first = 0) and negative (last = -1) indices are supported.
sgs_OptStackItem [function]
sgs_Variable sgs_OptStackItem( sgs_Context* C, sgs_StkIdx item )
Returns a non-owned copy of a variable on stack or null if the index is invalid.
- See sgs_StackItem for details on behavior, only difference is that
null
is returned when an invalid stack index is passed.
- This function is useful for the implementation of "Parse"/"ArgCheck" functions which are required never to throw errors by convention.
sgs_StackItem [function]
sgs_Variable sgs_StackItem( sgs_Context* C, sgs_StkIdx item )
Returns a non-owned copy of a variable on stack.
Avoid using this function with functions that can alter the stack and remove the source item.
This function does not acquire the variable and thus can't be used in functions that modify it without previously taking ownership of it, such as sgs_Assign or sgs_To***; to acquire variable on retrieval, see sgs_GetStackItem or sgs_Acquire.
- This function can be used to pass arguments from stack in most simple operations.
sgs_GetStackItem [function]
SGSBOOL sgs_GetStackItem( sgs_Context* C, sgs_StkIdx item, sgs_Variable* out )
Write the data of the specified stack variable and increments its reference count if the index is valid.
- Function returns whether the stack index was valid.
sgs_SetStackItem [function]
void sgs_SetStackItem( sgs_Context* C, sgs_StkIdx item, sgs_Variable val )
Copy the specified variable to the specified position in stack.
sgs_ItemType [function]
uint32_t sgs_ItemType( sgs_Context* C, sgs_StkIdx item )
Return the type ID of the specified stack item.
- Return value will be equal to one of the SGS_VT_* macro.
- If index is invalid, return value will be 0 (SGS_VT_NULL).
sgs_Acquire(Array) [function]
void sgs_Acquire( sgs_Context* C, sgs_Variable* var )
void sgs_AcquireArray( sgs_Context* C, sgs_Variable* var, sgs_SizeVal count )
Increment the reference count of the specified variables (if they count references).
sgs_Release(Array) [function]
void sgs_Release( sgs_Context* C, sgs_Variable* var )
void sgs_ReleaseArray( sgs_Context* C, sgs_Variable* var, sgs_SizeVal count )
Decrement and possibly deallocate the reference count of the specified variables (if they count references).
- Works differently while GC is running: doesn't delete objects of same context in destructor.
sgs_GCMark(Array) [function]
void sgs_GCMark( sgs_Context* C, sgs_Variable* var )
void sgs_GCMarkArray( sgs_Context* C, sgs_Variable* var, sgs_SizeVal count )
Mark the specified variables as reachable for the garbage collector.
- To be called in the GCMARK object callback.
sgs_ObjAcquire [function]
void sgs_ObjAcquire( sgs_Context* C, sgs_VarObj* obj )
Increment reference count of the specified object.
sgs_ObjRelease [function]
void sgs_ObjRelease( sgs_Context* C, sgs_VarObj* obj )
Decrement reference count and possibly delete the specified object.
sgs_ObjGCMark [function]
void sgs_ObjGCMark( sgs_Context* C, sgs_VarObj* obj )
Mark the specified object as accessible to avoid its destruction by the Garbage collection system.
- To be called in the GCMARK object callback.
sgs_ObjAssign [function]
void sgs_ObjAssign( sgs_Context* C, sgs_VarObj** dest, sgs_VarObj* src )
Assign object pointer, handling acquisition/release properly.
*dest
and src
must be NULL or valid pointers to objects.
- If
src
is not NULL, it is acquired.
- If
*dest
is not NULL, it is released.
- After the function call,
*dest
is equal to src
.
sgs_ObjCallDtor [function]
void sgs_ObjCallDtor( sgs_Context* C, sgs_VarObj* obj )
Call the DESTRUCT object callback.
- This function is to be used in cases where objects are owned by a single entity but have handles all over the place - calling this function would not delete the object but would free its resources, thus leaving handles intact, with their states updated.
sgs_ObjSetMetaObj [function]
void sgs_ObjSetMetaObj( sgs_Context* C, sgs_VarObj* obj, sgs_VarObj* metaobj )
Set metaobj
as the meta-object of object obj
.
obj
must always point to an object, metaobj
can be NULL.
sgs_ObjGetMetaObj [function]
sgs_VarObj* sgs_ObjGetMetaObj( sgs_VarObj* obj )
Retrieve meta-object of an object.
sgs_ObjSetMetaMethodEnable [function]
void sgs_ObjSetMetaMethodEnable( sgs_VarObj* obj, SGSBOOL enable )
Enable or disable metamethod support for an object.
sgs_ObjGetMetaMethodEnable [function]
SGSBOOL sgs_ObjGetMetaMethodEnable( sgs_VarObj* obj )
Check if metamethod support is enabled for an object.
sgs_GetStringPtr(P) [functions]
char* sgs_GetStringPtr( sgs_Context* C, sgs_StkIdx item )
Return the string data pointer of the specified stack item.
char* sgs_GetStringPtrP( sgs_Context* C, sgs_Variable* var )
Return the string data pointer of the specified variable.
- If item is out of bounds or not a string, NULL will be returned and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_GetStringSize(P) [functions]
sgs_SizeVal sgs_GetStringSize( sgs_Context* C, sgs_StkIdx item )
Return the string size of the specified stack item.
sgs_SizeVal sgs_GetStringSizeP( sgs_Context* C, sgs_Variable* var )
Return the string size of the specified variable.
- If item is out of bounds or not a string, 0 will be returned and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_GetObjectStruct(P) [functions]
sgs_VarObj* sgs_GetObjectStruct( sgs_Context* C, sgs_StkIdx item )
Return the object's internal data pointer of the specified stack item.
sgs_VarObj* sgs_GetObjectStructP( sgs_Context* C, sgs_Variable* var )
Return the object's internal data pointer of the specified variable.
- If item is out of bounds or not an object, NULL will be returned and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_GetObjectData(P) [functions]
void* sgs_GetObjectData( sgs_Context* C, sgs_StkIdx item )
Return the object data pointer of the specified stack item.
void* sgs_GetObjectDataP( sgs_Context* C, sgs_Variable* var )
Return the object data pointer of the specified variable.
- If item is out of bounds or not an object, NULL will be returned and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_GetObjectIface(P) [functions]
sgs_ObjInterface* sgs_GetObjectIface( sgs_Context* C, sgs_StkIdx item )
Return the object interface pointer of the specified stack item.
sgs_ObjInterface* sgs_GetObjectIfaceP( sgs_Context* C, sgs_Variable* var )
Return the object interface pointer of the specified variable.
- If item is out of bounds or not an object, NULL will be returned and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_SetObjectData(P) [functions]
void sgs_SetObjectData( sgs_Context* C, sgs_StkIdx item, void* data )
Set the object data pointer of the specified stack item.
void sgs_SetObjectDataP( sgs_Context* C, sgs_Variable* var, void* data )
Set the object data pointer of the specified variable.
- If item is out of bounds or not an object, pointer will not be set, and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_SetObjectIface(P) [functions]
void sgs_SetObjectIface( sgs_Context* C, sgs_StkIdx item, sgs_ObjInterface* iface )
Set the object interface pointer of the specified stack item.
void sgs_SetObjectIfaceP( sgs_Context* C, sgs_Variable* var, sgs_ObjInterface* iface )
Set the object interface pointer of the specified variable.
- If item is out of bounds or not an object, pointer will not be set, and ...
- in a debug build, one of the BreakIf macros will go off and stop the action.
sgs_StdOutputFunc [function]
void sgs_StdOutputFunc( void* userdata, sgs_Context* C, const void* ptr, size_t size )
Standard output function assumes userdata to be FILE* type and writes the passed buffer to it.
sgs_Get(Err)OutputFunc [function]
void sgs_GetOutputFunc( sgs_Context* C, sgs_OutputFunc* outfunc, void** outuserdata )
void sgs_GetErrOutputFunc( sgs_Context* C, sgs_OutputFunc* outfunc, void** outuserdata )
Retrieves the currently set (error) output function.
- Validity of the returned function pointer is assured as long as engine internals are not touched anywhere.
sgs_Set(Err)OutputFunc [function]
void sgs_SetOutputFunc( sgs_Context* C, sgs_OutputFunc func, void* userdata )
void sgs_SetErrOutputFunc( sgs_Context* C, sgs_OutputFunc func, void* userdata )
Sets the function used in 'print'/'errprint' function family.
- Default output function can be set by passing SGSOUTPUTFN_DEFAULT to func with userdata as FILE*, allocated using the same C runtime that SGScript uses.
- Default implementation - sgs_StdOutputFunc - copies data to FILE* stream, specified in userdata.
- To use this function with non-default (stderr) stream, pass it explicity due to the possibility of having different runtime libraries linked to different binaries.
sgs_(Err)Write [function]
void sgs_Write( sgs_Context* C, const void* ptr, sgs_SizeVal size )
void sgs_ErrWrite( sgs_Context* C, const void* ptr, sgs_SizeVal size )
Passes the specified data to the (error) output function.
- The default output function prints the data to the specified FILE* stream (stdout/stderr by default).
sgs_(Err)WriteStr [function alias]
void sgs_WriteStr( sgs_Context* C, const char* str )
void sgs_ErrWriteStr( sgs_Context* C, const char* str )
Passes the specified string to the (error) output function.
- Alias to
sgs_(Err)Write( C, str, SGS_STRINGLENGTHFUNC( str ) )
.
sgs_(Err)Writef [function]
void sgs_Writef( sgs_Context* C, const char* what, ... )
void sgs_ErrWritef( sgs_Context* C, const char* what, ... )
Passes the arguments through a `vsprintf`-like function to expand the data and passes it to the specified output function.
sgs_StdMsgFunc(_NoAbort) [functions]
void sgs_StdMsgFunc( void* ctx, sgs_Context* C, int type, const char* msg )
void sgs_StdMsgFunc_NoAbort( void* ctx, sgs_Context* C, int type, const char* msg )
Writes error info with sgs_WriteErrorInfo to userdata with fprintf
, assuming userdata is FILE*
.
sgs_GetMsgFunc [function]
void sgs_GetMsgFunc( sgs_Context* C, sgs_MsgFunc* outfunc, void** outuserdata )
Retrieves the currently set messaging function.
- Info about the system is at the Messaging system page.
- Validity of the returned function pointer is assured as long as engine internals are not touched anywhere.
sgs_SetMsgFunc [function]
void sgs_SetMsgFunc( sgs_Context* C, sgs_MsgFunc func, void* userdata )
Sets the function that handles and prints messages (more commonly, warnings and errors), while still being physically in that context.
- Info about the system is at the Messaging system page.
- Both subtypes of the default messaging function can be set by passing these flags for
func
:
- 'SGSMSGFN_DEFAULT' - default behavior (write stack frame, write error, abort on SGS_ERROR);
- 'SGSMSGFN_DEFAULT_NOABORT' - default behavior without the abort-on-errors feature;
- Default implementations - sgs_StdMsgFunc(_NoAbort) passes error and stack trace to @sgs_ErrWrite<sgs_(Err)Write).
sgs_GetScriptFSFunc [function]
SGSBOOL sgs_GetScriptFSFunc( sgs_Context* C, sgs_ScriptFSFunc* outf, void** outc )
Retrieves the currently set virtual file system function.
sgs_SetScriptFSFunc [function]
void sgs_SetScriptFSFunc( sgs_Context* C, sgs_ScriptFSFunc func, void* ctx ).
Sets the virtual file system function.
- Default VFS function - sgs_StdScriptFSFunc.
- These operations have to be implemented by the callback:
- SGS_SFS_FILE_EXISTS: check if file
sgs_ScriptFSData::filename
exists;
- SGS_SFS_FILE_OPEN: open the file
sgs_ScriptFSData::filename
for reading;
- SGS_SFS_FILE_READ: read
sgs_ScriptFSData::size
bytes from beginning to sgs_ScriptFSData::output
;
- SGS_SFS_FILE_CLOSE: close the currently opened file;
- File handle can be stored in
sgs_ScriptFSData::userhandle
.
sgs_StdScriptFSFunc [function]
SGSRESULT sgs_StdScriptFSFunc( void* ctx, sgs_Context* C, int op, sgs_ScriptFSData* data )
Implements virtual file system using real file system.
sgs_Msg [function]
SGSZERO sgs_Msg( sgs_Context* C, int type, const char* what, ... )
Prepares and prints the error specified.
- Info about the system is at the Messaging system page.
type
is the output code (SGS_WARNING, SGS_ERROR etc.).
what
is the error text;
- additional function name prefix can be specified with sgs_FuncName or the SGSFN/SGSBASEFN macros.
what
, the function name prefix (if set) and the variable arguments are passed to a `vsprintf`-like function so printf
syntax rules apply.
- Function always returns 0 to be compatible with most error handling cases in C functions: "return sgs_Msg( ... );".
sgs_WriteErrorInfo [function]
void sgs_WriteErrorInfo( sgs_Context* C, int flags, sgs_ErrorOutputFunc func, void* ctx, int type, const char* msg )
Writes error info using the error output function specified.
The error output function type has the following definition:
typedef int (*sgs_ErrorOutputFunc) ( void*, const char*, ... );
- Error output function has the same type as
fprintf
and sgs_(Err)Writef:
type
and msg
should be passed from the messaging callback - they are the same type number / error message.
flags
should be one of SGS_ERRORINFO_STACK, SGS_ERRORINFO_ERROR, SGS_ERRORINFO_FULL:
- SGS_ERRORINFO_STACK only writes the stack frame;
- SGS_ERRORINFO_ERROR only writes the error message;
- SGS_ERRORINFO_FULL writes both.
sgs_PushErrorInfo [function]
void sgs_PushErrorInfo( sgs_Context* C, int flags, int type, const char* msg )
Pushes a string generated from error info.
type
and msg
should be passed from the messaging callback - they are the same type number / error message.
flags
should be one of SGS_ERRORINFO_STACK, SGS_ERRORINFO_ERROR, SGS_ERRORINFO_FULL:
- SGS_ERRORINFO_STACK only writes the stack frame;
- SGS_ERRORINFO_ERROR only writes the error message;
- SGS_ERRORINFO_FULL writes both.
sgs_HasFuncName [function]
int sgs_HasFuncName( sgs_Context* C )
Checks if the currently executed function (last stack frame) has a name literal set.
sgs_FuncName [function]
void sgs_FuncName( sgs_Context* C, const char* fnliteral )
Sets the function name string for the currently executed function (last stack frame).
- The argument is expected to stay alive for the duration of the function call;
- this makes string literals safe for the call, everything else should be avoided.
SGSFN [function alias]
void SGSFN( const char* fnliteral )
Sets the function name string, more info at sgs_FuncName.
- Alias for
sgs_FuncName( <implicit> C, fnliteral )
.
SGSBASEFN [function alias]
void SGSBASEFN( const char* fnliteral )
Sets the function name string if it hasn't already been set for the function.
- Alias for
if( !sgs_HasFuncName( <implicit> C ) ) sgs_FuncName( <implicit> C, x )
.
sgs_SetHookFunc [function]
void sgs_SetHookFunc( sgs_Context* C, sgs_HookFunc func, void* ctx )
Sets the hook function and user data pointer.
- Hook function is called on function entry, exit and instruction change events.
- Setting a new hook function disables the one that was set before (if any).
sgs_GetHookFunc [function]
SGSBOOL sgs_GetHookFunc( sgs_Context* C, sgs_HookFunc* outfunc, void** outctx )
Writes the hook function and user data pointer that was set (if any), returns whether anything was written.
sgs_DefaultMemFunc [function]
void* sgs_DefaultMemFunc( void* userdata, void* ptr, size_t size )
The default memory allocation function.
Expected behavior: same as for sgs_Memory.
Sample implementation (same as in sgscript.h):
if( ptr && size ) return realloc( ptr, size );
else if( size ) return malloc( size );
if( ptr ) free( ptr );
return NULL;
sgs_Memory [function]
void sgs_Memory( sgs_Context* C, void* ptr, size_t size )
Allocates and frees memory, as specified in arguments.
- There are four possible cases that are handled by the function:
ptr
!= NULL, size
!= 0: ptr
is reallocated with new size, keeping as much data as possible, new block of memory is returned;
ptr
!= NULL, size
== 0: ptr
is freed, NULL is returned;
ptr
== NULL, size
!= 0: a new block of memory is allocated and returned;
ptr
== NULL, size
== 0: nothing is done, NULL is returned.
Memory allocation macros [macros]
Memory allocation macros
These macros allow slightly simplified handling of memory.
sgs_Malloc( C, size )
: allocates the memory (alias to sgs_Memory( C, NULL, size )
).
sgs_Free( C, ptr )
: frees the memory (alias to sgs_Memory( C, ptr, 0 )
).
- sgs_Realloc: alias to sgs_Memory.
- The following macros expect that the variable sgs_Context* C is in the scope:
sgs_Alloc( what )
: allocates enough memory to fit the specified type what
;
sgs_Alloc_n( what, n )
: allocates enough memory to fit n
instances of the specified type what
;
sgs_Alloc_a( what, app )
: allocates enough memory to fit the specified type what
and app
more bytes;
sgs_Dealloc( ptr )
: frees the memory.
- All of these functions, including sgs_Memory, work on the same heap, thus they are interchangeable.
sgs_CodeString [function]
const char* sgs_CodeString( int type, int val )
Returns a string for the enumeration type
value val
.
- There are 4 enumerations to have value names returned for:
- SGS_CODE_ER: error codes (SGS_ERROR, SGS_WARNING, ...);
- SGS_CODE_VT: variable types (SGS_VT_BOOL, SGS_VT_FUNC, ...);
- SGS_CODE_OP: VM instructions (SGS_SI_PUSH, SGS_SI_FORPREP, ... [internal]).
sgs_Abort [function]
SGSBOOL sgs_Abort( sgs_Context* C )
Stops execution of current SGS functions up to the last C function in the stack, excluding the current.
- Function fails if there was nothing to abort - last or next to last function in the stack was not a SGS function.
sgs_Stat [function]
ptrdiff_t sgs_Stat( sgs_Context* C, int type )
Returns or prints information about state of SGScript VM.
- The following
type
values are supported:
- SGS_STAT_VERSION: returns the version number of the VM;
- SGS_STAT_STATECOUNT: returns the number of execution states created in the VM;
- SGS_STAT_OBJCOUNT: returns the number of objects created in the VM;
- SGS_STAT_MEMSIZE: returns the number of bytes allocated through this SGScript context;
- SGS_STAT_NUMALLOCS: returns the number of memory allocations (incremented on each alloc/realloc);
- SGS_STAT_NUMFREES: returns the number of memory frees (incremented on each free/realloc);
- SGS_STAT_NUMBLOCKS: number of memory blocks currently allocated (incremented on alloc, decremented on free);
- SGS_STAT_DUMP_STACK: prints all of the variables in the stack;
- SGS_STAT_DUMP_GLOBALS: prints all variables in the global dictionary;
- SGS_STAT_DUMP_OBJECTS: prints all objects in the context;
- SGS_STAT_DUMP_FRAMES: prints all functions in the call stack;
- SGS_STAT_DUMP_STATS: dump some info about memory and objects;
- SGS_STAT_DUMP_SYMBOLS: dump the list of registered symbols;
- SGS_STAT_XDUMP_STACK: verbosely dumps all of the variables in the stack (extended info, may be much longer).
- Tips:
- compare return value of SGS_STAT_VERSION against SGS_VERSION_INT if using multiple versions should be supported / prevented.
sgs_Cntl [function]
int32_t sgs_Cntl( sgs_Context* C, int what, int32_t val )
Modifies the state of the VM or returns info about it.
- The following
what
values are supported:
- SGS_CNTL_STATE: sets the new compilation state from
val
, returns the previous value;
- SGS_CNTL_GET_STATE: returns the currently set compilation state;
- SGS_CNTL_MINLEV: sets the new minimum error level from
val
, returns the previous value;
- SGS_CNTL_GET_MINLEV: returns the currently set minimum error level;
- SGS_CNTL_ERRNO: if
val
is true, sets internal errno to 0, otherwise - to errno
, returns the previous value;
- SGS_CNTL_SET_ERRNO: sets internal errno to
val
, returns the previous value;
- SGS_CNTL_GET_ERRNO: returns the currently set internal errno;
- SGS_CNTL_ERRSUP: sets error suppression lock count to
val
, returns the previous value;
- SGS_CNTL_GET_ERRSUP: returns the currently set error suppression lock count for the last stack frame;
- SGS_CNTL_NUMRETVALS: returns the real number of returned values from last function call;
- SGS_CNTL_GET_PAUSED: returns whether the execution state is suspended;
- SGS_CNTL_GET_ABORT: returns whether last function call was aborted;
- Everything else does nothing and returns 0.
sgs_StackFrameInfo [function]
void sgs_StackFrameInfo( sgs_Context* C, sgs_StackFrame* frame, const char** name, const char** file, int* line )
Helps to retrieve file name, function name and line number of the specified stack frame.
- Each non-NULL pointer is initialized with valid data; even if it may not be very helpful (for example, all anonymous functions get the same name - "<anonymous function>").
sgs_GetFramePtr [function]
sgs_StackFrame* sgs_GetFramePtr( sgs_Context* C, sgs_StackFrame* from, int bwd )
Returns a call stack frame pointer.
- If
bwd
is 0, request a pointer for forward iteration:
- if
from
is NULL, return pointer to first frame, otherwise return the frame after from
(or NULL if it doesn't exist).
- If
bwd
is not 0, request a pointer for reverse iteration:
- if
from
is NULL, return pointer to last frame, otherwise return the frame before from
(or NULL if it doesn't exist).
sgs_Errno [function alias]
int sgs_Errno( sgs_Context* C, int clear )
Copies errno to internal errno value if clear
is not 0, otherwise internal errno value is set to 0, returns clear
.
- Used with a boolean expression and chaining to set errno if the expression returned false, like this:
sgs_PushBool( C, sgs_Errno( C, rename( a, b ) == 0 ) )
sgs_SetErrno [function alias]
int sgs_SetErrno( sgs_Context* C, int err )
Sets a specific value err
to the internal errno variable.
- Alias to
sgs_Cntl( C, SGS_CNTL_SET_ERRNO, err )
.
sgs_GetLastErrno [function alias]
int sgs_GetLastErrno( sgs_Context* C )
Returns the currently set internal errno variable.
- Alias to
sgs_Cntl( C, SGS_CNTL_GET_ERRNO, 0 )
.
sgs_PushStringAlloc [function]
char* sgs_PushStringAlloc( sgs_Context* C, sgs_SizeVal size )
Push an uninitialized string buffer, returns pointer to buffer.
Created string is a valid resource in terms of acquisition/release but not hashed and internalized yet, thus it cannot be used in indexing/comparison functions until it's finalized, see sgs_FinalizeStringAlloc(P).
- It is safe to write string data (to pointer retrieved from sgs_GetStringPtr(P) function) up until finalization.
sgs_InitStringAlloc [function]
char* sgs_InitStringAlloc( sgs_Context* C, sgs_Variable* var, sgs_SizeVal size )
Set an uninitialized string buffer to a variable, returns pointer to buffer.
Created string is a valid resource in terms of acquisition/release but not hashed and internalized yet, thus it cannot be used in indexing/comparison functions until it's finalized, see sgs_FinalizeStringAlloc(P).
- It is safe to write string data (to pointer retrieved from sgs_GetStringPtr(P) function) up until finalization.
sgs_FinalizeStringAlloc(P) [functions]
void sgs_FinalizeStringAlloc( sgs_Context* C, sgs_StkIdx item )
void sgs_FinalizeStringAllocP( sgs_Context* C, sgs_Variable* var )
Finalize (prepare for usage) an uninitialized string buffer.
- Preparations include string hashing and internalization (release of owned copy in favor of exact same string in string table).
- After using these functions, string data cannot be modified.
C Functions
A C function has the type int CFunc( sgs_Context* )
. It receives the context that called it and must return the number of return values pushed on stack.
Conventions
There are no forced courses of action beyond this point. However, to simplify development, some conventions were established and are used throughout the standard library and are suggested to follow.
General structure
- the usage of SGS_CTX in argument list is suggested to enable the use of certain macros that assume the availability of
sgs_Context* C
- there are no restrictions on function names, however it helps to mark the scripting engine functions with a common prefix and if they wrap a native function, including the name of the wrapped function is suggested
Argument loading
- prefer using sgs_LoadArgs, followed by sgs_LoadArgsExt, followed by the sgs_Parse***/sgs_Is***/sgs_ItemType(Ext)/... functions together with ArgError function family for error handling
Error handling
- it is preferred to do most of it at the beginning, before custom allocations (VM stack doesn't count here), where it is possible to just
return sgs_Msg( C, SGS_WARNING, "Error message" )
- SGS_WARNING is for non-fatal errors, SGS_ERROR is for errors that make it impossible to continue (severe, undoubted logical errors fall into this category)
- on error, functions should return nothing or null
A typical function
int sgsfunc_sample( SGS_CTX )
{
sgs_Int num;
char* str;
char* buf;
sgs_SizeVal bufsize;
if( !sgs_LoadArgs( C, "ism", &num, &str, &buf, &bufsize ) )
return 0;
if( bufsize == 0 )
return sgs_Msg( C, SGS_WARNING, "buffer cannot be empty" );
// sgs_Msg always returns 0
// .. do something with the passed arguments ..
// anything can be returned ..
// .. but in this case, we want to say ..
// .. that the action was successful
sgs_PushBool( C, 1 );
return 1;
}
Object interface
Every interface function has the type int ObjCallback ( sgs_Context* C, sgs_VarObj* data, ... )
. Not every of them has to be implemented (none of them are required) but for all non-pointer objects it helps to have at least one of them.
Interface is a structure that contains of an array and 10 function pointers in the following order: destruct, gcmark, getindex, setindex, convert, serialize, dump, getnext, call, expr. This is how interfaces are usually defined in code:
sgs_ObjInterface object_interface[1] =
{{
"object_type_name",
object_destruct, NULL, /* destruct, gcmark */
object_getindex, NULL, /* getindex, setindex */
NULL, NULL, NULL, NULL, /* convert, serialize, dump, getnext */
NULL, NULL /* call, expr */
}};
The interface is defined as an array with size=1 to later be able to use it in code without prepending "&" to the name.
DESTRUCT - destruction callback
When called:
Additional arguments:
None.
Stack frame:
Empty.
Return values:
Non-negative value if successful, negative on error.
Additional notes:
It is important to minimize the possibility of failure here. The system cannot help in any way if memory or ownership states are corrupted.
GETINDEX - index/property retrieval callback
When called:
- On A[B] (index) and A.B (property) reads in SGScript.
- Index/Property/Path function families in the C API.
Additional arguments:
- object argument (see sgs_ObjectArg) -- (0/1) whether this is a property read (1) or index read (0)
Stack frame:
- Item 0 - key variable to be used to find a sub-item.
- Expected to have at least one item on stack after a successful index/property read. The topmost one is used.
Return values:
- Non-negative value if successful, negative on error.
- Use SGS_ENOTFND if the specified index/property was not found.
Additional notes:
It is safe to use conversion functions on the key variable.
SETINDEX - index/property setting callback
When called:
- On A[B] (index) and A.B (property) writes in SGScript.
- Index/Property/Path function families in the C API.
Additional arguments:
- sgs_Variable* key -- key variable to be used to find a sub-item
- sgs_Variable* value -- value variable to be used in setting the value of the sub-item
- object argument (see sgs_ObjectArg) -- (0/1) whether this is a property read (1) or index read (0)
Stack frame:
- Item 0 - key variable to be used to find a sub-item.
- Item 1 - value variable to be used in setting the value of the sub-item.
Return values:
- Non-negative value if successful, negative on error.
- Use SGS_ENOTFND if the specified index/property was not found.
- Use SGS_EINVAL if the given value could not be used.
Additional notes:
It is safe to use conversion functions on both variables.
CONVERT - conversion callback
When called:
Depending on the argument, it is called by different sources:
- type conversion: to*** function families and other conversion triggers (like operators) in SGScript and the Get/To/Parse function families in the C API.
- SGS_CONVOP_CLONE: called on clone / sgs_Clone
- SGS_CONVOP_TOITER: called on foreach / sgs_PushIterator / sgs_GetIterator
Additional arguments:
- int type -- one of SGS_VT_[BOOL|STRING] or SGS_CONVOP_CLONE / SGS_CONVOP_TOITER
Stack frame:
Empty at beginning. Expected to have at least one item on stack after a successful conversion. The topmost one is used.
Depending on the argument, it requires different variable types on stack:
- type conversions require a value of the right type.
- SGS_CONVOP_CLONE should return an exact copy of the same object
- SGS_CONVOP_TOITER should return an object with a GETNEXT callback
Return values:
- Non-negative value if successful, negative on error.
- Use SGS_ENOTSUP if specified conversion is not supported.
Additional notes:
- It should be safe to give the wrong variable type but errors may not be triggered in such cases.
SERIALIZE - serialization callback
When called:
Additional arguments:
None.
Stack frame:
Empty.
Return values:
- Non-negative value if successful, negative on error.
Additional notes:
Callback requires no data but expects that sgs_Serialize / sgs_SerializeObject is successfully called once. In the case of sgs_SerializeObject, the necessary number (equal to argument count, passed to the function) of sgs_Serialize calls must be made before it.
DUMP - debug dump callback
When called:
Additional arguments:
- int maxdepth -- remaining recursion depth of dump to be passed on to sgs_DumpVar calls.
Stack frame:
Empty at beginning. Expected to have at least one item on stack after a successful conversion. The topmost one is used.
Return values:
- Non-negative value if successful, negative on error.
Additional notes:
- Callback expects a string variable on the top of the stack.
- sgs_DumpVar with maxdepth <= 0 returns "...", so it is not necessary to handle such cases beyond passing the parameter.
GCMARK - garbage collector marking callback
When called:
Additional arguments:
None.
Stack frame:
Empty.
Return values:
- Non-negative value if successful, negative on error.
Additional notes:
- Callback expects that sgs_GCMark is called on all of the owned variables.
- It is important to minimize the possibility of failure here. The system cannot help in any way if memory or ownership states are corrupted.
GETNEXT - iterator control callback
When called:
Additional arguments:
- int act -- specifies the actions that should be taken in this call.
- if argument == 0, iterator's position must be increased by one step and the return value must contain whether iterator has not reached end (positive value if so, otherwise - 0) or an error if callback has failed
- otherwise, callback must push the data required (if SGS_GETNEXT_KEY is set, the key, and if SGS_GETNEXT_VALUE is set - the value, in exactly that order)
Stack frame:
Empty at beginning. Expects at least one (if either flag is set, but not both) or two (if both flags are set) variables on success. Key first, value second.
Return values:
- Non-negative value if successful, negative on error.
- if argument == 0, must return whether iterator has not reached end (positive value if so, otherwise - 0)
Additional notes:
None.
CALL - the "function call" callback
When called:
- when an object is used like a function
object_variable( .. )
in SGScript
- Call function family in the C API
Additional arguments:
None.
Stack frame:
Contains all the same things as any C function call would: optional this
variable and optional argument list. Expects at least the returned number of items after the call to be used as return values.
Return values:
- Non-negative value if successful, negative on error.
- On success, the number returned is the number of variables returned by the function.
Additional notes:
None.
EXPR - expression callback
When called:
- On arithmetic operations with the object as one or both operands in SGScript.
- On sgs_ArithOp in the C API.
Additional arguments:
- sgs_Variable* A - the first (left side) operand or the only one in case of SGS_EOP_NEGATE
- sgs_Variable* B - the second (right side) operand or NULL in case of SGS_EOP_NEGATE
- int op - operation type, one of SGS_EOP_[ADD|SUB|MUL|DIV|MOD|COMPARE|NEGATE]
Stack frame:
Empty at beginning. Expects at least one variable on success (the topmost one will be used).
Return values:
- Non-negative value if successful, negative on error.
Additional notes:
- SGS_EOP_COMPARE expects int/real value: >0 if A > B, <0 if A < B, =0 if A = B
The full list of operators triggering the operations:
- SGS_EOP_ADD: binary +, +=
- SGS_EOP_SUB: binary -, -=
- SGS_EOP_MUL: *, *=
- SGS_EOP_DIV: /, /=
- SGS_EOP_MOD: %, %=
- SGS_EOP_COMPARE: <, <=, >, >=, ==, !=, ===, !==
- SGS_EOP_NEGATE: unary -
Interaction with the environment
Most operations are directed towards the scripting engine, that is - environment makes a function call and scripting engine handles it. For everything else, there are callbacks.
Memory allocation
- sgs_MemFunc must be specified in creation of the scripting engine context
- sgs_MemFunc (re)allocates and frees memory
- unlike realloc, if size = 0, this function must return NULL
- sgs_DefaultMemFunc is the sample implementation
- the expected behavior is same as for sgs_Memory
Output
- sgs_MsgFunc and sgs_OutputFunc are responsible for piping the outputs to their destinations
- they can be set at any moment after the creation of the scripting engine context
- sgs_MsgFunc takes the following arguments:
- void* data - the user data pointer
- sgs_Context* C - the scripting engine context
- int type - the debug type (SGS_INFO, SGS_WARNING etc.)
- const char* message - the debug message
- sgs_StdMsgFunc(_NoAbort) are the sample implementations
- sgs_OutputFunc takes the following arguments:
- void* data - the user data pointer
- sgs_Context* C - the scripting engine context
- const void* ptr - the data to write
- sgs_SizeVal size - the size of data to write
- sgs_StdOutputFunc is the sample implementation
Execution notifications
- sgs_HookFunc must be set to retrieve events of that kind
- it can be set at any moment after the creation of the scripting engine context
- sgs_HookFunc takes the following arguments:
- void* data - the user data pointer
- sgs_Context* C - the scripting engine context
- int event - the event that occured, can be one of these values:
- SGS_HOOK_ENTER - function was entered
- SGS_HOOK_EXIT - function was exited
- SGS_HOOK_STEP - instruction is about to be executed
- SGS_HOOK_PAUSE - context was paused
- SGS_HOOK_CONT - context was resumed
- SGS_HOOK_CREAT - context was created (empty, no state copy)
- SGS_HOOK_CFORK - context was forked (full state copy)
- SGS_HOOK_CFREE - context was freed
Commonly required advanced tasks
Method handling
- The preferred way to handle methods with a specific object type for
this
:
ObjectDataStruct* data;
if( !SGS_PARSE_METHOD( C, Object_interface_pointer, data, Object_name, Method_name ) )
return 0;
sgs_FuncName( C, "<object>.<method>" );
if( !sgs_Method( C ) || !sgs_IsObject( C, 0, Object_interface_pointer ) )
return sgs_ArgErrorExt( C, 0, 1, "<object>", "" );
ObjectDataStruct* data = (ObjectDataStruct*) sgs_GetObjectData( C, 0 );
sgs_HideThis( C );
- The OLD way, version 2: Method + function handling (function that can be called as a method too)
int method_call = sgs_Method( C );
sgs_FuncName( C, method_call ? "<object>.<method>" : "<object_function>" );
if( !sgs_IsObject( C, 0, Object_interface_pointer ) )
return sgs_ArgErrorExt( C, 0, method_call, "<object>", "" );
ObjectDataStruct* data = (ObjectDataStruct*) sgs_GetObjectData( C, 0 );
sgs_ForceHideThis( C );
- The reason why the first method is preferred to others is: it's shorter, does pretty much the same thing and resolves to sgs_ParseMethod, which allows sharing more code and rebuilding the SGS_PARSE_METHOD macro abstraction, if necessary.
Standard library reference
Core library
This library is loaded on initialization and contains the functions and constants necessary to do primary actions:
- execution of additional scripts
- creating and using array, class, dict, map, closure
- converting between variables
- serialization / deserialization
- operation control
- error handling and throwing
- global environment modification
- standard input / output
- data debugging
Functions:
- containers
- array - returns an array containing the specified variables
- dict - returns a key-value map object (string keys) containing the specified variables
- map - returns a key-value map object (many key types) containing the specified variables
- class - returns an index fallback / overloading object, linking both specified variables
- array_filter - returns an array that is filtered with a truth test or the specified function
- array_process - convert all array elements by a function
- dict_filter - returns a dict object that is filtered with a truth test or the specified function
- map_filter - returns a map object that is filtered with a truth test or the specified function
- map_process - convert all dictionary elements by a function
- dict_size - returns the number of items in a dict
- map_size - returns the number of items in a map
- isset - checks if the specified property is available
- unset - unsets the specified property (only for dict/map objects)
- clone - returns the cloned variable or the same if immutable
- get_keys - returns an array of keys from an iterable
- get_values - returns an array of values from an iterable
- get_concat - returns an array with all values from all iterables concatenated together in order
- get_merged - returns a dict with all mappings merged
- get_merged_map - returns a map with all mappings merged
- get_iterator - returns an iterator from the passed object, if it has one
- iter_advance - advances an iterator to the next position, returning if there is any more data to read
- iter_getdata - returns key/value data from iterator
- type info and conversion
- tobool - returns a variable, converted to boolean
- toint - returns a variable, converted to an integer
- toreal - returns a variable, converted to a real value
- tostring - returns a variable, converted to a string
- toptr - returns a variable, converted to pointer
- parseint - try to parse a variable as integer, return the value or null on failure
- parsereal - try to parse a variable as string, return the value or null on failure
- typeof - returns the type string of a variable
- typeid - returns type ID of a variable
- typeptr - returns type interface pointer from object variables
- typeptr_by_name - returns type interface pointer by its name
- is_numeric - returns if variable is a numeric type
- is_callable - returns if variable can be called as a function
- is_array - returns if variable is an array
- is_dict - returns if variable is a dict
- is_map - returns if variable is a map
- input/output
- operating system
- ftime - returns an always increasing time value, in seconds, as a real value
- utilities
- rand - returns a random integer between 0 and RAND_MAX
- randf - returns a random real value between 0 and 1
- srand - reseed random number generator
- hash_fnv - generate a hash using the FNV-1a algorithm
- hash_crc32 - generate a hash/checksum using the crc32 algorithm
- SGS-specific utilities
- va_get_args - returns an array of all arguments passed to calling function
- va_get_arg - returns one of the arguments passed to calling function
- va_arg_count - returns the number of all arguments passed to calling function
- metaobj_set - sets the meta-object of an object
- metaobj_get - retrieves the meta-object of an object
- metamethods_enable - enables or disables metamethod support for an object
- metamethods_test - retrieves metamethod support state
- mm_getindex_router - routes __getindex to __get_***
- mm_setindex_router - routes __setindex to __set_***
- event - create an event
- pooled_event - create a pooled event (named event, in table)
- end_on - set or unset an event that can stop a thread
- co_create - create a coroutine
- co_resume - start/resume a coroutine
- thread_create - create a managed topmost coroutine (thread)
- subthread_create - create a managed sub-coroutine (subthread)
- yield - suspend current state, return to caller
- abort - stop the execution of the calling SGS function
- sys_apply - call a function/callable even more dynamically (argument count also specified at runtime)
- pcall - do a protected call by trapping all internal messages in the specified callback
- assert - emit an error if a condition does not evaluate to
true
- sym_register - register persistent object by name (for serialization)
- sym_get - map name to a registered variable or variable to name using the symbol table
- eval - compile and run script code, retrieve return values
- eval_file - compile and rune script file, retrieve return values
- compile_sgs - compile script code
- include_library - load a built-in library
- include_file - load a script file
- include_shared - load a dynamically linked library / shared object (.DLL/.SO)
- import_cfunc - load a C function from .DLL/.SO
- find_include_file - find the include file according to SGS_PATH
- include - load many types of files
- sys_curfile - returns the origin file of the calling function
- sys_curfiledir - returns the directory of the origin file of the calling function
- sys_curprocfile - returns the path to current process file
- sys_curprocdir - returns the path to the directory of current process file
- multiply_path_ext_lists - combine prefix/suffix path lists
- sys_backtrace - returns call stack info
- sys_msg - emit a system message
- INFO - emit an INFO message
- WARNING - emit a WARNING message
- ERROR - emit an ERROR message
- app_abort - abort execution of application (exit application immediately with an error)
- app_exit - exit application immediately
- sys_replevel - change the minimum message reporting level
- sys_stat - write info about system state
- errno - return current errno value as number or string
- errno_string - return specified or current errno value as string
- errno_value - return the errno value corresponding to the name
- dumpvar - returns the dump string of variables
- dumpvar_ext - returns the dump string of a variable, optionally specifying max. recursion depth
- gc_collect - run the garbage collector to remove inaccessible objects
- serialize - returns a byte buffer containing info necessary to later recreate variable structure
- unserialize - recreate variable structure from a byte buffer
Objects and their built-in methods:
Constants:
Other:
- _G - environment superglobal, a dict containing all global variable names and values; can be changed
array [function]
array( ... )
returns an array, containing the arguments
- similar to the array literal, though somewhat limited (number of arguments is limited to 255 in the language, but not the API/serialization system)
array( "5", 6, 7.0 ) // same as ["5",6,7.0]
- the implementation of
array
is an object with __call metamethod. New methods can be added to array
:
function array.join( separator )
{
return string_implode( this, separator );
}
array_sized [function]
array_sized( size )
returns an array, containing size
null values
dict [function]
dict( [key, value, ...] )
returns a 'dict' (dictionary/hash table) object, containing the even arguments mapped to respective previous arguments
- if no arguments are passed, an empty dictionary is returned
- if an even number of arguments is passed, function returns null and emits a warning
- all even arguments must be strings or convertible to strings
dict( "name", "John", "phone", 1234567890 ); // same as { name = "John", phone = 1234567890 }
map [function]
map( [key, value, ...] )
returns a 'map' (map/hash table) object, containing the even arguments mapped to respective previous arguments
- if no arguments are passed, an empty map is returned
- if an even number of arguments is passed, function returns null and emits a warning
map( "John", "name", 1234567890, "phone" ); // useful for mapping additional data to variables or making sets
class [function]
class( object obj, object metaobj )
sets metaobj
as meta-object for obj
and enables metamethods for obj
, returns obj
- refer to Classes for more information on how class objects work and how to use them
someCommonInterface = { printdata = function(){ print( this.data ); } };
c = class( { data = "5" }, someCommonInterface );
c.data = "6";
c.printdata(); // prints 6
array_filter [function]
array_filter( array[, callable] )
return an array with the items that convert to boolean 'true', optionally preprocessed by a callable
- two arguments are passed to the callable: value, index
array_filter([ 0, 1, 2, 3 ]); // returns [1,2,3]
array_process [function]
array_process( array, callable )
return an array with the items passed through a callable
- two arguments are passed to the callable: value, index
dict_filter [function]
dict_filter( dict[, callable] )
return a dict with the items that convert to boolean 'true', optionally preprocessed by a callable
- two arguments are passed to the callable: value, key
dict_filter({ a = 0, b = 1 }); // returns {b=1}
map_filter [function]
map_filter( map[, callable] )
return a map with the items that convert to boolean 'true', optionally preprocessed by a callable
- two arguments are passed to the callable: value, key
map_filter(map{ a = 0, b = 1 }); // returns [map]{b=1}
map_process [function]
map_process( obj, callable )
pass all items through a callable, return same object
- two arguments are passed to the callable: value, key
dict_size [function]
dict_size( dict )
return the number of entries in the dict object
x = { a = 5, b = 123 };
dict_size( x ); // returns 2
map_size [function]
map_size( dict )
return the number of entries in the map object
x = map( 5, "a", 123, "b" );
map_size( x ); // returns 2
isset [function]
isset( var, key )
returns whether a property key
is readable (exists) in variable var
x = { a = 5 };
isset( x, "a" ); // returns 'true'
isset( x, "b" ); // returns 'false'
isset( print, "call" ); // returns 'true' -- works with built-in special properties too
unset [function]
unset( dict|map var, (string) key )
removes an entry named key
from the dictionary var
key
is only required to be of string
type if a dict
is passed
clone [function]
clone( var )
creates a one-reference copy of the variable var
or returns null and emits a warning on failure
- variables that are passed by value (null, bool, int, real, cfunc) or strings/functions are returned as-is, since for value types all copies are same and strings/functions are immutable
x = { a = 5 };
y = clone( x );
z = x;
x.a = 6;
print( y.a ); // prints "5"
print( z.a ); // prints "6"
get_keys [function]
get_keys( iterable var )
returns an array of keys found in the iterable object var
or returns null and emits a warning on failure
var
must be an iterable object (has interface OP_CONVERT defined and successfully handles a CONVOP_TOITER request) - such objects are array
, dict
, map
and io_dir
get_keys( [5,7,0] ); // returns [0,1,2]
get_keys( {b=5,a=2} ); // returns ["b","a"]
get_values [function]
get_values( iterable var )
returns an array of values found in the iterable object var
or returns null and emits a warning on failure
var
must be an iterable object (has interface OP_CONVERT defined and successfully handles a CONVOP_TOITER request) - such objects are array
, dict
, map
and io_dir
get_values( [5,7,0] ); // returns [5,7,0]
get_values( {b=5,a=2} ); // returns [5,2]
get_concat [function]
get_concat( iterable var, iterable var1, ... )
returns an array of values found in all iterable objects passed to the function or returns null and emits a warning on failure
get_concat( [1,2], {a="5",b=8} ); // returns [1,2,"5",8]
get_merged [function]
get_merged( iterable var, iterable var1, ... )
returns a dict of all key-value pairs found in all iterable objects passed to the function or returns null and emits a warning on failure
get_merged( [1,2], [3], {a="4"} ); // return {0=3,1=2,a="4"}
get_merged_map [function]
get_merged_map( iterable var, iterable var1, ... )
returns a map of all key-value pairs found in all iterable objects passed to the function or returns null and emits a warning on failure
get_merged_map( [1,2], map(5,6), {a="4"} ); // return {0=3,1=2,int(5)=6,a="4"}
get_iterator [function]
get_iterator( iterable var )
returns an iterator from the passed object, if it has one
get_iterator( [ 5 ] ); // returns array iterator for the specified array
iter_advance [function]
iter_advance( iterator var )
advances an iterator to the next position, returning if there is any more data to read
it = get_iterator( [ 5 ] ); // retrieves iterator from array [5]
iter_advance( it ); // returns true, indicating that the current position is still a valid one
iter_getdata [function]
iter_getdata( iterator var, bool pushkey = false, bool pushvalue = true )
returns key/value data from iterator
- if key is requested, it is returned first
- if neither key not value are requested,
null
is returned and a warning is emitted
it = get_iterator( [ 5 ] ); // retrieves iterator from array [5]
iter_advance( it ); // returns true, indicating that the current position is still a valid one
(key,value) = iter_getdata( it, true ); // returns 0, 5 -- key, value
tobool [function]
tobool( var )
returns a boolean, generated from variable var
using the Conversion rules
tobool( 5 ); // returns 'true'
tobool( "" ); // returns 'false'
toint [function]
toint( var )
returns an integer, generated from variable var
using the Conversion rules
toint( 5.4 ); // returns 5
toint( "0xff" ); // returns 255
toreal [function]
toreal( var )
returns a real value, generated from variable var
using the Conversion rules
toreal( 5 ); // returns 5.0
toreal( "3e+2" ); // returns 300.0
toreal( "0xff" ); // returns 255.0
tostring [function]
tostring( var )
returns a string value, generated from variable var
using the Conversion rules
tostring( 5 ); // returns "5"
tostring( { "a" = "b" } ); // returns "{a=b}"
toptr [function]
toptr( var )
returns a pointer value, generated from variable var
using the Conversion rules
toptr( 5 ); // returns 5
toptr( "3e+2" ); // returns address of the string
toptr( [] ); // returns address of array data
parseint [function]
parseint( var )
returns an integer, generated from variable var
using the Conversion rules or returns null
on failure
parseint( 5.4 ); // returns 5
parseint( "0xff" ); // returns 255
parseint( parseint ); // returns null
parsereal [function]
parsereal( var )
returns a real value, generated from variable var
using the Conversion rules or returns null
on failure
parsereal( 5 ); // returns 5.0
parsereal( "3e+2" ); // returns 300.0
parsereal( "0xff" ); // returns 255.0
parsereal( parsereal ); // returns null
typeof [function]
typeof( var )
returns the type name of variable var
, as string
- this function is equivalent to sgs_TypeOf in the C API
typeof( 5 ); // returns "real"
typeof( [] ); // returns "array"
typeid [function]
typeid( var )
returns the first 4 bits of the variable var
type flags, as int
- returns one of the values mapped to VT_NULL/VT_BOOL/VT_INT/VT_REAL/VT_STRING/VT_FUNC/VT_CFUNC/VT_OBJECT/VT_PTR/VT_THREAD
- this function is equivalent to sgs_ItemType in the C API
typeid( 5 ) == VT_INT; // returns 'true'
typeid( [] ); // returns 7 / VT_OBJECT
typeptr [function]
typeptr( var )
returns type interface pointer from object variables or null pointer from other variables
typeptr( 5 ); // returns ptr(0)
typeptr( [] ); // returns ptr(...), NOT ptr(0)
typeptr_by_name [function]
typeptr_by_name( string name )
returns type interface pointer by its name or null pointer if name is not assigned to a pointer
typeptr_by_name( "array" ); // returns ptr(...)
typeptr_by_name( "array" ) == typeptr( [] ); // returns 'true'
is_numeric [function]
is_numeric( var )
returns whether the variable var
is numeric - one of bool/int/real or a numeric string
- all types that can always be converted to numbers are considered numeric, with two exceptions:
- convertible objects are not numeric since validation requires an interface call and unnecessary interface calls cannot be made
- null value is considered to be the lack of a better value, thus it cannot be considered valid, even though it always maps implicitly to the integer 0
is_numeric( 12.124 ); // returns true
is_numeric( "what" ); // returns false
is_callable [function]
is_callable( var )
returns whether the variable var
is callable - a function (func/cfunc) or an object with OP_CALL defined
is_callable( print ); // returns 'true'
is_callable( function(){} ); // returns 'true'
is_callable( 5 ); // returns 'false'
is_array [function]
is_array( var )
returns if variable is an array
is_array( print ); // returns 'false'
is_array( [] ); // returns 'true'
is_dict [function]
is_dict( var )
returns if variable is a dict
is_dict( 5 ); // returns 'false'
is_dict( [] ); // returns 'false'
is_dict( {} ); // returns 'true'
is_map [function]
is_map( var )
returns if variable is a map
is_map( "map" ); // returns 'false'
is_map( {} ); // returns 'false'
is_map( map() ); // returns 'true'
print, println, printlns, errprint, errprintln, errprintlns [functions]
print( ... ), println( ... ), printlns( ... ),
errprint( ... ), errprintln( ... ), errprintlns( ... ),
passes all arguments, converted to strings, to the (error) output callback
- (err)print passes arguments without modifications
- (err)println passes a newline character after all variables
- (err)printlns passes a newline character after each variable
print( 5, "x" ); // prints "5x"
println( 5, "x" ); // prints "5x\n"
printlns( 5, "x" ); // prints "5\nx\n"
errprint( 5, "x" ); // prints "5x" to error output stream
errprintln( 5, "x" ); // prints "5x\n" to error output stream
errprintlns( 5, "x" ); // prints "5\nx\n" to error output stream
printvar_ext [function]
printvar_ext( var, int maxdepth = 5 )
passes a dump of the variable (informative string version) to the output callback, allowing to optionally specify the maximum depth of the dump (how deep it is allowed to look for sub-variables)
printvar_ext( 5 ); // prints "real (5)"
printvar_ext( "wat" ); // prints "string [3] "wat""
printvar_ext( [{a=[{}]}], 2 ); /* prints:
object (003C5F90) [0] array (1)
[
object (003C60A8) [1] dict (1)
{
...
}
]
*/
printvar [function]
printvar( var, ... )
same as a list of printvar_ext(var); calls for each argument
read_stdin [function]
read_stdin( bool all = false )
reads from the standard input
- if
all
is set to 'true', all standard input is read up to EOF (useful for piped input)
- if
all
is set to 'false' or not set at all, input is read up to (and excluding) the next newline character
print "Name: "; name = read_stdin(); // waits for user input
process( read_stdin(true) ); // loads all piped input
ftime [function]
ftime()
returns a value that is increased by a total of 1 each second (time), as real
- guaranteed to offer sub-second precision unless stated otherwise for any specific platform
start = ftime();
do_something_big();
println( "That took " $ ftime() - start $ " seconds." );
rand [function]
rand()
returns a random 'int' value in the range [0;RAND_MAX] - from 0, inclusive, to RAND_MAX, inclusive
randf [function]
randf()
returns a random 'real' value in the range [0;1] - from 0, inclusive, to 1, inclusive
srand [function]
srand( int seed )
specify a different seed value for the built-in pseudo-random number generator
srand( 5 ); // restart the generator with the value specified
srand( ftime() ); // restart the generator depending on the second the code was executed
hash_fnv [function]
hash_fnv( string buf, bool as_hexstring = false )
generate a hash, using the FNV-1a algorithm
- if
as_hexstring
is true, an 8 characters long string containing the hexadecimal fixed-length hash value is returned, otherwise the value is returned as integer
hash_crc32 [function]
hash_crc32( string buf, bool as_hexstring = false )
generate a hash/checksum, using the CRC32 algorithm
- if
as_hexstring
is true, an 8 characters long string containing the hexadecimal fixed-length hash/checksum value is returned, otherwise the value is returned as integer
va_get_args [function]
va_get_args()
return an array containing all arguments passed to the calling function
va_get_arg [function]
va_get_arg()
returns one of the arguments passed to calling function
va_arg_count [function]
va_arg_count()
return the number of arguments passed to the calling function
metaobj_set [function]
metaobj_set( object obj, object metaobj )
sets the meta-object of an object
metaobj_get [function]
metaobj_get( object obj )
retrieves the meta-object of an object
metamethods_enable [function]
metamethods_enable( object obj, bool enable )
enables or disables metamethod support for an object
metamethods_test [function]
metamethods_test( object obj )
retrieves metamethod support state
mm_getindex_router [function]
mm_getindex_router( key )
__getindex to __get_*** router
- when applied to metaobject of a metamethod-enabled object's
__getindex
property, it routes every request to __get_<key>
- see Metamethods for more info
mm_setindex_router [function]
mm_setindex_router( key, value )
__setindex to __set_*** router
- when applied to metaobject of a metamethod-enabled object's
__setindex
property, it routes every request to __set_<key>
- see Metamethods for more info
event [function]
event( bool signaled = false )
Creates an event.
- This object can be used to stop a thread. See end_on for more info.
- Event is initialized to the state specified by
signaled
.
- This object consists of one property -
bool signaled
. It can be modified to change the state of the event.
pooled_event [function]
pooled_event( object, string name, bool signaled = false )
Create a pooled event (named event, in table)
- This object can be used to stop a thread. See end_on for more info.
- If the event is found in the object as a property by the given name, that event is returned instead, without modification.
- Otherwise, a new event is created and registered to the specified object as a property with the given name.
- Event is initialized to the state specified by
signaled
.
- This object consists of one property -
bool signaled
. It can be modified to change the state of the event.
end_on [function]
end_on( this thread, object event, bool enable = true )
Set or unset an event object that can stop a thread.
An "event" is any object that implements the "convert to bool" behavior. True means 'signaled', false - inactive.
When the event is signaled, the thread will be aborted as soon as possible.
- Alternatively accessible via the "end_on" property of any thread.
- sgs_EndOn is the C version of this function.
co_create [function]
co_create( callable )
Creates a coroutine with the specified callable.
- function returns a coroutine object that can be started/resumed with co_resume
co_resume [function]
co_resume( coroutine[, args..] )
Starts or resumes the coroutine.
- if function is called for the first time, the attached callable is called within the coroutine, passing given arguments to the callable
- if function is suspended, arguments will be passed as return values from the yield call that suspended it
thread_create [function]
thread_create( fn, this[, args..] )
Starts a managed topmost coroutine (thread).
- This function returns the created thread.
- The function passed is immediately called once.
- This thread is owned by the topmost owned thread (engine thread or coroutine created with co_create) - if it's destroyed, this thread will be aborted and destroyed as well.
subthread_create [function]
subthread_create( fn, this[, args..] )
Starts a managed sub-coroutine (subthread).
- This function returns the created subthread.
- The function passed is immediately called once.
- This thread is owned by the current context (thread, subthread, engine thread or coroutine) - if it's destroyed, this thread will be aborted and destroyed as well.
process_threads [function]
process_threads( dt[, ctx ] )
Advance the managed subthreads once, using the specified delta time.
- If
ctx
is unspecified, it defaults to the current context.
- This function should only be used on the engine thread and owned coroutines since it recursively advances all subthreads.
yield [function]
yield([ args.. ])
Suspends the current state, returning to caller.
- Arguments are passed as return values to the caller.
- State cannot be suspended if there are C functions or other unusual constructs in the stack.
abort [function]
abort([ contexts... ])
Stops execution and returns to C code as soon as possible.
- If no contexts are specified, current context is aborted, otherwise only the specified contexts are aborted.
- This function is equivalent to using sgs_Abort in the C API.
abort();
print( 5 ); // this line is not reached
sys_apply [function]
sys_apply( func, this, args )
calls the specified function with the specified this
value and argument array
If argument count is known at compile time, prefer using the compatible function call syntax (thisvar!func( arg1, ... )
) to this function.
- C functions, SGS functions and closure objects have this function under the "apply" property.
pcall [function]
pcall( callable func[, callable errh ])
Calls the callable func
, hiding internal errors from the caller or optionally passing them to callable errh
.
errh
error handler is called with two arguments - int error_type, string message
- and expected to return 0-1 arguments ([int])
- error handler must return 0/null/nothing if the error has been successfully processed or the new error type otherwise
- errors thrown inside the handler will not be caught so any error can be transformed to any other
- an empty function behaves the same way as
pcall
without function
include "string";
function handler( type, msg )
{
if( string_find( msg, "not found" ) !== null )
sys_msg( type, "nooooooooooo" );
}
function handler2( type, msg )
{
if( string_find( msg, "not found" ) !== null )
return SGS_ERROR;
}
pcall(function(){ print x; }); // nothing
pcall(function(){ print x; }, handler ); // renamed warning
pcall(function(){ print x; }, handler2 ); // changed type to error
assert [function]
assert( var condition[, string message] )
if condition evaluates to 'false', emits an error "assertion failed" or if message is defined, "assertion failed: <message>"
assert( text, "text was not defined" );
sym_register [function]
sym_register( string name, var )
Register a persistent item (symbol) by the specified name.
- Symbols are used for serialization to map unserializable and persistent items in both ways, to preserve their linkage in the serialized data.
- This function is equivalent to sgs_RegSymbol in the C API.
myfunc = function(){};
sym_register( "myfunc", myfunc );
sym_get [function]
sym_get( var )
Map name to a registered variable or variable to name using the symbol table.
print sym_get( assert ); // prints "assert"
print sym_get( "assert" ); // prints "C function"
eval [function]
eval( string code )
returns the result of evaluating the passed code
string as SGScript code
eval("print 5;"); // prints 5
eval_file [function]
eval_file( string filename )
returns the result of evaluating the file pointed to by filename
as SGScript code
eval_file("myfile.sgs"); // ???
compile_sgs [function]
compile_sgs( string code )
returns the generated bytecode or null + error info
- this function is equivalent to sgs_Compile in the C API
compile_sgs( io_file_read( "myfile.sgs" ) ); // ???
include_library [function]
include_library( string lib[, bool override ] )
loads the global variables of the specific library lib
in the state, returns success, as bool
, emits a warning on failure
- lib must be one of 'fmt', 'io', 'math', 'os', 'string'
- if
override
is specified, library will be reloaded even if it was already loaded before
- this function is equivalent to the sgs_LoadLib_* functions in the C API
printvar( sin ); // warning, null
include_library( "math" );
printvar( sin ); // C function
include_file [function]
include_file( string file[, bool override ] )
executes the file pointed to by file
, returns success, as bool
, emits a warning on failure
- this function does NOT check include paths (SGS_PATH)
- if
override
is specified, file will be reloaded even if it was already loaded before
- this function is equivalent to sgs_ExecFile in the C API
include_file( "something.sgs" ); // loads something
include_file( "something.sgs" ); // does not load it again
include_file( "something.sgs", true ); // loads it again
include_shared [function]
include_shared( string file[, bool override ] )
runs the shared library pointed to by file
, returns success, as bool
, emits a warning on failure
file
must be available according to the platform-specific rules of dynamic libraries (shared objects)
- the library must contain a 'sgscript_main' function that will be called on initialization
- if
override
is specified, file will be reloaded even if it was already loaded before
include_shared( "sgsjson.dll" ); // load the JSON library DLL on Windows
find_include_file [function]
find_include_file( string file )
Find the include file according to SGS_PATH.
- File is searched according to the semicolon-separated pattern list specified in the global variable
SGS_PATH
.
|
- replaced with calling file's directory.
@
- replaced with process directory.
?
- replaced with file
.
- A path to file is only returned if the file exists.
include [function]
include( string file[, bool override ] )
tries to load a library or a file according to the include path
- the order of actions:
- first, a library load is attempted
- on failure, a file is looked for by every entry of the sys_include_path variable (? - the file replacement symbol, | - file directory replacement symbol, ; - separator)
- if file is not found, everything stops
- if file is found, first - a library load is attempted, on failure - bytecode & source code loading
- this function is also available as a replicating statement 'include' (ex. 'include "fmt", "io";' works the same way as include("fmt"); include("io");)
import_cfunc [function]
import_cfunc( string file, string funcname )
retrieves the funcname
function of the shared library file
, returns success, as bool
, emits a warning on failure
Do not call 'sgscript_main' using this function! That function has different return value semantics so at best, something will work, a warning could be emitted and the worst case is that something will crash.
file
must be available according to the platform-specific rules of dynamic libraries (shared objects)
import_cfunc( "mydll.dll", "someSGScriptFunc" )();
sys_curfile [function]
sys_curfile()
returns the path of the file (as passed on load) that contains the currently executed code or null
if the file cannot be determined (eval, C functions)
// a.sgs
print( sys_curfile() ); // prints "a.sgs"
// b.sgs
include "a.sgs";
sys_curfiledir [function]
sys_curfiledir()
returns the directory path of the file (as passed on load) that contains the currently executed code or null
if the file cannot be determined (eval, C functions)
// ext/a.sgs
print( sys_curfiledir() ); // prints "ext"
// a.sgs
print( sys_curfiledir() ); // prints "."
// b.sgs
include "ext/a.sgs", "a.sgs";
sys_curprocfile [function]
sys_curprocfile()
returns the path of the executable file the script is executed in
- in case of failure, function will set errno
sys_curprocdir [function]
sys_curprocdir()
returns the path to the directory of the executable file the script is executed in
multiply_path_ext_lists [function]
multiply_path_ext_lists( string prefixes, string joiner = "/"[, string suffixes ])
combines prefixes
(paths) and suffixes
(extensions) through the joiner
string to create an array of paths
- default value of
suffixes
is platform-specific and equal to the last logical half of the initial SGS_PATH value
- from code:
suffixes = "?;?" SGS_MODULE_EXT ";?.sgc;?.sgs"
(SGS_MODULE_EXT is either ".dll" or ".so")
prefixes
and suffixes
are expected to be in the SGS_PATH format - semicolon-separated (;) strings
sys_backtrace [function]
sys_backtrace( bool as_string = false )
returns the call stack function/line/file list, either as array of dicts, or as a string, formatted exactly like in error messages (via sgs_PushErrorInfo)
- in the dict, there are three keys:
- func (string)
- line (null/int)
- file (string)
errprint( sys_backtrace( true ) ); // print backtrace to stderr
println( sys_backtrace().last.func ); // print name of current function
sys_msg [function]
sys_msg( int code, string message )
passes a message to the internal messaging system (one that's commonly used to report errors and warnings)
Different codes can be handled differently by the system. By default, SGS_ERROR code will stop execution and return to C code as soon as possible.
code
is the code to use to pass the message (ex. SGS_INFO, SGS_WARNING, SGS_ERROR)
INFO [function]
INFO( string message )
passes a message to the internal messaging system
- the name of this function is written in all caps to avoid shadowing by a common variable name
- works exactly like
sys_msg( SGS_INFO, message )
WARNING [function]
WARNING( string message )
passes a message to the internal messaging system
- the name of this function is written in all caps for consistency with the other two
- works exactly like
sys_msg( SGS_INFO, message )
ERROR [function]
ERROR( string message )
passes a message to the internal messaging system
By default, SGS_ERROR code (the one this function uses internally) will stop execution and return to C code as soon as possible.
- the name of this function is written in all caps to avoid shadowing by a common variable name
- works exactly like
sys_msg( SGS_INFO, message )
app_abort [function]
app_abort()
calls the abort() function of the C standard library (crashes the application)
app_exit [function]
app_exit( code = 0 )
calls the exit() function of the C standard library (exits the application)
sys_replevel [function]
sys_replevel([ level ])
returns the current reported error level and optionally sets a new one
The effects of this function are not reverted automatically at any moment (unless implemented manually with hooks).
old_level = sys_replevel( SGS_ERROR ); // report only errors or worse
magic = calculate_magic(); // any warnings are never processed at this point
sys_replevel( old_level ); // restore the old reported level
sys_stat [function]
sys_stat( code )
prints info about virtual machine state, everything is implementation-defined
- accepted codes are the same as for sgs_Stat, which this function is equivalent to
sys_stat( 11 ); // dumps all globals
errno [function]
errno( as_string = false )
returns the last relevant error number for the C standard library, as an integer or a string if as_string
is set
data = io_file_read( "doesnotexist" ); // file that does not exist
print errno(); // prints 2
print errno(true); // prints "No such file or directory" on Windows
errno_string [function]
errno_string( int code )
returns the error string for the given code
- errno_string(errno()) is equivalent to errno(true)
print errno_string(2); // prints "No such file or directory" on Windows
errno_value [function]
errno_value( string key )
returns the number for the error key (for "ENOENT" it would return 2)
- this function might be a bit slow considering that it currently does not use any extended lookup systems, such as hash tables
data = io_file_read( "doesnotexist" );
if( errno() == error_string("ENOENT") )
println( "file does not exist" );
dumpvar_ext [function]
dumpvar_ext( var, int depth = 5 )
similar to printvar_ext() but returns the dump instead of printing it
- this function is equivalent to sgs_DumpVar in the C API
sys_msg( SGS_INFO, "Extended variable info:\n" $ dumpvar(data) );
dumpvar [function]
dumpvar( ... )
similar to printvar() but returns the dumps, concatenated, instead of printing them
gc_collect [function]
gc_collect()
Runs the garbage collector on the virtual machine, waiting until it has finished
- returns the reduction in objects or false on failure
a = [];
a.push(a); // creates a circular dependency
a = null; // a is not actually freed
gc_collect(); // a is freed now
serialize [function]
serialize( var, int mode = 2 )
Converts the variable to a byte buffer (string), containing the serialized data that can be recreated with unserialize() or returns null and emits a warning on failure
- C functions and objects without OP_SERIALIZE implemented cannot be serialized
data = serialize({ name = "A", info = "B" });
print data; // prints random-looking, yet deterministic garbage
print unserialize(data); // prints {name=A,info=B}
unserialize [function]
unserialize( string data, int mode = 2 )
Recreates a variable from the buffer with serialized data or returns null and emits a warning on failure
- this function will internally call global object creation functions specified in the data, so they must be defined and the state could change in the process
- for more info, refer to Serialization in SGScript
data = serialize({ name = "A", info = "B" });
print data; // prints random-looking, yet deterministic garbage
print unserialize(data); // prints {name=A,info=B}
sgson_encode [function]
sgson_encode( var[, string tab ])
Encodes the given variable in the SGSON format.
tab
allows to specify the string used for tabs
- if
tab
is null
, the text output is tightly packed, without any extra spaces
sgson_decode [function]
sgson_decode( string data )
Decodes the SGSON text into a variable
SGS_*** [constants]
SGS_INFO, SGS_WARNING, SGS_ERROR, SGS_APIERR
defined to the values of the C macros, respectively 100, 200, 300 and 330
VT_*** [constants]
VT_NULL, VT_BOOL, VT_INT, VT_REAL, VT_STRING, VT_FUNC, VT_CFUNC, VT_OBJECT, VT_PTR, VT_THREAD
these constants are defined to the values of the C macros (with the prefix "SGS_VT_" in C) and can be compared with the values returned in typeid()
RAND_MAX [constant]
RAND_MAX
The maximum number that can be returned by rand().
_G [superglobal]
A hard-coded global value that points to the global dictionary. Can be used to access non-identifier globals and change the global dictionary.
_G["$diff"] = 5; // no way to access this via usual globals
_G = {}; // global value dictionary is changed, previous functions are lost unless stored somewhere
_R [superglobal]
A hard-coded global value that points to the registry. Can be used to access the symbol table (_R["$sym"]) or include list (_R["$inc"]).
- It is preferred to use sym_get and sym_register to deal with symbols, this table is mostly available for introspection and workarounds.
_F [superglobal]
The currently executed function.
- It can be used in a function to call itself recursively, especially when the function is defined in a position where it cannot reference itself without additional effort.
function f(){ printvar( _F ); }
f(); // prints info about function 'f'
_T [superglobal]
The currently executed thread (context/coroutine).
function f(){ printvar( _T ); }
f(); // prints info about current context
thread f(); // prints info about this newly created thread
array [object]
- built-in methods
- read-only properties
- [int] size
- [int] capacity
- [var] first (valid if array is not empty, otherwise a warning is thrown and 'null' is returned)
- [var] last (similar to 'first')
- other features:
- read/write integer index
- full content dump
- tostring = quick content dump
- tobool = size != 0
- iterator
- cloning
- serialization
- GC-safe
- meta-object (global array)
array.push [method]
array.push( ... )
appends the variables passed to the end of array in the same order, returns the array for chaining
a = [ 5 ];
a.push( 6, 7 ).push( 8 ); // a = [5,6,7,8]
array.pop [method]
array.pop()
removes one item from the end of array or emits a warning if there are no items in the array, returns the removed item
a = [ 5 ];
a.pop(); // array is empty now
a.pop(); // warning: "array is empty, cannot pop"
array.shift [method]
array.shift()
removes one item from the beginning of array or emits a warning if there are no items in the array, returns the removed item
a = [ 5, 6 ];
a.shift(); // a = [6], returned 5
array.unshift [method]
array.unshift( ... )
prepends the variables passed to the beginning of array in the same order, returns the array for chaining
a = [ 5 ];
a.unshift( 6, 7 ); // a = [6,7,5] now
array.insert [method]
array.insert( int pos, ... )
inserts the variables passed (all arguments after first) to the position specified in the array or emits a warning on failure (index out of bounds), returns the array for chaining
pos
accepts both positive and negative values, the meaning is "which value to insert before"
- negative values are converted to positive ones by adding (<size> + 1) to them
- beginning of array can be inserted to using position 0 or (- <size> - 1)
- end of array can be inserted to using position <size> or -1
a = [ 5, 7 ];
a.insert( 1, 6 ); // inserts 6 at position 1 (before item with index 1)
a.insert( -1, 8 ); // appends to the end of array, a = [5,6,7,8] now
array.erase [method]
array.erase( int[, int] )
erases item or a range of items from the array, depending on the arguments passed or emits a warning on failure, returns the array for chaining
- both arguments have same index processing rules as array.insert(), but with one difference - if both arguments are passed, after resolving (converting negative indices to positive ones, if there are any), first must be smaller than second
a = [ 5, 6, 7, 8 ];
a.erase( 1, 2 ); // erases all items between position 1 and 2, including; gives a = [5,8]
a.erase( 0 ); // a = [8]
array.part [method]
array.part( int from[, int max ] )
returns a new array starting from index from
, with the max. size max
- if
from
is negative, it is subtracted from the end of array
max
cannot be negative, everything else is allowed
a = [ 5, 6, 7, 8 ];
a.part( 1, 2 ); // returns [6,7]
a.part( -5, 2 ); // returns [5]
a.part( 3 ); // returns [8]
array.clear [method]
array.clear()
erases all items from the array, returns the array for chaining
a = [ 1, "asd", 8 ];
a.clear(); // a = []
array.reverse [method]
array.reverse()
reverses the order of items in the original array, returns the original array for chaining
a = [ 1, 2, 3 ];
b = a;
a.reverse(); // a = [3,2,1]
print( b ); // prints [3,2,1]
array.resize [method]
array.resize( int size )
changes the size of the array, returns the array for chaining
size
must be larger than or equal to 0
- if previous size was less than passed to the method, null variables are appended
- if previous size was more than passed to the method, items are popped from the end of the array
- if size was not changed, nothing else will change
a = [ 5, 6, 7 ];
a.resize( 5 ); // a = [5,6,7,null,null]
a.resize( 2 ); // a = [5,6]
array.reserve [method]
array.reserve( int capacity )
reserves the space for the requested number of elements in the array, returns the array for chaining
capacity
must be larger than or equal to 0
- if previous capacity was less than passed to the method, capacity will be increased to the requested amount
- if previous capacity was more than or equal to what was passed to the method, nothing will change
a = [ 5, 6, 7 ];
a.capacity( 1 ); // nothing happens
a.capacity( 5 ); // a.capacity = 5 and two variable additions can now happen without reallocations
array.sort [method]
array.sort([ bool reverse ])
sorts the array using the sgs_Compare C API function for comparisons, returns the array for chaining
- if
reverse
is true, array is sorted in the reverse order
a = [ 6, 8, 7, 5 ];
a.sort(); // a = [5,6,7,8]
array.sort_custom [method]
array.sort_custom( callable[, bool reverse ] )
sorts the array using the callable for comparisons, returns the array for chaining
This function is considerably slower than array.sort or array.sort_mapped so prefer those if performance matters.
- callable must return a number, specifying the relative order of the two passed arguments: less than 0 if first variable should be placed before second, greater than 0 if first variable should be placed after second, or 0 if it doesn't matter
- if
reverse
is true, array is sorted in the reverse order
a = [ 6, 8, 7, 5 ];
// this code will sort numbers into odd/even ones and in ascending order
a.sort_custom( function(a,b){return a-b+(b%2-a%2)*1000; } ); // a = [5,7,6,8]
array.sort_mapped [method]
array.sort_mapped( array map[, bool reverse ] );
sorts the array by sorting the passed array and applying the index map to the first one, returns the array for chaining
- both arrays must have the same size, otherwise a warning is emitted
- all variables in the mapping array are interpreted as 'real' values
- if
reverse
is true, array is sorted in the reverse order
a = [ 5, 6, 7, 8 ];
b = [ 3, 1, 4, 2 ];
a.sort_mapped( b ); // a = [6,8,5,7]
array.find [method]
array.find( var item[, bool strict[, int from ]] )
attempts to find item
in array, starting from 0 or the index passed with from
, if it exists, using basic or strict equality comparisons (depending on strict
), returning the index or 'null' if item was not found
- if strict comparisons are enabled, variable types are also checked for equality
a = [ 5, 6, 7, 8 ];
a.find( "7" ); // returns 2
a.find( "7", true ); // returns null
array.remove [method]
array.remove( var item[, bool strict[, bool all[, int from ]]] )
attepts to find and remove first or all item
variables in array (depending on all
), according to the rules specified in array.find(), returning the number of removed items
a = [ 5, 2, 6, 7, 8, 2 ];
a.remove( "7" ); // returns 1; a = [5,2,6,8,2]
a.remove( "6", true ); // returns 0; a remains unchanged
a.remove( 2, false, true ); // returns 2; a = [5,6,8]
array.unique [method]
array.unique( bool strconv = false )
returns an array without duplicates, where a duplicate is a strictly equal variable or a string conversion match
- if
strconv
is true, items are converted to strings before comparison
a = [ 5, 3, 2, 3, 2, "3" ];
a.unique(); // returns [5,3,2,"3"]
a.unique( true ); // returns [5,3,2]
array.random [method]
array.random( int num )
return num
randomly chosen items from the array
- to retrieve a part of the array in random order without duplicates, array.shuffle can be used
- items after RAND_MAX will currently not be returned
array.shuffle [method]
array.shuffle()
change the order of items in the array
dict [object]
- features:
- read/write string index
- read/write string properties and integer index-via-property
- full content dump
- tostring = quick content dump
- tobool = size != 0
- iterator
- cloning
- serialization
- GC-safe
- type identification (returns the string "dict")
map [object]
- features:
- read/write index
- read/write properties
- full content dump
- tostring = quick content dump
- tobool = size != 0
- iterator
- cloning
- serialization
- GC-safe
- type identification (returns the string "map")
ALL SGScript core functions (A-Z)
Formatting library ("fmt")
This library includes functions and objects for parsing binary and text buffers.
Functions:
- fmt_pack - pack variables into a byte buffer, according to the format string
- fmt_unpack - unpack byte buffer to an array of variables, according to the format string
- fmt_pack_count - returns the number of items found in a packing format string
- fmt_pack_size - returns the number of bytes found in a packing format string
- fmt_base64_encode - encodes a byte buffer in base64 character buffer (A-Za-z0-9+/)
- fmt_base64_decode - decodes a base64 character buffer (A-Za-z0-9+/) to a byte buffer
- fmt_custom_encode - encodes a custom format (selected character codes to numeric version)
- fmt_text - formats specified variables according to the format string
- fmt_parser - creates a text parser object with the specified stream reading function
- fmt_string_parser - creates a text parser object that reads from the specified string
- fmt_file_parser - creates a text parser object that reads from the specified file
- fmt_charcc - checks if a character is in the character class
Objects and their methods:
- fmt_parser - formatted text string-parsing object
- read - read the specified number of characters from the stream
- getchar - read one character from the stream
- readcc - read characters while they match the specified class
- skipcc - skip characters while they match the specified class
- read_real - read with the real value character class, optionally return real
- read_int - read with the integer value character class, optionally return integer
- read_binary_int - read with the binary integer character class, optionally -return integer
- read_octal_int - read with the octal integer character class, optionally return -integer
- read_decimal_int - read with the decimal integer character class, optionally -return integer
- read_hex_int - read with the hexadecimal integer character class, optionally return -integer
- check - check for presence of a string in stream
fmt_pack [function]
fmt_pack( string fmt, ... )
packs the given arguments using the format fmt
and returns the byte buffer or returns null and emits a warning on failure
- the format: character command list
- 0-9: add a digit to multiplier
- =/</>/@: "=" sets host byte order, "<" - little endian byte order, ">" - big endian, "@" - inverted
- +/-: "+" - unsigned integers, "-" - signed integers
- c/w/l/q/p: integers (c - char, 1 byte, w - word, 2 bytes, l - long, 4 bytes, q - quad-word, 8 bytes, p - pointer/size, platform-specific size of 4/8 bytes, usually)
- f/d: floating-point numbers: "f" - single precision, "d" - double precision
- s: string, multiplier sets length instead of count, as with other items
- x: padding byte (does not get read or written, can be used to advance the pointer)
- space/tab/CR/LF: invisible to the parser
- everything else resets multiplier, does nothing
- sign modifiers do nothing in fmt_pack, refer to fmt_unpack() for their usage info
printvar( fmt_pack( "3cf", 0, 1, 2, 3 ) ); // prints 'string [7] "\x00\x01\x02\x00\x00@@"'
fmt_unpack [function]
fmt_unpack( string fmt, string data )
unpacks the byte buffer data
using the format fmt
, returns unpacked items (possibly in an array)
- if '#' can be found in the format string, all data is returned in, otherwise
- unpacks c/w/l/q/p to integers, f/d to floats, s to strings
- if signed numbers are expected (as set by the "-" modifier), the sign bit of the expected type is extended to the end of the native integer type, this makes the loaded integer signed
- refer to fmt_pack() for more info about the format
print fmt_unpack( "3ld", fmt_pack( "3ld", 0, 1, 2, 3 ) ); // prints [0,1,2,3]
fmt_pack_count [function]
fmt_pack_count( string fmt )
calculates the number of items to be expected in an unpacked array / required to make a successful fmt_pack call
- refer to fmt_pack() for more info about the format
print fmt_pack_count( "3ld" ); // prints 4
fmt_pack_size [function]
fmt_pack_size( string fmt )
calculates the number of bytes generated by a successful fmt_pack call / required to successfully unpack data using the given format
- refer to fmt_pack() for more info about the format
print fmt_pack_size( "3ld" ); // prints 20
fmt_base64_encode [function]
fmt_base64_encode( string data )
encodes data to produce base64 text data
- encoding is done using the following table (shortened): "A-Za-z0-9+/"
print fmt_base64_encode( "hello world" ); // prints "aGVsbG8gd29ybGQ="
fmt_base64_decode [function]
fmt_base64_decode( string b64text )
decodes base64 text data
fmt_base64_decode( fmt_base64_encode( "hello world" ) ) == "hello world" // returns true
fmt_custom_encode [function]
fmt_custom_encode( string text, string class, string prefix, int format, int mindigits = 0, string postfix = "" )
encodes a custom format (selected character codes to numeric version)
Every character (byte) from text
that matches class
is converted to the following format:
prefix
- number according to
format
, at least mindigits
long
postfix
format
must be one of:
FMT_NUMBER_BINARY
- binary (base 2) number
FMT_NUMBER_OCTAL
- octal (base 8) number
FMT_NUMBER_DECIMAL
- decimal (base 10) number
FMT_NUMBER_HEX
, FMT_NUMBER_HEX_LC
- lowercase hexadecimal (base 16) number
FMT_NUMBER_HEX_UC
- uppercase hexadecimal (base 16) number
Use case example - encode a string for C/C++ source code output:
// character class:
// - '^' - invert class (exclude the following characters/ranges)
// - <space>, '!' - characters to exclude (first printable characters, before quote)
// - '#-~' - character range to exclude (other printable characters, after quote)
// the extra set of quotes around hex code prevent hyperactive parsers from thinking ..
// .. that the following characters might be a part of the hex code
fmt_custom_encode( 'some text', "^ !#-~", '""\\x', FMT_NUMBER_HEX, 2, '""' )
fmt_text [function]
fmt_text( [int prealloc,] string text, ... )
parses all format specifiers in text
and returns the result
see string_format if you need position (argument index) specifications in the format string
prealloc
specifies number of bytes to be preallocated on the buffer to avoid continuous reallocations during string generation
- the general format of a format specifier is as follows: {fmt[size][.prec][r][p<char>]}
- fmt: one-character output type (b-binary, o-octal, d-decimal, x/X-hexadecimal, f-floating-point, g/G-compact floating-point, e/E-scientific floating-point, s-valid string, c-always converted to string)
- size: minimum number of characters to print
- prec: precision of floating-point variables, string length limit
- r: add "r" to right-pad (left-justify)
- p<char>: add "p" and any character to set that character as the padding character (default: space/0x20)
- if anything unexpected happens, this function will emit a warning and put "#error#" in the place of a format specifier
print fmt_text( "{d} -> {x}", 1337, 1337 ); // prints "1337 -> 539"
print fmt_text( "null: {d}, {s}, {c}", null, null, null ); // prints "null: #error#, #error#, null" and emits two warnings for item 1 and item 2
print fmt_text( "pi: {f10.10r} {g10r} {E10r}", M_PI, M_PI, M_PI ); // "pi: 3.1415926536 3.14159 3.141593E+000"
fmt_parser [function]
fmt_parser( callable[, buffersize ] )
creates a fmt_parser object, connected to the callable
- the callable is a function that returns at most the number of bytes requested from the stream
- if previous request reached end, subsequent requests must return 'null'
f = io_file( "test.txt", FILE_READ );
// usually it is easier to use @fmt_file_parser instead of the next line of code
p = fmt_parser( function( num ) use( file ){ if( file.eof() ) return null; return file.read( num ); } );
fmt_string_parser [function]
fmt_string_parser( string, offset = 0[, buffersize ] )
creates a fmt_parser object, connected to a string reader object, initialized to the given offset and buffer size
p = fmt_string_parser( "this is a test" );
p.readcc( "a-z" ); // returns "this"
fmt_file_parser [function]
fmt_file_parser( file[, buffersize ] )
creates a fmt_parser object, connected to a file reader object, initialized to the given buffer size
p = fmt_file_parser( io_file( "something.txt", FILE_READ ) );
p.readcc( "a-z" ); // returns something
fmt_charcc [function]
fmt_charcc( string char, string class )
checks if the first character of string char
is included in the character class class
- character class is a regex-like list of specific symbols and ranges (its low and high symbols separated by "-"), optionally prepended by "^" that inverts the scope of the class
fmt_charcc( ".", "a-zA-Z0-9" ); // returns false
fmt_charcc( "x", "a-zA-Z0-9" ); // returns true
fmt_parser [object]
- methods
- read-only properties
- [bool] at_end
- [bool] stream_offset
- other features:
fmt_parser.read [method]
fmt_parser.read( int num )
reads at most num
bytes from stream and returns them as string
- if 0 bytes are returned, it's quite safe to assume that the function has reached the end of file but check the at_end property to be sure
- may return null and emit a warning on unexpected read errors
stream = fmt_string_parser( "action" );
stream.read( 5 ); // returns "actio"
fmt_parser.getchar [method]
fmt_parser.getchar( bool peek = false, bool as_int = false )
returns a character from stream
- if
peek
is true, stream is not advanced (next read operation will also work on the same character)
- if
as_int
is true, character is returned as integer (as one-character string otherwise)
- may return null and emit a warning on unexpected read errors
stream = fmt_string_parser( "action" );
stream.read( true ); // returns "a"
stream.read( true, true ); // returns 97
stream.read(); // returns "a"
stream.read(); // returns "c"
fmt_parser.readcc [method]
fmt_parser.readcc( string class, int num = 2^31-1 (0x7fffffff) )
reads and returns at most num
bytes that match the character class class
- returns null and emits a warning if the class is empty/only contains the inversion symbol "^"
- may return null and emit a warning on unexpected read errors
stream = fmt_string_parser( "what is this" );
stream.readcc( "a-z" ); // returns "what"
stream.readcc( "^a-z" ); // returns " "
fmt_parser.skipcc [method]
fmt_parser.skipcc( string class, int num = 2^31-1 (0x7fffffff) )
skips at most num
bytes that match the character class class
and returns the number of bytes skipped
- returns null and emits a warning if the class is empty/only contains the inversion symbol "^"
- may return null and emit a warning on unexpected read errors
stream = fmt_string_parser( "what is this" );
stream.skipcc( "a-z" ); // returns 4
stream.skipcc( "^a-z" ); // returns 1
fmt_parser.read_real [method]
fmt_parser.read_real( bool as_real = true )
returns characters read with the character class "-+0-9.eE", optionally returned as a real value
fmt_parser.read_int [method]
fmt_parser.read_int( bool as_int = true )
returns characters read with the character class "-+0-9A-Fa-fxob", optionally returned as an int value
fmt_parser.read_binary_int [method]
fmt_parser.read_binary_int( bool as_int = true )
returns characters read with the character class "0-1", optionally returned as an int value
fmt_parser.read_octal_int [method]
fmt_parser.read_octal_int( bool as_int = true )
returns characters read with the character class "0-7", optionally returned as an int value
fmt_parser.read_decimal_int [method]
fmt_parser.read_decimal_int( bool as_int = true )
returns characters read with the character class "-+0-9", optionally returned as an int value
fmt_parser.read_hex_int [method]
fmt_parser.read_hex_int( bool as_int = true )
returns characters read with the character class "0-9a-fA-F", optionally returned as an int value
fmt_parser.check [method]
fmt_parser.check( string str, bool ci = false, bool partial = false )
returns whether the specified string was found at the current position
ci
makes matching case-insensitive
- if
partial
is true, function returns the number of characters successfully matched instead of whether everything has been matched
ALL SGScript formatting functions (A-Z)
I/O library ("io")
This library contains the functions necessary to work with the file system (files and directories).
Functions:
Objects and their methods:
- io_file - file object
- open - open a file
- close - close the currently open file (if any)
- read - read from the open file
- write - write to the open file
- seek - change read/write position in file
- flush - flush the write buffer
- setbuf - change the size and flush trigger of the write buffer or disables it
- io_dir - directory iterator object, for use in "foreach"
Constants:
io_setcwd [function]
io_setcwd( string cwd )
sets the current working directory, returns bool/sets errno
io_getcwd [function]
io_getcwd()
returns the current working directory or null, if for some reason an error occured
- in case of failure, function will set errno
io_getexecpath [function]
io_getexecpath()
returns the path of the executable file the script is executed in
- in case of failure, function will set errno
io_rename [function]
io_rename( string path, string newpath )
attempts to rename the file, returns bool/sets errno
- wraps the C library function rename
- to avoid moving the file/directory, make sure both paths are of the same origin
io_file_exists [function]
io_file_exists( string file )
checks if file exists and is accessible by the process at the moment, returns true on success, false otherwise
- uses the C library functions fopen/fclose
io_dir_exists [function]
io_dir_exists( string dir )
checks if directory exists and is accessible by the process at the moment, returns true on success, false otherwise
- uses the C library functions opendir,closedir where supported properly, Windows API Find*** functions otherwise
io_stat [function]
io_stat( string fsitem )
returns info about the file system item fsitem
, as dict
- the returned object contains the following properties:
- atime: last access time
- ctime: creation time
- mtime: last modification time
- type: enum (one of FST_DIR/FST_FILE/FST_UNKNOWN)
- size: size of item
- uses the C library function stat/_stat
io_dir_create [function]
io_dir_create( string path, int mode = 0o777 )
attempts to create a directory at the specified path, with the specified access mode mode
, returns bool/sets errno
mode
is ignored on Windows
- uses the C library function mkdir/_mkdir
io_dir_delete [function]
io_dir_delete( string path )
attempts to delete a directory at the specified path, returns bool/sets errno
- uses the C library function rmdir/_rmdir
io_file_delete [function]
io_file_delete( string path )
attempts to delete a file at the specified path, returns bool/sets errno
- uses the C library function remove
io_file_write [function]
io_file_write( string path, string data )
writes the byte buffer data
to the file pointed to by path
, returns bool/sets errno
io_file_read [function]
io_file_read( string path )
reads the byte buffer from file at path
, returns buffer as string or null/sets errno
io_file [object]
- methods
- read-only properties
- [int] offset
- [int] size
- [bool] error
- [bool] eof
- other features:
- tobool = returns whether file is open or not
- GC-safe
io_file.open [method]
io_file.open( string name, int mode )
closes the previously open file if any, opens the file name
for operation mode mode
, returns bool/sets errno
mode
must be one of FILE_READ, FILE_WRITE or FILE_READ|FILE_WRITE
- file is always opened in binary mode
f = io_file();
f.open( "file" ); // returns true or false, sets errno accordingly
io_file.close [method]
io_file.close()
closes the previously open file, if any, returns whether the file was open or not
f = io_file( "file.txt" );
f.close(); // returns true if the file existed
f.close(); // returns false
io_file.read [method]
io_file.read( int num )
reads and returns at most num
bytes from file, sets errno
io_file.write [method]
io_file.write( string data )
writes the byte buffer data
to the file, sets errno
io_file.seek [method]
io_file.seek( int off, int mode )
sets the offset in file, returns bool/sets errno
mode
must be one of SEEK_SET (sets as-is), SEEK_CUR (sets relative to current), SEEK_END (sets relative to end)
io_file.flush [method]
io_file.flush()
flushes a buffered file, returns bool
io_file.setbuf [method]
io_file.setbuf( int size )
sets the size of file buffer (0 to disable buffering), returns bool
- buffering allows to avoid committing each write immediately to disk, resulting in a performance gain, however it may introduce issues if application is expected to fail at any moment, resulting in some data not being written in such cases
io_file [function]
io_file([ string name, int mode ])
creates and returns a file, optionally allowing to open it on creation
- see io_file.open() for more info on opening the file
io_dir (directory_iterator) [object]
- features:
- tostring = "directory_iterator"
- iterator interface (key = whether real item, value = item name)
- real items are all except "." and ".."
- returns self as iterator
- GC-safe
- type identification (returns the string "directory_iterator")
io_dir [function]
io_dir( string dir )
creates a directory iterator for the directory dir
, sets errno, returns null and emits a warning on failure
FILE_*** [constants]
FILE_READ, FILE_WRITE
SEEK_*** [constants]
SEEK_SET, SEEK_CUR, SEEK_END
mode constants for io_file.seek
FST_*** [constants]
FST_UNKNOWN, FST_FILE, FST_DIR
file system item type constants for io_stat
ALL SGScript I/O functions (A-Z)
Math library ("math")
This library contains the basic math functions for processing real values.
Functions:
- abs - returns the absolute value of x
- floor - returns rounded-down value of x
- ceil - returns the rounded-up value of x
- round - returns the rounded-to-nearest-integer value of x
- pow - returns x to the power of y
- sqrt - returns a square root of x
- log - returns the logarithm (power) of x for base y
- sin - returns the sine of x
- cos - returns the cosine of x
- tan - returns the tangent of x
- asin - returns arcsine (angle for sine value) of x
- acos - returns arccosine (angle for cosine value) of x
- atan - returns arctangent (angle for tangent value) of x
- atan2 - returns arctangent of x and y, using both values to extend the range of returned value
- deg2rad - returns x degrees as radians
- rad2deg - returns x radians as degrees
Constants:
- M_*** - mathematical constants
abs [function]
abs( x )
returns the absolute value of x
, as real
abs( 2.2 ); // real (2.2)
abs( -3.1 ); // real (3.1)
floor [function]
floor( x )
returns the largest integer that is not bigger than x
, as real
floor( 3.4 ); // real (3)
floor( 3.8 ); // real (3)
floor( 4.2 ); // real (4)
floor( -3.1 ); // real (-4)
ceil [function]
ceil( x )
returns the smallest integer that is not smaller than x
, as real
ceil( 3.4 ); // real (4)
ceil( 3.8 ); // real (4)
ceil( 4.2 ); // real (5)
ceil( -3.1 ); // real (-3)
round [function]
round( x )
returns the closest integer to x
, as real
round( 3.4 ); // real (3)
round( 3.8 ); // real (4)
round( 4.2 ); // real (4)
round( -3.1 ); // real (-3)
pow [function]
pow( x, y )
returns x
raised to the power y
, as real
- If base (
x
) is negative and exponent (y
) is not an integral value, or if base is zero and exponent is negative, function returns null
and emits a warning message.
pow( 2, 5 ); // real (32)
pow( 9, 0.5 ); // real (3)
pow( -1, 0.5 ); // null; Warning: pow(): mathematical error
sqrt [function]
sqrt( x )
returns the square root of x
, as real
- If
x
is negative, function returns null
and emits a warning message.
sqrt( 16 ); // real (4)
sqrt( -1 ); // null; Warning: sqrt(): mathematical error
log [function]
log( x, y )
returns the base-`y` logarithm of x
, as real
- If
x <= 0
or b <= 0
or b = 1
, function returns null
and emits a warning message.
log( 9, 3 ); // real (2)
log( -1, 3 ); // .. or ..
log( 3, 0 ); // .. or ..
log( 3, 1 ); // null; Warning: log(): mathematical error
sin [function]
sin( x )
returns the sine of angle x
in radians, as real
sin( 0 ); // real (0)
sin( M_PI / 2 ); // real (1)
sin( M_PI / 4 ); // real (0.707107)
cos [function]
cos( x )
returns the cosine of angle x
in radians, as real
sin( 0 ); // real (1)
sin( M_PI ); // real (-1)
sin( M_PI / 4 ); // real (0.707107)
tan [function]
tan( x )
returns the tangent of angle x
in radians, as real
tan( 0 ); // real (0)
tan( 1 ); // real (1.55741)
tan( M_PI / 4 ); // real (1)
asin [function]
asin( x )
returns the arcsine of x
(angle in radians), as real
- If
x
is outside the [-1,1] range, function returns null
and emits a warning message
asin( -1 ); // real (-1.5708)
asin( 0 ); // real (0)
asin( 2 ); // null; Warning: asin(): mathematical error
acos [function]
acos( x )
returns the arccosine of x
(angle in radians), as real
- If
x
is outside the [-1,1] range, function returns null
and emits a warning message
acos( -1 ); // real (3.14159)
acos( 0 ); // real (1.5708)
acos( 2 ); // null; Warning: acos(): mathematical error
atan [function]
atan( x )
returns the arctangent of x
(angle in radians), as real
atan( 0 ); // real (0)
atan( 1 ); // real (0.785398)
atan( 9999999 ); // real (1.5708)
atan2 [function]
atan2( y, x )
returns the extended arctangent of y/x (angle in radians), as real
- Signs of
x
and y
are used to determine the quadrant, thus y
is expected to be the sine of the angle to be returned (the y
coordinate of a point) and x
- the cosine (the x
coordinate).
Due to the common requirement to use this function to determine the angle between two somewhat random points (usually from a simulation), it will not emit a warning when both arguments are 0 - it will return 0 instead.
atan2( 0, 1 ); // real (0)
atan2( 1, 0 ); // real (1.5708)
atan2( -1, -1 ); // real (-2.35619)
atan2( 0, 0 ); // real (0)
deg2rad [function]
deg2rad( x )
returns angle, converted from degrees to radians, as real
deg2rad( 0 ); // real (0)
deg2rad( 180 ); // real (3.14159)
deg2rad( -90 ); // real (-1.5708)
rad2deg [function]
rad2deg( x )
returns angle, converted from radians to degrees, as real
rad2deg( 0 ); // real (0)
rad2deg( M_PI ); // real (180)
rad2deg( -M_PI / 2 ); // real (-90)
M_*** [constants]
M_PI
the ratio of circumference of a circle to its diameter (pi)
- the value of this constant is
3.14159265358979323846
M_E
the natural logarithmic base (e)
- the value of this constant is
2.7182818284590452354
ALL SGScript math functions (A-Z)
OS library ("os")
- environment variables
- time and date
- locale / regional settings
Functions:
Constants:
os_gettype [function]
os_gettype()
returns the name of the closest known match for the operating system type, defined at library compile time
- the function can detect and return the following OSes at the moment (with the preprocessor define in braces):
- "Windows" (_WIN32/__WIN32__/__WINDOWS__)
- "Mac OS X" (__APPLE__)
- "Android" (__ANDROID__)
- "Linux" (__linux/__linux__)
- "Unix" (__unix/__unix__)
- "POSIX" (__posix)
- "Unknown" (..any other)
os_command [function]
os_command( string cmd )
passes a command to the OS command processor, returns the integer return value
this function can be extremely unsafe in multithreaded/incontrollable environments due to the completely undefined outcome of the call
- uses the C library function 'system'
os_getenv [function]
os_getenv( string var )
returns the value for the environment variable var
or null, if there is no such value
os_putenv [function]
os_putenv( string cmd )
sets the value for the environment variable specified in command cmd
, returns success as bool
cmd
has the format "<name>=<value>"
os_time [function]
os_time( real tz = <local> )
returns the time in seconds, as integer, optionally from a different time zone tz
os_get_timezone [function]
os_get_timezone( bool as_string = false )
returns the time zone set in the operating system, optionally as string in the format "(+/-)HH:MM"
os_date_string [function]
os_date_string( string fmt, int time = os_time() )
returns the date/time string in the format fmt
, optionally for a different time time
- the following item specifiers are supported (*-local-specific):
- %a: abbreviated weekday name *
- %A: full weekday name *
- %b: abbreviated month name *
- %B: full month name *
- %c: full date/time *
- %x: full date *
- %X: full time *
- %Z: timezone name/abbreviation (could be an empty string) *
- %U: week number with first Sunday as the first day of week one *
- %W: week number with first Monday as the first day of week one *
- %C: year/100, as integer
- %d: zero-padded day of the month (01-31)
- %e: space-padded day of the month ( 1-31)
- %F: date, shortcut of "%Y-%m-%d"
- %H: hour in 24h format (00-23)
- %I: hour in 12h format (01-12)
- %j: day of the year (001-366)
- %m: month number (01-12)
- %M: minute (00-59)
- %p: AM or PM
- %R: hour/minute time, shortcut to %H:%M
- %s: second (00-61)
- %T: time, shortcut to %H:%M:%S
- %u: weekday with Sunday as 0
- %w: weekday with Monday as 1
- %y: 2-digit year (00-99)
- %Y: year
- %f: file-safe full time, shortcut to %Y-%m-%d_%H-%M-%S
- %t: the UNIX timestamp
- %%: prints "%"
- %<any other>: prints both characters
os_parse_time [function]
os_parse_time( int time = os_time() )
returns time
split into parts, as dict
- the returned dict contains the following properties (all are integers):
- year (1900-????)
- month (1-12)
- day (1-31)
- weekday (1-7)
- yearday (1-366)
- hours (0-23)
- minutes (0-59)
- seconds (0-61)
os_make_time [function]
os_make_time( int sec, int min = 0, int hour = 0, int mday = 0, int mon = 0, int year = 0 )
returns time as UNIX timestamp, generated from the arguments, using them as hints (under-/overflows may have some unexpected behavior)
os_get_locale [function]
os_get_locale( int which )
returns the currently set locale for the specified category
which
must be one of the LC_ constants
- the returned string is platform-specific
- wraps the C library function setlocale
os_set_locale [function]
os_set_locale( int which, string locale )
sets the locale for the specified category, returning whether the call was successful
which
must be one of the LC_ constants
- the available locale strings are platform-specific
- wraps the C library function setlocale
os_get_locale_format [function]
os_get_locale_format()
retrieve the formatting info of the currently set locale as a dict
- wraps the C library function localeconv
- the returned data is identical to pre-C99 format of struct lconv
os_locale_strcmp [function]
os_locale_strcmp( string a, string b )
compare two strings using locale to return correct sign for inequalities (good for language-correct sorting)
- expected encoding depends on the platform and the locale that is currently set
- wraps the C library function strcoll
LC_*** [constants]
These constants specify the categories for which locale can be changed.
- LC_ALL affects every locale-related function
- LC_COLLATE: os_locale_strcmp
- LC_MONETARY: os_get_locale_format
- LC_NUMERIC: os_get_locale_format
- LC_TIME: os_date_string
ALL SGScript OS functions (A-Z)
Regular expression library ("re")
This library includes regular expression match & replace functions.
Functions:
- re_match - check for first match in string for pattern
- re_match_all - check for all matches in string for pattern
- re_replace - replace all matches in string for pattern with the specified string
Constants:
re_match [function]
re_match( string str, string pattern, int flags = 0, int offset = 0 )
check for matches in string str
for pattern
, returning whether a match was found or details of the first match, as specified in flags
offset
specifies the character to start matching from, negative offset is subtracted from the end
flags
expect RE_RETURN_CAPTURED, RE_RETURN_OFFSETS or RE_RETURN_BOTH, which is a combination of the previous two
- if
flags
is one of the special values, function returns an array of captured ranges
- each entry is either a string (on RE_RETURN_CAPTURED) or an array of beginning and end offsets (at positions 0 and 1, respectively, on RE_RETURN_OFFSETS) or an array of a string and the beginning and end offsets (on RE_RETURN_BOTH)
- the first character in the pattern specifies a delimiter that separates the pattern from modifiers
- example pattern strings: "/^[a-z]+/mi", "#[a-z0-9_]+.*?#s"
- more info about the supported features and modifiers at https://github.com/snake5/sgregex
re_match_all [function]
re_match_all( string str, string pattern, int flags = 0, int offset = 0 )
check for matches in string str
for pattern
, returning the number of matches or details of all matches, as specified in flags
- similar to re_match, only difference is in the return value:
- if
flags
is one of the special values, function returns an array of matches where each match is an array of captured ranges
re_replace [function]
re_replace( string str, string pattern, string replacement )
find and replace all occurrences of pattern
in string str
with the replacement
string
- replacement string can contain backreferences in the forms "$[0-9]" or "\[0-9]" (in a string constant, a double backslash is required due to rules in SGScript)
- there can be up to 10 backreferences, 0-9, 0 being the whole match
RE_RETURN_*** [constants]
These constants are used in re_match / re_match_all to specify the format of the return value.
If none of these are specified (flags
= 0), only the success state is returned (true/false/match count).
- RE_RETURN_CAPTURED - return the captured string
- RE_RETURN_OFFSETS - return array of start/end offsets
- RE_RETURN_BOTH - return both the captured string and the start/end offsets in an array
ALL SGScript RegExp functions (A-Z)
String library ("string")
This library contains the string handling functions. In all functions, except the utf-8 ones, it is assumed that strings are byte buffers where each byte is one character. If correct indices are applied, many of them will work with multibyte strings.
Objects:
Functions:
- string_cut - extract a substring from a string from the specified beginning / end offsets
- string_part - extract a substring from a string from the specified offset and length
- string_reverse - reverse the order of bytes in a string
- string_pad - pad one or both sides of a string with a pattern string up to the specified length
- string_repeat - concatenate several copies of the specified string
- string_count - count occurences of a substring in a string
- string_find - find first substring in the string, optionally after the specified position
- string_find_rev - find a substring by walking the string backwards, optionally before the specified position
- string_replace - replace parts of string according to match / replacement strings or arrays
- string_translate - replace parts of string according to the provided match -> replacement mapping dict
- string_trim - trim one or both sides of string, removing the specified or default character set
- string_toupper - convert all ASCII lowercase characters into uppercase equivalents
- string_tolower - convert all ASCII uppercase characters into lowercase equivalents
- string_compare - compare strings as byte arrays
- string_implode - combine an array of strings, putting a separator string between each two consecutive strings
- string_explode - split string into parts, separated by the specified separator string
- string_charcode - get the character code (byte value, as integer) from the specified position in string
- string_frombytes - make a string from an array of integer values, interpreted as bytes
- string_utf8_decode - decode a UTF-8 string into an array of code points
- string_utf8_encode - encode an array of code points into a UTF-8 string
- string_utf8_offset - get byte offset of a specific character
- string_utf8_length - get UTF-8 length of string or its part
- string_utf8_iterator - create an iterator for UTF-8 code points in a string
- string_format - format variables according to the specified format string
Constants:
- STRING_NO_REV_INDEX - used by string_cut / string_part - disable handling of negative indices
- STRING_STRICT_RANGES - used by string_cut / string_part - disable handling of out-of-bounds indices
- STRING_TRIM_LEFT, STRING_TRIM_RIGHT - used by string_trim - specify sides to be trimmed
- STRING_PAD_LEFT, STRING_PAD_RIGHT - used by string_pad - specify sides to be padded
string_utf8_iterator [object]
- read/write properties:
- [int] offset - returns the point in string from which last character was retrieved, can set point in string from which next character will be retrieved
- read-only properties:
- [string] string - returns the string currently being iterated on
- other features:
- iterator (self)
- cloning
- serialization
- GC-safe
string_cut [function]
string_cut( string str, int from[, int to[, int flags]] )
returns a part of string str
, from
and to
being positions of the first and last character returned, respectively
- if
to
is not specified, to
is assumed to be the position of the last character in string str
- if
from
or to
are negative, they point to characters before the end of string (-1 being the last one)
- available values for
flags
:
STRING_NO_REV_INDEX
- emit warnings on negative indices, instead of handling them
STRING_STRICT_RANGES
- emit warnings on out of bounds from
/to
values instead of silently ignoring the outside characters
string_cut( "01234567", 3, 5 ); // string [3] "345"
string_part [function]
string_part( string str, int from[, int len[, int flags]] )
returns a part of string str
, starting at from
, at most len
characters
- if
len
is not specified, len
is assumed to be the number of characters between from
and the end of string str
- if
from
is negative, it points to characters before the end of string (-1 being the last one)
- if
len
is negative, the maximum length of returned string is the sum of len
and string str
length
- available values for
flags
:
STRING_NO_REV_INDEX
- emit warnings on negative indices, instead of handling them
STRING_STRICT_RANGES
- emit warnings on out of bounds from
/len
values instead of silently ignoring the outside characters
string_part( "01234567", 3, 3 ); // string [3] "345"
string_reverse [function]
string_reverse( string str )
returns str
with all the bytes in reversed order
This function will not work correctly with multibyte-encoded strings.
string_reverse( "noitca" ); // string [6] "action"
string_pad [function]
string_pad( string str, int tgtsize, string padstr = " ", int flags = STRING_PAD_RIGHT )
return the string str
, padded from template padstr
up to the size tgtsize
according to flags
- if
str
is longer than tgtsize
, it is returned without changes
- available values for
flags
:
STRING_PAD_LEFT
- pad the string at the left side
STRING_PAD_RIGHT
- pad the string at the right side
- if both flags are OR'ed together, the string
str
is centered
- at least one of the flags must be specified if the argument is passed for the function to work
string_pad( "padded", 10 ); // string [10] "padded "
string_pad( "center", 10, "_", STRING_PAD_LEFT | STRING_PAD_RIGHT ); // string [10] "__center__"
string_repeat [function]
string_repeat( string str, int count )
return the string str
, appended to itself `count`-1 times or an empty string if count
is equal to 0
count
must be greater than or equal to 0
string_repeat( "na", 6 ); // string [12] "nananananana"
string_repeat( "none", 0 ); // string [0] ""
string_count [function]
string_count( string str, string substr, bool overlap = false )
returns the number of substrings substr
found in string str
- if
overlap
is true, function does not skip substrings when they are found
string_count( "abababa", "aba" ); // int 2
string_count( "abababa", "aba", true ); // int 3
string_find [function]
string_find( string str, string substr, int offset = 0 )
returns the position of first found substring substr
in string str
, starting at offset
- if
substr
was not found, 'null' is returned
- if
offset
is less than 0, it specifies offset from the end
string_find( "what hat", "hat" ); // int 1
string_find( "what", "hat", 2 ); // null
string_find_rev [function]
string_find_rev( string str, string substr, int offset = 0 )
returns the position of last found substring substr
in string str
, starting at offset
- if
substr
was not found, 'null' is returned
- if
offset
is less than 0, it specifies offset from the end
string_find_rev( "what hat", "hat" ); // int 5
string_find_rev( "what", "hat", 2 ); // int 1
string_replace [function]
string_replace( string str, string from, string to )
string_replace( string str, array from, string to )
string_replace( string str, array from, array to )
replaces parts of string str
, specified in from
, to the respective values passed in to
- the respective replacement is picked by taking the substring index and performing modulo operation with the number of replacement strings
string_replace( "loaded %num files", "%num", 5 ); // string [14] "loaded 5 files"
string_replace( "abcd", ["a","b","c","d"], [1,2,3,4] ); // string [4] "1234"
string_replace( "1234", ["1","2","3","4"], ["x","y"] ); // string [4] "xyxy"
string_translate [function]
string_translate( string str, iterable repmap )
replaces parts of string str
, specified in the keys of repmap
, to the matching values of the same iterable
string_translate( "found %a files and %b folders", {"%a" = 5, "%b" = 17} ); // string [28] "found 5 files and 17 folders"
string_trim [function]
string_trim( string str, string chars = " \t\r\n", int flags = STRING_TRIM_LEFT | STRING_TRIM_RIGHT )
removes the specified characters from the specified sides of the string
- available values for
flags
:
STRING_TRIM_LEFT
- trim the string from the left side
STRING_TRIM_RIGHT
- trim the string from the right side
string_trim( " space " ); // string [5] "space"
string_trim( "..something!..", ".!", STRING_TRIM_RIGHT ); // string [11] "..something"
string_toupper [function]
string_toupper( string str )
converts all ASCII lowercase letter characters of the string to uppercase
string_toupper( "Test" ); // string [4] "TEST"
string_tolower [function]
string_tolower( string str )
converts all ASCII uppercase letter characters of the string to lowercase
string_toupper( "Test" ); // string [4] "test"
string_compare [function]
string_compare( string str1, string str2, int max = 0, int from = 0 )
compares the two strings or the specified portions of them
string_compare( "what", "whaT" ); // int 1
string_compare( "what", "whaT", 3 ); // int 0
string_compare( "file.txt", ".txt", 0, -4 ); // int 0
string_implode [function]
string_implode( array items, string sep )
concatenates the string representations of array items
values, putting a string sep
between each two
string_implode( ["one","two","three"], ", " ); // string [15] "one, two, three"
string_explode [function]
string_explode( string str, string sep )
splits the string str
into an array of substrings, separated by string sep
string_explode( "www.example.com", "." ); // ["www","example","com"]
string_explode( "x", "-" ); // ["x"]
string_explode( "/some//data", "/" ); // ["","some","","data"]
string_charcode [function]
string_charcode( string str, int offset = 0 )
returns the byte value / ASCII character code of the specified byte in the string
string_charcode( "Test" ); // int 84
string_charcode( "Test", 3 ); // int 116
string_frombytes [function]
string_frombytes( int byteval )
string_frombytes( array bytes )
returns a string, created from either one byte value (overload #1) or an array of byte values (overload #2)
- byte values must be in the range [0-255]
string_frombytes( 53 ); // string [1] "5"
string_frombytes([ 84, 101, 115, 116 ]); // string [4] "Test"
string_utf8_decode [function]
string_utf8_decode( string ustr )
returns an array of Unicode code points, decoded from the UTF-8 string ustr
- invalid byte sequences will add 0xFFFD to the array
string_utf8_decode( "pie" ); // [112,105,101]
string_utf8_decode( "код" ); // [1082,1086,1076]
string_utf8_decode( "標準" ); // [27161,28310]
string_utf8_encode [function]
string_utf8_encode( array cplist )
returns a UTF-8 string, composed from the Unicode code point list cplist
string_utf8_encode([ int cp0[, int cp1, ... ]])
returns a UTF-8 string, composed from the Unicode code point list passed in argument list
Without proper terminal software UTF-8 strings will not be displayed correctly (as is the case on Windows).
- invalid code points will add "\xEF\xBF\xBD" (0xFFFD code point as UTF-8) to the string
string_utf8_encode( [112,105,101] ); // string [3] "pie"
string_utf8_decode( [1082,1086,1076] ); // string [6] "код"
string_utf8_decode( [27161,28310] ); // string [6] "標準"
string_utf8_offset [function]
string_utf8_offset( string ustr, int charnum[, int byteoff ])
returns byte offset of character in UTF-8 string, optionally skipping the specified number of bytes
- valid character numbers are 0 to actual number of characters from specified byte offset
- valid byte offsets are 0 to ustr.length
string_utf8_offset( "標準", 2 ); // returns 6
string_utf8_length [function]
string_utf8_length( string ustr, int byteoff = 0[, int numbytes[, int flags ]])
returns length of UTF-8 string or the specified part of it
string_utf8_length( "標準", 3 ); // returns 1
string_utf8_iterator [function]
string_utf8_iterator( string ustr, int byteoff = 0 )
creates a UTF-8 code point iterator object
it = string_utf8_iterator( "標準" ); // returns string_utf8_iterator object
iter_advance( it ); // go to position 0
iter_getdata( it ); // returns 27161
string_format [function]
string_format( [int prealloc,] string text, ... )
parses all format specifiers in text
and returns the result
see fmt_text if you don't need the position (argument index) specifications
prealloc
specifies number of bytes to be preallocated on the buffer to avoid continuous reallocations during string generation
- the format specifier has the form {<id>:<specifier>} where "id" is the argument index to use and specifier is a fmt_text specifier
- argument indices to be used in specifiers start from 1
print string_format( "{1:d} -> {1:x}", 1337 ); // prints "1337 -> 539"
ALL SGScript string functions (A-Z)
Included tools
Executables
Extensions
Virtual Machine (sgsvm)
This is the default standalone environment for SGScript, useful for running scripts in a portable way.
Command line syntax
sgsvm [files|options]
sgsvm [options] -p|--program <srcname>[, <arguments>]
Options
-h
, --help
: print help text, displaying command line syntax
-v
, --version
: print version info
-s
, --separate
: restart the engine between scripts
-d
, --debug
: enable interactive debugging on errors
-p
, --program
: translate the following arguments into a SGS program call
--stats
: print VM stats after running the scripts
- prints number of allocations, frees, memory blocks and size, object count, GC state
--profile
: enable profiling by collecting call stack timings
--profile-ops
: enable low-level VM instruction profiling
--profile-mem
: enable memory usage profiling
Example usage
sgsvm -d -p appMain param=1
- run application appMain
with debugging, passing argument 'param=1'
sgsvm one.sgs two.sgs
- run file one.sgs
, followed by two.sgs
, in the same environment
Additional info
- Program mode defines global
argc
and argv
variables, generated from arguments after the flag.
- It is possible to execute multiple files, this is so that environment could be prepared by one file and used by another one.
- Profilers dump their data to standard output before freeing the engine (after end of each separately executed script or at the end of all scripts).
Compiler (sgsc)
This is the standalone script compiler and instruction listing generator for SGScript.
Command line syntax
sgsc [file|options]
Additional info
-h
: print help info
-c
: compile the file
-d
: dump bytecode to standard output
-o
: specify bytecode output file (default: remove .sgs on end, add .sgc)
Example usage
sgsc -c src.sgs
- compile src.sgs
to src.sgc
sgsc -d src.sgs
- compile src.sgs
, dump generated bytecode
Executable generator for Windows (sgsexe)
Utility to combine a single script with the virtual machine. After compilation, the executable passes all input arguments as-is as argc
and argv
to the script.
Command line syntax
sgsexe <output-file> <script-file>
Language test application (sgstest)
The application runs all test scripts in ./tests
directory. File handling rules are as follows:
- Ignore files with
!_
prefix.
- Require compilation success for tests with
s_
prefix.
- Require compilation failure for tests with
f_
prefix.
- If there is no prefix, require that the system does not crash.
- If a file name as
TF
in it, use the advanced testing framework.
- Files are sorted according to the logical order of testing: requirements grow with test file number:
- first sort by whether testing framework (TF) is required (files that don't need it go first);
- then sort by whether compilation success is required (files that do need it go first);
- finally, sort by whether compilation state is expected (files that do need it go first);
The sort order broken down:
- 1.
s_
tests without TF
- 2.
f_
tests without TF
- 3. tests without prefix and
TF
- 4.
s_
tests with TF
- 5.
f_
tests with TF
(none such tests exist because it would make no sense to have them)
- 6. tests without prefix but with
TF
The application sgstest
must be run from root, like so: bin/sgstest
. It generates two log files: ./tests-errors.log
and ./tests-output.log
.
API test application (sgsapitest)
This application tests the core programming interface. It generates two log files: ./apitests-errors.log
and ./apitests-output.log
.
C++ binding compiler test application (sgscppbctest)
This application tests the C++ programming interface that utilizes the binding compiler.
Multithreading safety test application (mttest)
This application tests the SGScript engine's ability to work with more than one thread (different instances for each) at the same time.
Profiler
This is an engine profiler hook extension. It supports three processing modes.
Modes
- Function timing profiler: use SGS_PROF_FUNCTIME to initialize
- Instruction timing profiler: use SGS_PROF_OPTIME to initialize
- Memory usage profiler: use SGS_PROF_MEMUSAGE to initialize
Functions
- void sgs_ProfInit( sgs_Context* C, sgs_Prof* P, int mode ) - initialize the profiler
- void sgs_ProfClose( sgs_Prof* P ) - free the profiler
- void sgs_ProfDump( sgs_Prof* P ) - dump the data
Usage example
sgs_Prof profiler; // keep this allocated while it is linked to engine
// initialize and attach the profiler
sgs_ProfInit( contextPtr, &profiler, [SGS_PROF_FUNCTIME|SGS_PROF_OPTIME|SGS_PROF_MEMUSAGE] );
// ...do things with the engine...
sgs_ProfDump( &profiler ); // dump the data (done through @sgs_Write* functions)
// free the profiler - must be done before freeing the engine
sgs_ProfClose( &profiler );
Interactive debugger
This is an engine debugging hook extension. It provides the opportunity to interactively introspect the engine state on each message (info/warning/error).
Functions
- int sgs_InitIDbg( sgs_Context* C, SGS_IDBG ) - initialize the debugger
- int sgs_CloseIDbg( sgs_Context* C, SGS_IDBG ) - free the debugger
Usage example
sgs_IDbg debugger; // keep this allocated while it is linked to engine
// initialize and attach the debugger
sgs_InitIDbg( contextPtr, &debugger );
// ...do things with the engine...
// free the debugger
sgs_CloseIDbg( contextPtr, &debugger );
Serialization in SGScript
In SGScript, serialization is conversion to a binary stream of a specific format. Serialization in the language API is done by calling the "serialize" function and deserialization is done with "unserialize". The C API has similar functions: sgs_Serialize(Ext) / sgs_SerializeObject and sgs_Unserialize, respectively.
check the "Possible gotchas" part of this page if it is intended to trust the end user with access to serialized data
The format (modes 1 and 2)
- a list of operations
- each operation consists of a 'type' byte and additional data
- a "push" operation has the byte 'P', the data consists of the type to push (a byte consisting of one base flag from SGS_VT_*) and the binary data of the type
- a "call" operation has the byte 'C', the following data differs between formats:
- MODE 1: number of arguments (4 bytes), function name length (1 byte) and the null-terminated function name itself (<length>+1 bytes)
- MODE 2: number of arguments (4 bytes), function name length (1 byte), argument indices (4 bytes for each, count as previously specified) and the null-terminated function name itself (<length>+1 bytes)
The format (mode 3)
- SGScript Object Notation (SGSON) - a minimal version of the script syntax for defining data
- Supported features:
- keywords:
null
, false
, true
- integers and real values
- strings (
"..."
or '...'
)
- containers:
- array:
[...]
- dict:
{ a = 1, b = "x" }
- map:
map{ [false] = 5, [{}] = "test" }
- function calls:
<identifier>(<arg1>, <arg2>, ... <argN>)
Serialization
- "serialize" is called
- "sgs_Serialize(Ext)" is called internally
- type of variable is determined and the data is written
- C functions cannot be serialized and whenever encountered, will abort the action
- objects will have SERIALIZE operation called
- if operation is not defined, everything will stop
- if object is an array, all variables in it will be serialized using sgs_Serialize(Ext) and sgs_SerializeObject will generate a call to 'array'
- if object is a 'dict' or a 'map', all keys and values in it will be serialized using sgs_Serialize and sgs_SerializeObject will generate a call to 'dict'/'map'
Deserialization
- "unserialize" is called
- "sgs_Unserialize(Ext)" is called internally
- "push", "call", "symbol" operations are executed, thus regenerating the data
- "push" operation pushes a variable on the stack
- "call" operation calls the specified function
- "symbol" operation resolves the given string to a variable from the symbol table
Possible gotchas
- unserialization is not by default safe in the sense that any function can be executed with a carefully crafted byte buffer; this can be prevented by temporarily replacing the global environment (_G)
- if environment overrides are used on deserialization, remember to add "array", "dict" and "map" to the list if you use them, they are not always supported automatically
- mode 1/3 serialization will not preserve any variable reuse relationships so after deserialization the structure could use more memory than before; if more efficient behavior is desired, it is suggested to use mode 2 (default) instead
Secure sandbox environment
To ensure safety of the underlying environment, there are functions that need to be protected or disabled.
Critical (access to file system, possibility of taking control of the machine):
Information control (access to data about the system)