228 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- tolua: array class
 | |
| -- Written by Waldemar Celes
 | |
| -- TeCGraf/PUC-Rio
 | |
| -- Jul 1999
 | |
| -- $Id: array.lua 1141 2006-05-18 23:58:45Z lindquist $
 | |
| 
 | |
| -- This code is free software; you can redistribute it and/or modify it.
 | |
| -- The software provided hereunder is on an "as is" basis, and
 | |
| -- the author has no obligation to provide maintenance, support, updates,
 | |
| -- enhancements, or modifications.
 | |
| 
 | |
| 
 | |
| -- Array class
 | |
| -- Represents a extern array variable or a public member of a class.
 | |
| -- Stores all fields present in a declaration.
 | |
| classArray = {
 | |
| }
 | |
| classArray.__index = classArray
 | |
| setmetatable(classArray,classDeclaration)
 | |
| 
 | |
| -- Print method
 | |
| function classArray:print (ident,close)
 | |
|  print(ident.."Array{")
 | |
|  print(ident.." mod  = '"..self.mod.."',")
 | |
|  print(ident.." type = '"..self.type.."',")
 | |
|  print(ident.." ptr  = '"..self.ptr.."',")
 | |
|  print(ident.." name = '"..self.name.."',")
 | |
|  print(ident.." def  = '"..self.def.."',")
 | |
|  print(ident.." dim  = '"..self.dim.."',")
 | |
|  print(ident.." ret  = '"..self.ret.."',")
 | |
|  print(ident.."}"..close)
 | |
| end
 | |
| 
 | |
| -- check if it is a variable
 | |
| function classArray:isvariable ()
 | |
|  return true
 | |
| end
 | |
| 
 | |
| 
 | |
| -- get variable value
 | |
| function classArray:getvalue (class,static)
 | |
|  if class and static then
 | |
|   return class..'::'..self.name..'[tolua_index]'
 | |
|  elseif class then
 | |
|   return 'self->'..self.name..'[tolua_index]'
 | |
|  else
 | |
|   return self.name..'[tolua_index]'
 | |
|  end
 | |
| end
 | |
| 
 | |
| -- Write binding functions
 | |
| function classArray:supcode ()
 | |
|  local class = self:inclass()
 | |
| 
 | |
|  -- get function ------------------------------------------------
 | |
|  if class then
 | |
|   output("/* get function:",self.name," of class ",class," */")
 | |
|  else
 | |
|   output("/* get function:",self.name," */")
 | |
|  end
 | |
|  self.cgetname = self:cfuncname("tolua_get")
 | |
|  output("#ifndef TOLUA_DISABLE_"..self.cgetname)
 | |
|  output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
 | |
|  output("{")
 | |
|  output(" int tolua_index;")
 | |
| 
 | |
|  -- declare self, if the case
 | |
|  local _,_,static = strfind(self.mod,'^%s*(static)')
 | |
|  if class and static==nil then
 | |
|   output(' ',self.parent.type,'*','self;')
 | |
|   output(' lua_pushstring(tolua_S,".self");')
 | |
|   output(' lua_rawget(tolua_S,1);')
 | |
|   output(' self = ')
 | |
|   output('(',self.parent.type,'*) ')
 | |
|   output('lua_touserdata(tolua_S,-1);')
 | |
|  elseif static then
 | |
|   _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
 | |
|  end
 | |
| 
 | |
|  -- check index
 | |
| 	output('#ifndef TOLUA_RELEASE\n')
 | |
| 	output(' {')
 | |
| 	output('  tolua_Error tolua_err;')
 | |
|  output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
 | |
|  output('   tolua_error(tolua_S,(char*)"#vinvalid type in array indexing.",&tolua_err);')
 | |
| 	output(' }')
 | |
| 	output('#endif\n')
 | |
| 	if flags['1'] then -- for compatibility with tolua5 ?
 | |
| 		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
 | |
| 	else
 | |
| 		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
 | |
| 	end
 | |
| 	output('#ifndef TOLUA_RELEASE\n')
 | |
| 	if self.dim and self.dim ~= '' then
 | |
| 	  output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
 | |
| 	else
 | |
| 	  output(' if (tolua_index<0)')
 | |
| 	end
 | |
|  output('  tolua_error(tolua_S,(char*)"array indexing out of range.",NULL);')
 | |
| 	output('#endif\n')
 | |
| 
 | |
|  -- return value
 | |
|  local t,ct = isbasic(self.type)
 | |
|  if t then
 | |
|   output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
 | |
|  else
 | |
| 		t = self.type
 | |
|   if self.ptr == '&' or self.ptr == '' then
 | |
|    output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
 | |
|   else
 | |
|    output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
 | |
|   end
 | |
|  end
 | |
|  output(' return 1;')
 | |
|  output('}')
 | |
|  output('#endif //#ifndef TOLUA_DISABLE\n')
 | |
|  output('\n')
 | |
| 
 | |
|  -- set function ------------------------------------------------
 | |
|  if not strfind(self.type,'const') then
 | |
|   if class then
 | |
|    output("/* set function:",self.name," of class ",class," */")
 | |
|   else
 | |
|    output("/* set function:",self.name," */")
 | |
|   end
 | |
|   self.csetname = self:cfuncname("tolua_set")
 | |
|   output("#ifndef TOLUA_DISABLE_"..self.csetname)
 | |
|   output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
 | |
|   output("{")
 | |
| 
 | |
|   -- declare index
 | |
|   output(' int tolua_index;')
 | |
| 
 | |
|   -- declare self, if the case
 | |
|   local _,_,static = strfind(self.mod,'^%s*(static)')
 | |
|   if class and static==nil then
 | |
|    output(' ',self.parent.type,'*','self;')
 | |
|    output(' lua_pushstring(tolua_S,".self");')
 | |
|    output(' lua_rawget(tolua_S,1);')
 | |
|    output(' self = ')
 | |
|    output('(',self.parent.type,'*) ')
 | |
|    output('lua_touserdata(tolua_S,-1);')
 | |
|   elseif static then
 | |
|    _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
 | |
|   end
 | |
| 
 | |
|   -- check index
 | |
| 	 output('#ifndef TOLUA_RELEASE\n')
 | |
| 	 output(' {')
 | |
| 	 output('  tolua_Error tolua_err;')
 | |
|   output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
 | |
|   output('   tolua_error(tolua_S,(char*)"#vinvalid type in array indexing.",&tolua_err);')
 | |
| 		output(' }')
 | |
| 		output('#endif\n')
 | |
| 
 | |
| 	if flags['1'] then -- for compatibility with tolua5 ?
 | |
| 		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
 | |
| 	else
 | |
| 		output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
 | |
| 	end
 | |
| 
 | |
| 	 output('#ifndef TOLUA_RELEASE\n')
 | |
| 	if self.dim and self.dim ~= '' then
 | |
| 	  output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
 | |
| 	else
 | |
| 	  output(' if (tolua_index<0)')
 | |
| 	end
 | |
|   output('  tolua_error(tolua_S,(char*)"array indexing out of range.",NULL);')
 | |
| 		output('#endif\n')
 | |
| 
 | |
|   -- assign value
 | |
|   local ptr = ''
 | |
|   if self.ptr~='' then ptr = '*' end
 | |
|   output(' ')
 | |
|   if class and static then
 | |
|    output(class..'::'..self.name..'[tolua_index]')
 | |
|   elseif class then
 | |
|    output('self->'..self.name..'[tolua_index]')
 | |
|   else
 | |
|    output(self.name..'[tolua_index]')
 | |
|   end
 | |
|   local t = isbasic(self.type)
 | |
|   output(' = ')
 | |
|   if not t and ptr=='' then output('*') end
 | |
|   output('((',self.mod,self.type)
 | |
|   if not t then
 | |
|    output('*')
 | |
|   end
 | |
|   output(') ')
 | |
|   local def = 0
 | |
|   if self.def ~= '' then def = self.def end
 | |
|   if t then
 | |
|    output('tolua_to'..t,'(tolua_S,3,',def,'));')
 | |
|   else
 | |
|    output('tolua_tousertype(tolua_S,3,',def,'));')
 | |
|   end
 | |
|   output(' return 0;')
 | |
|   output('}')
 | |
|   output('#endif //#ifndef TOLUA_DISABLE\n')
 | |
|   output('\n')
 | |
|  end
 | |
| 
 | |
| end
 | |
| 
 | |
| function classArray:register (pre)
 | |
|  pre = pre or ''
 | |
|  if self.csetname then
 | |
|   output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
 | |
|  else
 | |
|   output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
 | |
|  end
 | |
| end
 | |
| 
 | |
| -- Internal constructor
 | |
| function _Array (t)
 | |
|  setmetatable(t,classArray)
 | |
|  append(t)
 | |
|  return t
 | |
| end
 | |
| 
 | |
| -- Constructor
 | |
| -- Expects a string representing the variable declaration.
 | |
| function Array (s)
 | |
|  return _Array (Declaration(s,'var'))
 | |
| end
 | |
| 
 | |
| 
 |