![]() |
Hide Changes |
![]() |
Edit |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
![]() |
Administration Page |
![]() |
Topic Locks |
Search |
History
3/17/2017 9:25:05 AM |
-85.76.7.116 |
11/21/2016 1:36:53 PM |
-207.244.89.107 |
12/26/2014 5:14:52 PM |
-84.163.31.193 |
7/5/2014 5:12:14 AM |
-88.181.126.101 |
3/2/2014 4:46:53 PM |
-24.225.231.24 |
![]() |
List all versions |
NEEDS MORE BETTER DOCUMENTATION
Check out the formatting tips on the right for help formatting and making links.
Use the template below:
This tutorial explains step by step how to build a minimal application that embed squirrel, load and run a script.
First let's take a look at the following script and C code, later I'll be explaing in detail what they do.
squirrel code
function foo(i, f, s) { print("Called foo(), i="+i+", f="+f+", s='"+s+"'"); }
and this C code
C code
#include <stdarg.h> #include <stdio.h> #include <squirrel.h> #include <sqstdio.h> #include <sqstdaux.h> #ifdef _MSC_VER #pragma comment (lib ,"squirrel.lib") #pragma comment (lib ,"sqstdlib.lib") #endif #ifdef SQUNICODE #define scvprintf vwprintf #else #define scvprintf vprintf #endif void printfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list arglist; va_start(arglist, s); scvprintf(s, arglist); va_end(arglist); } void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) { int top = sq_gettop(v); //saves the stack size before the call sq_pushroottable(v); //pushes the global table sq_pushstring(v,_SC("foo"),-1); if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table sq_pushroottable(v); //push the 'this' (in this case is the global table) sq_pushinteger(v,n); sq_pushfloat(v,f); sq_pushstring(v,s,-1); sq_call(v,4,0,0); //calls the function } sq_settop(v,top); //restores the original stack size } int main(int argc, char* argv[]) { HSQUIRRELVM v; v = sq_open(1024); // creates a VM with initial stack size 1024 sqstd_seterrorhandlers(v); sq_setprintfunc(v, printfunc, NULL); //sets the print function sq_pushroottable(v); //push the root table(were the globals of the script will be stored) if(SQ_SUCCEEDED(sqstd_dofile(v, _SC("test.nut"), 0, 1))) // also prints syntax errors if any { call_foo(v,1,2.5,_SC("teststring")); } sq_pop(v,1); //pops the root table sq_close(v); return 0; }
The first thing you have to do is create a virtual machine(VM)
HSQUIRRELVM v = sq_open(1024);
1024 is the initial stack size
squirrel stack grows automatically so this value is just a hint to the VM
Squirrel allows to define your own error handling function, this sample uses the prebuilt on from the standard IO library.
sqstd_seterrorhandlers(v);
in order to allow functions like print()
to output some text is necessary to provide
a print-function to the VM.
sq_setprintfunc(v, printfunc, NULL); //sets the print function
where printfunc
is defined as follows
void printfunc(HSQUIRRELVM v, const SQChar *s, ...) { va_list arglist; va_start(arglist, s); scvprintf(s, arglist); va_end(arglist); }
and third parameter NULL tell the VM we don't want handle the errors.
Squirrel offers a low level API to compile and run scripts from any kind of media,
however, 90% of the time, the script will be a simple text file and you will want to run it
right after compilation. The easiest way to archieve this is to use the standard IO library (sqstdio.h
).
sqstd_dofile
compiles a script and runs it.
sq_pushroottable(v); sqstd_dofile(v, "myscript.nut",0);
sqstd_dofile
expects an object on top of the stack(in this case the root table) that will be
used as this
during the execution of the script.
The squirrel script we are taking as example defines a function called foo
.
In order to call the function first we have to retrieve it and place it on the stack.
Because the function was declared in the global scope, it is stored in the root table.
void call_foo(HSQUIRRELVM v, int n,float f,const SQChar *s) { int top = sq_gettop(v); //saves the stack size before the call sq_pushroottable(v); //pushes the global table sq_pushstring(v,_SC("foo"),-1); if(SQ_SUCCEEDED(sq_get(v,-2))) { //gets the field 'foo' from the global table sq_pushroottable(v); //push the 'this' (in this case is the global table) sq_pushinteger(v,n); sq_pushfloat(v,f); sq_pushstring(v,s,-1); sq_call(v,4,0,0); //calls the function } sq_settop(v,top); //restores the original stack size }
call_foo
calls the foo
function passing an integer, a float and a string as parameters.
Let's analyze it line by line.
First it stores the current stack size for cleaning it up after the call.
int top = sq_gettop(v);
Pushes the root table, where the function will be fetched from.
sq_pushroottable(v);
negative index | object |
-1 | root table |
... | ... |
stack situation
Pushes the string "foo"
that in this case is the name of the slot that contains the function
we want to fetch.
sq_pushstring(v,_SC("foo"),-1);
the parameter -1 specifies that the VM should compute the string length automatically.
negative index | object |
-1(top) | "foo" |
-2 | root table |
... | ... |
stack situation
Then fetches the function
if(SQ_SUCCEEDED(sq_get(v,-2))) {
The function sq_get
, pops an object from the stack(in this case the string "foo")
and uses it as key to fetch the object at position -2 from the top of the stack(in this case
the root table). If the function succeed, it pushes the result in the stack.
negative index | object |
-1(top) | function foo(){} |
-2 | root table |
... | ... |
stack situation after sq_get
now the function pushes the parameters in the stack. the root table is pushed again to set it
as this
parameter.Squirrel function always have a hidden parameters this (just like C++ class memebers).
sq_pushroottable(v); sq_pushinteger(v,n); sq_pushfloat(v,f); sq_pushstring(v,s,-1);
negative index | object |
-1(top) | string |
-2 | float |
-3 | integer |
-4 | root table |
-5 | function foo(){} |
-6 | root table |
... | ... |
stack situation
Finally the sq_call
function is invoked. This execute the actual call.
sq_call(v,4,0,0);
4 means that the function has 4 parameters(this,the integer,the float and the string).
Squirrel will then pop the 4 parameters and links. expect a function to be at the top of the stack.
the third parameters set to 0 tells squirrel that no return value is expected from the function
call. If another value than 0 would be specified squirrel would push the return value of the called function.
the fourth parameter set to 0 tells squirrel not to invoke the error handler while runtime errors occur.
negative index | object |
-1(top) | function foo(){} |
-2 | root table |
... | ... |
stack situation after sq_call
the function has been executed so now we reset the stack to the initial state
sq_settop(v,top); //restores the original stack size
previously we pushed the root table once to for executing sqstd_dofile, is time to remove it.
sq_pop(v,1);
at the end of the program we delete the squirrel VM
sq_close(v);