Lgi Scripting Syntax

Variables

Variables are created on demand and don't need to be explicitly declared. Sometimes the host will insert known global variables before the script is run, but that usage pattern is declining as "Main" functions are now used, that allow parameters from outside the script to be passed in via explicit method arguments.

The variables themselves are based on a variant data type, that can contain integers, strings and various pointer types. There is no dereference operator needed to use a pointer type variable. Pointer arithmetic is not supported, as generally the pointers are to single class objects, not arrays of objects. That said there are List and HashTable sub-types to the variables, but no array as such.

Scope

There are 3 fixed scopes: global, local, register. Although in practice when writting code you only ever deal with global and local. Unlike C, there are no extra scope levels inside { } blocks inside a function. Variables defined in that function (including it's arguments) are visible throughout that function. Global variables are defined outside of a function scope and are visible everywhere.

Constructs

Scripts are constructed from these primitives:
if (expression) { statements; }
[else if (expression) { statements; }]
[else { statements; }]
while (expression)
{
    statements;
}
for (initial_expression; condition_expression; iterate_expression)
{
    statements;
}
function method_name([arg1, arg2, ...])
{
    statements;
    [return expression;]
}
struct structure_name
{
    type member1;
    [type member2; ... ]
};
extern "dynamic_library" return_type method_name([type arg1, type arg2, ...]);
return expression;
expression;

Operators

These operators can be used in expressions:
=Assign
+Plus
-Minus
*Multiply
/Divide
%Mod
<LessThan
<=LessThanEqual
>GreaterThan
>=GreaterThanEqual
==Equals
!=Not Equals
+=Plus Equals
-=Minus Equals
*=Multiply Equals
/=Divide Equals
++Post Increment
--Post Decrement
++Pre Increment
--Pre Decrement
&&And
||Or
!Not
.Object member reference

Objects

Some variant types allow the referencing of object members or methods via the '.' operator. The available members depends on the variant type:

List

The list object type allows you to store a bunch of objects in a variable (of the same variant type). To get the length of the list, use var_name.length, and to access the various members use var_name[index_expression] where the exp evaluates to an integer. If you don't specify an integer then you'll get back a NULL variable as the result.

HashTable

HashTable's are very similar to lists, in that they allow you to store a objects in a variable. To get the number of objects in the hash table, use var_name.length, and to access the various members use var_name[index_expression] where the exp evaluates to an string. If you don't specify a string then you'll get back a NULL variable as the result.

Built In Types

These types can be used in defining structures and parameters to external functions:


Some of these types don't have any implementation or testing done. Integers and strings should work fine though.

Custom Types

You can define structures in a similar fashion to C code using the struct keyword. For example:
struct PxRgb24 {
    uint8 r;
    uint8 g;
    uint8 b;
};
struct Image
{
    uint32 Width;
    uint32 Height;
    PxRgb24 Pixels[16 * 16];
};
Packing of structures is currently on 1 byte boundaries, but it would be possible to implement other settings later. The typeid(...) keyword is supported for custom types. e.g.
Obj = New("Image");
if (Obj)
{
    Type = typeid(Obj);
    Print("TypeName=" + Type.Name + ", sizeof=" + Type.Length + "\n");
    Delete(Obj);
}
TypeName=Image, sizeof=772

Calling extern functions

To call methods in dynamic libraries you first have to declare the method using the extern keyword:
extern "dynamic_library" type method([type arg1, type arg2, ...]);
The types for extern functions are somewhat limited to these keywords: More type support will be added as needed. All non-char pointers will become "void*". The dynamic_library will be passed to "dlopen" or "LoadLibrary" pretty much unchanged.

Windows based example:
extern "Kernel32.dll" uint32 GetWindowsDirectoryA(_out_ char *buffer, int size);
buf = New(256); // Allocate a buffer for the return value
r = GetWindowsDirectoryA(buf, buf.Length);
Print("Dir='"+buf+"'");
Dir='c:\Windows'

Casting between types

There is limited support for casting between these types: int, string, date and double. The syntax is just:
my_str.int;
my_str.double;

my_int.string;
my_int.double;

my_dbl.string;
my_dbl.int;

my_date.int;
my_date.string;