2.5. The Stack
Quirrel exchanges values with the virtual machine through a stack. This mechanism has been inherited from the language Lua. For instance to call a Quirrel function from C it is necessary to push the function and the arguments in the stack and then invoke the function; also when Quirrel calls a C function the parameters will be in the stack as well.
2.5.1. Stack indexes
Many API functions can arbitrarily refer to any element in the stack through an index. The stack indexes follow those conventions:
1 is the stack base
Negative indexes are considered an offset from top of the stack. For instance -1 isthe top of the stack.
0 is an invalid index
Here an example (let’s pretend that this table is the VM stack)
STACK |
positive index |
negative index |
---|---|---|
“test” |
4 |
-1(top) |
1 |
3 |
-2 |
0.5 |
2 |
-3 |
“foo” |
1(base) |
-4 |
In this case, the function sq_gettop would return 4;
2.5.2. Stack manipulation
The API offers several functions to push and retrieve data from the Quirrel stack.
To push a value that is already present in the stack in the top position:
void sq_push(HSQUIRRELVM v,SQInteger idx);
To pop an arbitrary number of elements:
void sq_pop(HSQUIRRELVM v,SQInteger nelemstopop);
To remove an element from the stack:
void sq_remove(HSQUIRRELVM v,SQInteger idx);
To retrieve the top index (and size) of the current virtual stack you must call sq_gettop
SQInteger sq_gettop(HSQUIRRELVM v);
To force the stack to a certain size you can call sq_settop
void sq_settop(HSQUIRRELVM v,SQInteger newtop);
If the newtop is bigger than the previous one, the new positions in the stack will be filled with null values.
The following function pushes a C value into the stack:
void sq_pushstring(HSQUIRRELVM v,const SQChar *s,SQInteger len);
void sq_pushfloat(HSQUIRRELVM v,SQFloat f);
void sq_pushinteger(HSQUIRRELVM v,SQInteger n);
void sq_pushuserpointer(HSQUIRRELVM v,SQUserPointer p);
void sq_pushbool(HSQUIRRELVM v,SQBool b);
this function pushes a null into the stack:
void sq_pushnull(HSQUIRRELVM v);
returns the type of the value in a arbitrary position in the stack:
SQObjectType sq_gettype(HSQUIRRELVM v,SQInteger idx);
the result can be one of the following values:
OT_NULL,OT_INTEGER,OT_FLOAT,OT_STRING,OT_TABLE,OT_ARRAY,OT_USERDATA,
OT_CLOSURE,OT_NATIVECLOSURE,OT_GENERATOR,OT_USERPOINTER,OT_BOOL,OT_INSTANCE,OT_CLASS,OT_WEAKREF
The following functions convert a quirrel value in the stack to a C value:
SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c);
SQRESULT sq_getstringandsize(HSQUIRRELVM v,SQInteger idx,const SQChar **c,SQInteger size);
SQRESULT sq_getinteger(HSQUIRRELVM v,SQInteger idx,SQInteger *i);
SQRESULT sq_getfloat(HSQUIRRELVM v,SQInteger idx,SQFloat *f);
SQRESULT sq_getuserpointer(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p);
SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag);
SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *p);
The function sq_cmp compares 2 values from the stack and returns their relation (like strcmp() in ANSI C).:
SQInteger sq_cmp(HSQUIRRELVM v);