Squirrel V3.0 for FreeBASIC (32/64-bit Windows and Linux)

Headers, Bindings, Libraries for use with FreeBASIC, Please include example of use to help ensure they are tested and usable.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Squirrel V3.0 for FreeBASIC (32/64-bit Windows and Linux)

Post by D.J.Peters »

I build Squirrel V3.0.6 for 32/64-bit Windows and Linux
and translated the include files to FreeBASIC.

Squirrel: homepage
Squirrel: forum
Squirrel: wiki
"Squirrel is a high level imperative, object-oriented programming language, designed to be a light-weight scripting language that fits in the size, memory bandwidth, and real-time requirements of applications like video games."
download: fbSquirrel.zip

Joshy
Last edited by D.J.Peters on Oct 12, 2022 18:33, edited 6 times in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

callFreebasic.nut

Code: Select all

const w = 512
const h = 512

local yy=0

screenres(w,h,32)

for(local y=0;y<h;y++) {
  yy=y*y
  screenlock()
  for(local x=0;x<w;x++) {
    pset(x,y,rgb(x,y,x*x + yy))
  }
  screenunlock()
}
callSquirrel.nut

Code: Select all

function foo(i, f, s) 
{ 
    print("Called foo(), i="+i+", f="+f+", s='"+s+"'\n"); 
} 
Last edited by D.J.Peters on Dec 21, 2014 2:42, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

class

Code: Select all

class Vector3 {
  constructor(...) {
    if (vargv.len()>2) {
      x=vargv[0];y=vargv[1];z=vargv[2]
    }
  }
  function tostring() {
    return "x="+x+", y="+y+", z="+z
  }
  // squared
  function length2() {
    return x*x+y*y+z*z
  }
  function length() {
    local l=x*x+y*y+z*z
    if (l!=0.0) l=sqrt(l)
    return l
  }
  function normalize() {
    local l=x*x+y*y+z*z
    if (l!=0.0) {
      l=sqrt(l); x/=l; y/=l; z/=l
    }
  }
  // v = this+other
  function _add(other) {
    return ::Vector3(x+other.x,y+other.y,z+other.z)
  }
  // v = this-other
  function _sub(other) {
    return ::Vector3(x-other.x,y-other.y,z-other.z)
  }
  // v = this * scalar
  function _mul(scalar) {
    return ::Vector3(x*scalar,y*scalar,z*scalar)
  }
  // v = this%other cross product
  function _modulo(other) {
    return ::Vector3(y*other.z - z*other.y,
                     z*other.x - x*other.z,
                     x*other.y - y*other.x)
  }
  x = 0.0; y = 0.0; z = 0.0
}

local v0 = Vector3(1,2,3)*2.0
local v1 = Vector3(1.1,2.2,3.3)
local v2 = v0%v1
print(v2.tostring() + "\n")
v2.normalize()
print(v2.x+","+v2.y+","+v2.z+"\n")
print(v2.length())
Last edited by D.J.Peters on Dec 21, 2014 2:42, edited 1 time in total.
rdc
Posts: 1741
Joined: May 27, 2005 17:22
Location: Texas, USA
Contact:

Post by rdc »

This looks cool Joshy. I'll look at this when I get off work this afternoon. Thanks!
kiyotewolf
Posts: 1009
Joined: Oct 11, 2008 7:42
Location: ABQ, NM
Contact:

Post by kiyotewolf »

How do you compile a *.NUT file.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

kiyotewolf wrote:How do you compile a *.NUT file.
take look inside of "compile.bas"

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

The squirrel reference seams to be complete
but isn't easy for me to get all ideas working
i miss some examples how to combine all the stuff.

If i find out some essential things i will post it here.

For example if you will return an array of integers to the script
you must create (push) a new array OBJECT on the stack
than you can push your integers on the stack and insert (pop)
this integers in the new array OBJECT.

Remember an array OBJECT can be an mix of different data types.
(pushinteger, pushfloat, pushstring, pushobject, ...)
and you can iterate every item with a foreach loop.

returnArray.bas

Code: Select all

function ReturnArray cdecl (v as HSQUIRRELVM) as SQInteger
  sq_newarray(v,0)
  for i as integer=0 to 9
    sq_pushinteger(v,i) ' push 0...9
    sq_arrayinsert(v,-2,i) ' here i use "i" now as position index too
  next
  return 1
end function
embFunc(v,@ReturnArray,"getArray")
getArray.nut

Code: Select all

local a = getArray()

foreach(val in a)
  print("value = " + val + "\n");
result:

Code: Select all

value = 0
value = 1
...
value = 8
value = 9
Last edited by D.J.Peters on Nov 18, 2011 12:33, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

@kiyotewolf

squirrel API reference manual:
sq_compile()
sq_compilebuffer()

If the first two bytes of a file is &HFAFA then it should be a compiled binary script.

&HFAFA = compiled script
&HBBEFBF = script source code in UTF-8
in all aother cases script source code in ASCII

Joshy
Last edited by D.J.Peters on Oct 16, 2015 6:49, edited 2 times in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

Native FreeBASIC class as script class.

If you will use a modern script language
for your game engine or what ever
you can share your native classes with the VM.

for example in an 3D editor with script interface
import / export script

Code: Select all

foreach(object in scene)
  foreach(material in object)
    if material.inuse() file.write(material.write)
  foreach(face in object)
    foreach(vertex in face)
       file.write(vertex.write)
a complete vector class

Code: Select all

' nativeClassTest.bas
' test for native script class
#include once "crt.bi"
#include once "inc/squirrel.bi"
#include once "inc/sqstdlib.bi"

'#define debug

#ifdef DEBUG
#define DPRINT(txt) open err for output as #99:print #99,"dbg:"+txt:close #99
#else
#define DPRINT(txt) :
#endif

type Vector3
  ' script class helpers
  declare        function script_new(v as HSQUIRRELVM) as SQInteger
  declare        function script_push(v as HSQUIRRELVM,idx as SQInteger) as SQInteger
  declare static function script_typetag(typetag as SQUserPointer=0) as SQUserPointer
  ' script class (all C calling)
  declare static function script_typeof      cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_tostring    cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_constructor cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_destructor  cdecl (p as SQUserPointer,size as SQInteger) as SQInteger
  declare static function script_nexti       cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_get         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_set         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_unm         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_add         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_sub         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_mul         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_div         cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_modulo      cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_length      cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_distance    cdecl (v as HSQUIRRELVM) as SQInteger
  declare static function script_normalize   cdecl (v as HSQUIRRELVM) as SQInteger

  ' native class
  declare constructor(v as HSQUIRRELVM)
  declare constructor(p as Vector3 ptr)
  declare constructor(x as SQFloat,y as SQFloat,z as SQFloat)
  declare destructor
  union
    type
    as SQFloat x,y,z,w
    end type
    as SQFloat m(3)
  end union

  private:
  declare sub ClassBegin (v as HSQUIRRELVM)
  declare sub ClassMember(v as HSQUIRRELVM, _
                          sName  as SQChar ptr, _
                          pFunc  as SQFUNCTION, _
                          iCheck as SQInteger, _
                          sMask  as SQChar ptr)
  declare sub ClassEnd   (v as HSQUIRRELVM)


end type
' create new Vector3 instance
function Vector3.script_new(v as HSQUIRRELVM) as SQInteger
  sq_pushroottable(v)
  sq_pushstring(v,"Vector3",-1) ' push name
  sq_rawget(v,-2)               ' pop as instance name
  sq_createinstance(v,-1)       ' new instance
  sq_remove(v,-3)               ' removes the root table
  sq_remove(v,-2)               '`removes the this class
  return 1
end function

' push native instance on script stack
function Vector3.script_push(v as HSQUIRRELVM,idx as SQInteger) as SQInteger
  sq_setinstanceup(v,idx,@this)
  sq_setreleasehook(v,idx,@script_destructor)
  return 1
end function

' set or get the class typetag
function Vector3.script_typetag(typetag as SQUserPointer=0) as SQUserPointer
  static as SQUserPointer tag=0
  if typetag then tag=typetag
  return tag
end function

' return native class type
function Vector3.script_typeof cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_typeof")
  sq_pushstring(v,"Vector3",-1)
  return 1
end function

' return a string representation of the Vector3 class
function Vector3.script_tostring cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_tostring")
  dim as Vector3 ptr pSelf = any
  if(SQ_FAILED(sq_getinstanceup(v,1,@pSelf,script_typetag()))) then
    return sq_throwerror(v,"invalid instance type")
  end if
  dim as string s = str(pSelf->x) & "," & str(pSelf->y) & "," & str(pSelf->z) + chr(0)
  sq_pushstring(v,strptr(s),-1)
  return 1
end function

' var = Vecor3() or var = vector3(vector3) or var = Vector3(x,y,z[,w])
function Vector3.script_constructor cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_constructor")
  dim as SQFloat x,y,z
  ' get the number of params Note param 1=the hidden this pointer
  dim as SQInteger n = sq_gettop(v)
  dim as Vector3 ptr pNew
  ' param
  if (n>3) andalso (sq_gettype(v,4) and SQOBJECT_NUMERIC) then sq_getfloat(v,4,@z)
  if (n>2) andalso (sq_gettype(v,3) and SQOBJECT_NUMERIC) then sq_getfloat(v,3,@y)
  if (n>1) then
    ' is the first param numeric ?
    if (sq_gettype(v,2) and SQOBJECT_NUMERIC) then
      dprint("script_constructor numeric")
      sq_getfloat(v,2,@x)
      pNew=new Vector3(x,y,z)
    ' is the first param instance ?
    elseif (sq_gettype(v,2)=OT_INSTANCE) then
      dprint("script_constructor instance")
      ' is it a instance of
      if(SQ_FAILED(sq_getinstanceup(v,2,@pNew,script_typetag()))) then
        return sq_throwerror(v,"invalid instance type")
      end if
      pNew=new Vector3(pNew)
    else
      return sq_throwerror(v,"must be numeric or instance")
    end if
  end if
  pNew->script_push(v,1)
  return 1
end function

function Vector3.script_destructor cdecl (p as SQUserPointer,size as SQInteger) as SQInteger
  dprint("script_destructor")
  dim as Vector3 ptr pRelease = p
  ' call the native constructor
  if pRelease then delete pRelease
  return 1
end function

' the foreach iterator _nexti
function Vector3.script_nexti cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_nexti")
  dim as Vector3 ptr pSelf
  dim as SQInteger iN=-1
  ' is it a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pSelf,script_typetag()))) then
    return sq_throwerror(v,"_nexti invalid instance type")
  end if
  dim as SQInteger typ = sq_gettype(v,2)
  ' first iterator ? return 'x'
  if (typ = OT_NULL) then
    sq_pushstring(v,"x",-1):return 1
  ' is it a numeric index [0|1|2] ?
  elseif (typ and SQOBJECT_NUMERIC) then
     sq_getinteger(v,2,@iN) ' index
  ' or is it a string index .y|.z|.w ?
  elseif (typ = OT_STRING) then
     dim as SQChar ptr sN
     sq_getstring(v,2,@sN)
     if len(*sN)<>1 then
       return sq_throwerror(v,"_nexti invalid string index [x|y|z]")
     end if
     iN=sN[0] ' first char = index
  endif
  select case as const iN
  ' [0|1|2],x|y|z,X|Y|Z
  case 0,88,120:sq_pushstring(v,"y",-1):return 1
  case 1,89,121:sq_pushstring(v,"z",-1):return 1
  case 2,90,122:return 0
  case else
    return sq_throwerror(v,"_nexti invalid index [0..2] [x..z]")
  end select
end function

' operator _get  var = Vector3.x|y|z or var = Vector3[0|1|2]
function Vector3.script_get cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_get")
  dim as Vector3 ptr pSelf
  dim as SQInteger iN=-1
  ' is it a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pSelf,script_typetag()))) then
    return sq_throwerror(v,"_get invalid instance type")
  end if
  ' is it var = Vector3[0|1|2|3]
  if (sq_gettype(v,2) and SQOBJECT_NUMERIC) then
     sq_getinteger(v,2,@iN) ' index
  ' is it var = Vector3.x|.y|.z|.w ?
  elseif (sq_gettype(v,2) = OT_STRING) then
     dim as SQChar ptr sN
     sq_getstring(v,2,@sN)
     if len(*sN)<>1 then
       return sq_throwerror(v,"_set invalid string index must be x|y|z")
     end if
     iN=sN[0] ' first char = index
  endif
  select case as const iN
  ' [0|1|2] | .x|X | .y|Y | .z|Z
  case 0,88,120:sq_pushfloat(v,pSelf->x)
  case 1,89,121:sq_pushfloat(v,pSelf->y)
  case 2,90,122:sq_pushfloat(v,pSelf->z)
  case else
    return sq_throwerror(v,"_get unknow index must be [0|1|2] or .x|.y|.z")
  end select
  return 1 ' return value on stack
end function

' operator _set Vector3.x|y|z=value or Vector3[0|1|2] = value
function Vector3.script_set cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_set")
  dim as Vector3 ptr pSelf
  ' is it a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pSelf,script_typetag))) then
    return sq_throwerror(v,"_set invalid instance type")
  end if
  dim as SQInteger iN
  ' is it Vector3[0|1|2|3] = var ?
  if (sq_gettype(v,2) and SQOBJECT_NUMERIC) then
     sq_getinteger(v,2,@iN)
  ' is it Vector3.x|.y|.z|.w = var ?
  elseif (sq_gettype(v,2) = OT_STRING) then
     dim as SQChar ptr sN
     sq_getstring(v,2,@sN)
     if len(*sN)<>1 then
       return sq_throwerror(v,"_set invalid string index must be x|y|z")
     end if
     iN=sN[0]
  else
    return sq_throwerror(v,"_set invalid index type")
  endif
  dim as SQFloat f
  sq_getfloat(v,3,@f)
  select case as const iN
  case 0,88,120:pSelf->x=f
  case 1,89,121:pSelf->y=f
  case 2,90,122:pSelf->z=f
  case else
    return sq_throwerror(v,"_set unknow index must be [0|1|2] or .x|.y|.z")
  end select
  return 0 ' no return value on stack
end function

' operator _unm unary minus
function Vector3.script_unm cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_unm")
  dim as Vector3 ptr pL=any,pNew=any
  ' is left param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_unm invalid instance type")
  end if

  ' var = -Vector3
  pNew = new Vector3(-pL->x,-pL->y,-pL->z)
  pNew->script_new(v)
  pNew->script_push(v,-1)
  return 1 ' new instance on stack
end function


' + operator _add
function Vector3.script_add cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_add")
  dim as Vector3 ptr pL=any,pR=any,pNew=any
  ' is left param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_add invalid left instance type")
  end if
  ' is right param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,2,@pR,script_typetag))) then
    return sq_throwerror(v,"_add invalid right instance type")
  end if
  ' var = a + b
  pNew = new Vector3(pL->x+pR->x,pL->y+pR->y,pL->z+pR->z)
  pNew->script_new(v)
  pNew->script_push(v,-1)
  return 1 ' new instance on stack
end function

' - operator _sub
function Vector3.script_sub cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_sub")
  dim as Vector3 ptr pL=any,pR=any,pNew=any
  ' is left param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_add invalid left instance type")
  end if
  ' is right param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,2,@pR,script_typetag))) then
    return sq_throwerror(v,"_add invalid right instance type")
  end if
  ' var = a - b
  pNew = new Vector3(pL->x-pR->x, pL->y-pR->y, pL->z-pR->z)
  pNew->script_new(v)
  pNew->script_push(v,-1)
  return 1 ' new instance on stack
end function

' * operator _mul
function Vector3.script_mul cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_mul")
  dim as Vector3 ptr pL=any,pR=any,pNew=any
  dim as SQFloat f
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_mul invalid left instance type")
  end if
  ' dotproduct = Vector * Vector
  if (sq_gettype(v,2) = OT_INSTANCE) then
    if(SQ_FAILED(sq_getinstanceup(v,2,@pR,script_typetag))) then
      return sq_throwerror(v,"_mul invalid right instance type")
    end if
    f = pL->x*pR->x + pL->y*pR->y + pL->z*pR->z
    sq_pushfloat(v,f)
    return 1
  ' Vector3 = Vector3 * numver
  elseif (sq_gettype(v,2) and SQOBJECT_NUMERIC) then
    sq_getfloat(v,2,@f)
    pNew = new Vector3(pL->x*f,pL->y*f,pL->z*f)
    pNew->script_new(v)
    pNew->script_push(v,-1)
    return 1
  end if
  return SQ_ERROR
end function

' / operator _div
function Vector3.script_div cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_div")
  dim as Vector3 ptr pL=any,pNew=any
  dim as SQFloat f
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_div invalid left instance type")
  end if
  sq_getfloat(v,2,@f)
  if (f=0) then return sq_throwerror(v,"_div divide by 0 ")
  pNew = new Vector3(pL->x/f,pL->y/f,pL->z/f)
  pNew->script_new(v)
  pNew->script_push(v,-1)
  return 1
end function

' % operator _modulo (cross product)
function Vector3.script_modulo cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_modulo")
  dim as Vector3 ptr pL=any,pR=any,pNew=any
  dim as SQFloat f
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_modulo invalid left instance type")
  end if
  if(SQ_FAILED(sq_getinstanceup(v,2,@pR,script_typetag))) then
    return sq_throwerror(v,"_modulo invalid right instance type")
  end if
  ' Vector3 = Vector3 % Vector3
  pNew = new Vector3(pL->y*pR->z - pL->z*pR->y, _
                     pL->z*pR->x - pL->x*pR->z, _
                     pL->x*pR->y - pL->y*pR->x)
  pNew->script_new(v)
  pNew->script_push(v,-1)
  return 1
end function

' float = Vector3.length()
function Vector3.script_length cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_length")
  dim as Vector3 ptr pL=any
  dim as SQFloat f=any
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_length invalid instance type")
  end if
  f = pL->x*pL->x + pL->y*pL->y + pL->z*pL->z
  if (f<>0.0) then f=sqr(f)
  sq_pushfloat(v,f)
  return 1
end function

' float = Vector3.distance(Vector3)
function Vector3.script_distance cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_distance")
  dim as Vector3 ptr pL=any,pR=any
  dim as SQFloat f=any,dx=any,dy=any,dz=any
  ' is left param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_distance invalid left instance type")
  end if
  ' is right param a instance of Vector3 ?
  if(SQ_FAILED(sq_getinstanceup(v,2,@pR,script_typetag))) then
    return sq_throwerror(v,"_distance invalid right instance type")
  end if
  ' float = |a - b|
  dx = pL->x-pR->x: dy=pL->y-pR->y: dz=pL->z-pR->z
  f  = dx*dx + dy*dy + dz*dz
  if (f<>0.0) then f=sqr(f)
  sq_pushfloat(v,f)
  return 1
end function

' Vector3 = Vector3.normalize()
function Vector3.script_normalize cdecl (v as HSQUIRRELVM) as SQInteger
  dprint("_normalize")
  dim as Vector3 ptr pL=any,pNew=any
  dim as SQFloat f
  if(SQ_FAILED(sq_getinstanceup(v,1,@pL,script_typetag))) then
    return sq_throwerror(v,"_normalize invalid left instance type")
  end if
  f = pL->x*pL->x + pL->y*pL->y + pL->z*pL->z
  if (f<>0.0) then f=1.0/sqr(f)
  ' Vector3 = Vector3.normalize()
  pNew = new Vector3(pL->x*f,pL->y*f,pL->z*f)
  pNew->script_new(v)
  pNew->script_push(v,-1)
  return 1
end function

' script class factory
sub Vector3.ClassBegin(v as HSQUIRRELVM)
  sq_pushroottable(v)
  sq_pushstring(v,"Vector3",-1)
  sq_newclass(v,0)
  sq_settypetag(v,-1,script_typetag(@this))
end sub

sub Vector3.ClassMember(v      as HSQUIRRELVM, _
                        sName  as SQChar ptr, _
                        pFunc  as SQFUNCTION, _
                        iCheck as SQInteger, _
                        sMask  as SQChar ptr)
  sq_pushstring(v,sName,-1)
  sq_newclosure(v,pFunc,0)
  sq_setparamscheck(v,iCheck,sMask)
  sq_setnativeclosurename(v,-1,sName)
  sq_createslot(v,-3)
end sub

sub Vector3.ClassEnd(v as HSQUIRRELVM)
  sq_createslot(v,-3)
  sq_pop(v,1)
end sub

' base class constructor
constructor Vector3(v as HSQUIRRELVM)
  dprint("base_constructor")
  ClassBegin(v)
  ClassMember(v,"_typeof"    ,@script_typeof     , 1,0)
  ClassMember(v,"_tostring"  ,@script_tostring   , 1,"x")
  ClassMember(v,"constructor",@script_constructor,-1,". x|n nnn")
  ClassMember(v,"_nexti"     ,@script_nexti      , 2,"x o|s|n")
  ClassMember(v,"_get"       ,@script_get        , 2,"x s|n")
  ClassMember(v,"_set"       ,@script_set        , 3,"x s|n n")
  ClassMember(v,"_unm"       ,@script_unm        , 1,"x")
  ClassMember(v,"_add"       ,@script_add        , 2,"x x")
  ClassMember(v,"_sub"       ,@script_sub        , 2,"x x")
  ClassMember(v,"_mul"       ,@script_mul        , 2,"x x|n")
  ClassMember(v,"_div"       ,@script_div        , 2,"x n")
  ClassMember(v,"_modulo"    ,@script_modulo     , 2,"x x")
  ClassMember(v,"length"     ,@script_length     , 1,"x")
  ClassMember(v,"distance"   ,@script_distance   , 2,"x x")
  ClassMember(v,"normalize"  ,@script_normalize  , 1,"x")
  ClassEnd(v)
end constructor


' native
constructor Vector3(p as Vector3 ptr)
  dprint("native_constructor(Vector3)")
  x=p->x:y=p->y:z=p->z:w=1
end constructor
constructor Vector3(fx as SQFloat,fy as SQFloat,fz as SQFloat)
  dprint("native_constructor(x,y,z)")
  x=fx:y=fy:z=fz:w=1
end constructor
destructor Vector3
  dprint("native_destructor~")
end destructor

sub printfunc cdecl (v as HSQUIRRELVM,s as SQChar ptr,...)
  dim as va_list vl = va_first()
  vfprintf(stdout, s, vl)
end sub

sub errorfunc cdecl (v as HSQUIRRELVM,s as SQChar ptr,...)
  dim as va_list vl = va_first()
  vfprintf(stderr, s, vl)
end sub

' create VM
dim as HSQUIRRELVM v = sq_open(1024)
' optional set handlers
sqstd_seterrorhandlers(v)
sq_setprintfunc(v, @printfunc,@errorfunc)

' save current stack
sq_pushroottable(v)

' register some std libs
sqstd_register_bloblib(v)
sqstd_register_iolib(v)
sqstd_register_mathlib(v)
sqstd_register_stringlib(v)
sqstd_register_systemlib(v)

' register native class
dim as Vector3 BaseVector3 = Vector3(v)

' load/compile and call a script
sqstd_dofile(v, "nativeClassTest.nut", SQFalse, SQTrue)
'restore the stack
sq_pop(v,1)
' delete VM
sq_close(v)

sleep
 

Code: Select all

// nativeClassTest.nut

local a = Vector3(1,2,3)
local b = Vector3(3,4,5)
local c = null
local d = null

print("typeof a = " + typeof a + "\n")

print("a.tostring = " + a + "\n")

print("numeric and string index access\n")
print("b[0] = " + b[0]+ " b.y = " + b.y + " b.z = " + b.z +"\n")

print("foreach iterator ")
foreach(c in b) print("value " + c + " ") ; print("\n")

print("foreach key,iterator ")
foreach(d,c in b) print("key " + d +" value " + c + " ") ; print("\n")

print("unary minus operator ")
c = -a;print("c = -a " + c +"\n")

print("+ operator ")
c = a+b;print("c = a+b " + c +"\n")

print("vector * vector operator ")
c = a*b; print("c = a*b dot prod. " + c +"\n")

print("vector * scalar operator ")
c = a*10; print("c = a*10 " + c +"\n")

print("vector / scalar operator ")
c = a/10; print("c = a/10 " + c + "\n")

print("vector % vector operator ")
c = a%b; print("c = a % b cross prod. " + c + "\n")

c = a.length() // c becomes a float
print("c = a.length() " + c + "\n")

c = a.distance(b) // c becomes a float
print("c = a.distance(b) " + c + "\n")

b = a.normalize() // b becomes a vector
print("b = a.normalize() " + b + "\n")

c = b.length() // c becomes a float
print("c = b.length() " + c +"\n")
Last edited by D.J.Peters on Apr 03, 2011 6:59, edited 2 times in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

a short hint how param checking works

first take a look to the base class constructor

Code: Select all

constructor Vector3(v as HSQUIRRELVM)
  dprint("base_constructor")
  ClassBegin(v)
  ClassMember(v,"_typeof"    ,@script_typeof     , 1,0)
  ClassMember(v,"_tostring"  ,@script_tostring   , 1,"x")
  ClassMember(v,"constructor",@script_constructor,-1,". x|n nnn")
  ClassMember(v,"_nexti"     ,@script_nexti      , 2,"x o|s|n")
  ClassMember(v,"_get"       ,@script_get        , 2,"x s|n")
  ClassMember(v,"_set"       ,@script_set        , 3,"x s|n n")
  ClassMember(v,"_unm"       ,@script_unm        , 1,"x")
  ClassMember(v,"_add"       ,@script_add        , 2,"x x")
  ClassMember(v,"_sub"       ,@script_sub        , 2,"x x")
  ClassMember(v,"_mul"       ,@script_mul        , 2,"x x|n")
  ClassMember(v,"_div"       ,@script_div        , 2,"x n")
  ClassMember(v,"_modulo"    ,@script_modulo     , 2,"x x")
  ClassMember(v,"length"     ,@script_length     , 1,"x")
  ClassMember(v,"distance"   ,@script_distance   , 2,"x x")
  ClassMember(v,"normalize"  ,@script_normalize  , 1,"x")
  ClassEnd(v)
end constructor
ClassMember(v,"_mul" ,@script_mul, 2, "xx|n")

"_mul" = the member name visible for the script engine

@script_mul = the pointer to the member implementation CDECL calling

2 = the number of params

"xx|n" = the param description

x = the first param must be a instance

x|n = the second param can be a instance or a number
( '|' can be used as 'or' to accept multiple types on the same parameter)

'x' a instance can be any class instance (Vector3 here)
'n' a numer can be a 'f'loat or 'i'nteger

vec = vec * float is "xn"
float = vec * vec is "xx"

all types
'o' null
'i' integer
'f' float
'n' number (integer or float)
's' string
't' table
'a' array
'u' userdata
'c' closure and nativeclosure
'g' generator
'p' userpointer
'v' thread
'x' instance
'y' class
'b' bool
'.' any type

Happy scripting

Joshy
Last edited by D.J.Peters on Dec 23, 2014 10:30, edited 4 times in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

Joshy's news from Squirrel universum ;-)

A table{} object differs from array[] object
that every item of a table (a slot) has an key.

Code: Select all

mytable = {
  "any_string_ident_as_key" = any_value_or_object, 
  any_other_ident           = anything, 
  [100]                     = a_number_as_key,
  empty_table_in_this_table = {},
  an_array_inside_the_table = ["item1",1.0, ...]
  ...
}
But a table object is much more powerfull
you can put code directly inside a table.

Code: Select all

mytable = {
  "any_ident_as_key" = any_value_or_object, 
  function foo(a,b)
  {
    return a+b
  }
  ...
}
looks really clever

from this point of view a class is a a kind of table object too

It exist two types of table item assignments

id = value
id <- value

In the first case the item ID as key must exist to assign a new value
in the other case a new slot with the key ID will be inserted if not exists

An other fine thing is a line terminator is ok
that is you don't need the ";" on every line end

const a_const = 1
a_var = 1.0
print("test")

";" is only needed to seperate things on one line

const a_const = 1; a_var = 1.0; print("test")

one source of errors are the language is case sensitive
vector.Length() differs from vector.length() and so on

Happy OO scripting

Joshy
Last edited by D.J.Peters on Dec 21, 2014 2:44, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

Nuts for the squirrel ;-)

I added a native squirrel lib written in FreeBASIC
can be a starting point for your own native squirrel lib.

Joshy

some new examples:
nativeLibTest.bas

compileScriptFromFile.bas
runScriptFromFile.bas
runScriptFromScript.bas

writeByteCodeToFile.bas
runByteCodeFromFile.bas
runByteCodeFromScript.bas
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

added:

from FreeBASIC:
runScriptFromMemory()
runByteCodeFromMemory()

from Script:
var = RunByteCode("mycopiled_scrip.cnut")

Joshy
Last edited by D.J.Peters on Dec 23, 2014 10:35, edited 1 time in total.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

Some new examples and classes.

new native classes:
Int8, Int16, Int32
Float32, Float64
Float32Vector, Float64Vector

list of examples:
callFreebasic.bas
callSquirrel.bas
compileScriptFromFile.bas
compiletimeHandler.bas
getArray.bas
nativeFloat32Test.bas
nativeFloat32VectorTest.bas
nativeFloat64Test.bas
nativeFloat64VectorTest.bas
nativeInt16Test.bas
nativeInt32Test.bas
nativeInt64Test.bas
nativeInt8Test.bas
nativeLibTest.bas
noCompiler.bas
runByteCodeFromFile.bas
runByteCodeFromScript.bas
runScriptFromFile.bas
runScriptFromScript.bas
runtimeHandler.bas
scriptClassTest.bas
testNamespace.bas
writeByteCodeToFile.bas

list of scripts
callFreebasic.nut
callSquirrel.nut
compileError.nut
errorScript.nut
getArray.nut
HelloWorld.nut
nativeFloat32Test.nut
nativeFloat32VectorTest.nut
nativeFloat64Test.nut
nativeFloat64VectorTest.nut
nativeInt16Test.nut
nativeInt32Test.nut
nativeInt64Test.nut
nativeInt8Test.nut
nativeLibTest.nut
runByteCodeFromScript.nut
runScriptFromScript.nut
runtimeError.nut
scriptClassTest.nut
testNamespace.nut

happy scripting

Joshy
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

Next step are OpenGL.

I use different namespaces for the libs

GL. GLU. GLFW. SOIL. ODE. etc.

Joshy
(I wish I had a mac too)

My first working tests.

Code: Select all

// glTest01.nut

// half of the desktop
GLFW.OpenWindow(GLFW.DESKTOP_WIDTH/2,GLFW.DESKTOP_HEIGHT/2)
// centered on desktop
GLFW.SetWindowPos(GLFW.DESKTOP_WIDTH/4,GLFW.DESKTOP_HEIGHT/4)
GLFW.SetWindowTitle("glTest01.nut")

local w = GLFW.GetWidth()
local h = GLFW.GetHeight()

GL.Viewport(0,0,w,h)
GL.MatrixMode(GL.PROJECTION)
GL.LoadIdentity()
GLU.Perspective(45.0, w/h,0.1, 100.0)
GL.MatrixMode(GL.MODELVIEW)
GL.LoadIdentity()

local rot=0.0

// turn off VSync (60Hz. on my box)
GLFW.SwapInterval(0)

GL.ClearColor(0.5,0.25,0,1)
while (GLFW.WindowOpen()==true) {

  GL.Clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT)

  GL.LoadIdentity()

  GL.Translatef(0, 0, -2)
  GL.Rotatef(rot,1,0,0)
  GL.Rotatef(rot,0,1,0)
  GL.Rotatef(rot,0,0,1)
  GL.Begin(GL.QUADS)
    GL.Color3f(1, 0, 0); GL.Vertex3f(-0.5,-0.5, 0)
    GL.Color3f(0, 1, 0); GL.Vertex3f( 0.5,-0.5, 0)
    GL.Color3f(0, 0, 1); GL.Vertex3f( 0.5, 0.5, 0)
    GL.Color3f(0, 1, 1); GL.Vertex3f(-0.5, 0.5, 0)
  GL.End()

  GLFW.SwapBuffers()
  GLFW.Sleep(1.0/100.0)
  rot+=1.0
}

Code: Select all

/* glFrameWorkFullScreen.nut
   test for: SetFullScreen() */
GLFW.SetFullScreen(true)
GLFW.OpenWindow(800,600)
while (GLFW.GetKey(GLFW.KEY_ESC)==false) {
  GLFW.SwapBuffers()
  GLFW.Sleep(1.0/70.0)
}

Code: Select all

/* glFrameWorkWindow.nut
   test for: GLFW.OpenWindow() */
GLFW.OpenWindow(GLFW.DESKTOP_WIDTH/2,GLFW.DESKTOP_HEIGHT/2)
GLFW.SetWindowPos(GLFW.DESKTOP_WIDTH/4,GLFW.DESKTOP_HEIGHT/4)
GLFW.SetWindowTitle("glFrameWorkWindow.nut")
while (GLFW.WindowOpen()==true) {
  GLFW.SwapBuffers()
  GLFW.Sleep(1.0/70.0)
}
Last edited by D.J.Peters on Dec 21, 2014 2:45, edited 1 time in total.
Post Reply