commit 8ba26d71be99830c130f5e44c7781dcda69dcc08 Author: Tomaka17 Date: Thu Jun 5 11:00:23 2014 +0200 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b71c593 --- /dev/null +++ b/.gitignore @@ -0,0 +1,217 @@ +################# +## Eclipse +################# + +*.pydevproject +.project +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + + +################# +## Visual Studio +################# + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +############# +## Windows detritus +############# + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store + + +############# +## Python +############# + +*.py[co] + +# Packages +*.egg +*.egg-info +dist/ +build/ +eggs/ +parts/ +var/ +sdist/ +develop-eggs/ +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg +project.sublime-* +*.rlib diff --git a/README.md b/README.md new file mode 100644 index 0000000..b93f447 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +## rust-lua + +This library is a high-level binding for Lua. You don't have access to the Lua stack, all you can do is read and write variables. + +### How to compile? + + rustc src/lib.rs + +### How to use it? + + let mut lua = Lua::new(); // mutable is mandatory + lua.set("x", 2); + lua.execute("x = x + 1"); + let x = lua.get("x").unwrap(); // return 3 + +### Documentation + +#### Reading and writing variables + + let mut lua = Lua::new(); + lua.set("x", 5); + lua.execute("x = x + 2;"); + let x = lua.get("x").unwrap(); + +Reading and writing global variables of the Lua context can be done with `set` and `get`. +The `get` function returns an `Option` + +The types that can be read and written are: `int`, `std::string::String`, ... (TODO) diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..30a1328 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,123 @@ +#![crate_id = "lua"] +#![crate_type = "lib"] +#![comment = "Lua bindings for Rust"] +#![license = "MIT"] + +extern crate libc; +extern crate std; + +mod liblua; +pub mod value; + +pub struct Lua { + lua: *mut liblua::lua_State +} + +pub struct VariableAccessor<'a, TIndexFollower> { + lua: &'a mut Lua, + location: TIndexFollower +} + +pub trait Pushable { + fn push_to_lua(self, &Lua); +} + +pub trait Readable { + fn read_from_lua(&Lua, i32) -> Option; +} + +pub trait Index: Pushable + Readable { +} + +trait Dropbox { + fn store(&self, &Lua, &TIndex, TPushable); +} + +trait Readbox { + fn read(&self, &Lua, &TIndex) -> Option; +} + +pub struct IndexFollower<'a, TIndex, TPrev> { + index: &'a TIndex, + prev: TPrev +} + +pub struct Globals; + + +extern "C" fn alloc(_ud: *mut libc::c_void, ptr: *mut libc::c_void, _osize: libc::size_t, nsize: libc::size_t) -> *mut libc::c_void { + unsafe { + if nsize == 0 { + libc::free(ptr as *mut libc::c_void); + std::ptr::mut_null() + } else { + libc::realloc(ptr, nsize) + } + } +} + +impl Lua { + pub fn new() -> Lua { + let lua = unsafe { liblua::lua_newstate(alloc, std::ptr::mut_null()) }; + if lua.is_null() { + fail!("lua_newstate failed"); + } + + Lua { lua: lua } + } + + pub fn execute(&mut self, code: &std::string::String) -> T { + unimplemented!() + } + + pub fn access<'a, 'b, TIndex: Index>(&'a mut self, index: &'b TIndex) -> VariableAccessor<'a, IndexFollower<'b, TIndex, Globals>> { + VariableAccessor { + lua: self, + location: IndexFollower { index: index, prev: Globals } + } + } +} + +impl<'a, 'b, TIndex: Index, TValue: Pushable, TDropbox: Dropbox> VariableAccessor<'a, IndexFollower<'b, TIndex, TDropbox>> { + pub fn set(&mut self, value: TValue) { + self.location.store(self.lua, value) + } +} + +impl<'a, 'b, TIndex: Index, TValue: Readable, TReadbox: Readbox> VariableAccessor<'a, IndexFollower<'b, TIndex, TReadbox>> { + pub fn get(&self) -> Option { + self.location.read(self.lua) + } +} + +impl<'a, TIndex: Index, TValue: Pushable, TDropbox: Dropbox> IndexFollower<'a, TIndex, TDropbox> { + fn store(&self, lua: &Lua, value: TValue) { + self.prev.store(lua, self.index, value) + } +} + +impl<'a, TIndex: Index, TValue: Readable, TReadbox: Readbox> IndexFollower<'a, TIndex, TReadbox> { + fn read(&self, lua: &Lua) -> Option { + self.prev.read(lua, self.index) + } +} + +impl Dropbox for Globals { + fn store(&self, lua: &Lua, index: &std::string::String, value: TValue) { + unsafe { + value.push_to_lua(lua); + liblua::lua_setglobal(lua.lua, index.to_c_str().unwrap()); + } + } +} + +impl Readbox for Globals { + fn read(&self, lua: &Lua, index: &std::string::String) -> Option { + unsafe { + liblua::lua_getglobal(lua.lua, index.to_c_str().unwrap()); + let value = Readable::read_from_lua(lua, -1); + liblua::lua_pop(lua.lua, 1); + value + } + } +} diff --git a/src/liblua.rs b/src/liblua.rs new file mode 100644 index 0000000..7be9f76 --- /dev/null +++ b/src/liblua.rs @@ -0,0 +1,337 @@ +#![allow(non_camel_case_types)] +#![allow(uppercase_variables)] +#![allow(dead_code)] + +extern crate libc; +extern crate std; + +use libc::c_int; +use std::{ default, ptr }; + +pub static MULTRET: c_int = -1; + +pub static LUA_REGISTRYINDEX: c_int = -10000; +pub static LUA_ENVIRONINDEX: c_int = -10001; +pub static LUA_GLOBALSINDEX: c_int = -10002; + +pub static LUA_OK: c_int = 0; +pub static LUA_YIELD: c_int = 1; +pub static LUA_ERRRUN: c_int = 2; +pub static LUA_ERRSYNTAX: c_int = 3; +pub static LUA_ERRMEM: c_int = 4; +pub static LUA_ERRGCMM: c_int = 5; +pub static LUA_ERRERR: c_int = 6; + + +pub struct lua_State; + +pub type lua_CFunction = extern "C" fn(L: *mut lua_State) -> c_int; + +pub type lua_Reader = extern "C" fn(L: *mut lua_State, ud: *mut libc::c_void, sz: *mut libc::size_t) -> *libc::c_char; +pub type lua_Writer = extern "C" fn(L: *mut lua_State, p: *libc::c_void, sz: libc::size_t, ud: *mut libc::c_void) -> libc::c_int; + +pub type lua_Alloc = extern "C" fn(ud: *mut libc::c_void, ptr: *mut libc::c_void, osize: libc::size_t, nsize: libc::size_t) -> *mut libc::c_void; + +pub type lua_Hook = unsafe extern "C" fn(L: *mut lua_State, ar: *mut lua_Debug); + + +pub static LUA_TNONE: c_int = -1; + +pub static LUA_TNIL: c_int = 0; +pub static LUA_TBOOLEAN: c_int = 1; +pub static LUA_TLIGHTUSERDATA: c_int = 2; +pub static LUA_TNUMBER: c_int = 3; +pub static LUA_TSTRING: c_int = 4; +pub static LUA_TTABLE: c_int = 5; +pub static LUA_TFUNCTION: c_int = 6; +pub static LUA_TUSERDATA: c_int = 7; +pub static LUA_TTHREAD: c_int = 8; + +pub static LUA_MINSTACK: c_int = 20; + +pub static LUA_RIDX_MAINTHREAD: c_int = 1; +pub static LUA_RIDX_GLOBALS: c_int = 2; + +pub type lua_Number = libc::c_double; +pub type lua_Integer = libc::ptrdiff_t; +pub type lua_Unsigned = libc::c_ulong; + +pub static LUA_OPADD: c_int = 0; +pub static LUA_OPSUB: c_int = 1; +pub static LUA_OPMUL: c_int = 2; +pub static LUA_OPDIV: c_int = 3; +pub static LUA_OPMOD: c_int = 4; +pub static LUA_OPPOW: c_int = 5; +pub static LUA_OPUNM: c_int = 6; + +pub static LUA_OPEQ: c_int = 0; +pub static LUA_OPLT: c_int = 1; +pub static LUA_OPLE: c_int = 2; + +pub static LUA_GCSTOP: c_int = 0; +pub static LUA_GCRESTART: c_int = 1; +pub static LUA_GCCOLLECT: c_int = 2; +pub static LUA_GCCOUNT: c_int = 3; +pub static LUA_GCCOUNTB: c_int = 4; +pub static LUA_GCSTEP: c_int = 5; +pub static LUA_GCSETPAUSE: c_int = 6; +pub static LUA_GCSETSTEPMUL: c_int = 7; +pub static LUA_GCSETMAJORINC: c_int = 8; +pub static LUA_GCISRUNNING: c_int = 9; +pub static LUA_GCGEN: c_int = 10; +pub static LUA_GCINC: c_int = 11; + +pub static LUA_HOOKCALL: c_int = 0; +pub static LUA_HOOKRET: c_int = 1; +pub static LUA_HOOKLINE: c_int = 2; +pub static LUA_HOOKCOUNT: c_int = 3; +pub static LUA_HOOKTAILRET: c_int = 4; + +pub static LUA_MASKCALL: c_int = 1 << LUA_HOOKCALL; +pub static LUA_MASKRET: c_int = 1 << LUA_HOOKRET; +pub static LUA_MASKLINE: c_int = 1 << LUA_HOOKLINE; +pub static LUA_MASKCOUNT: c_int = 1 << LUA_HOOKCOUNT; + +pub struct lua_Debug { + pub event: c_int, + pub name: *libc::c_char, + pub namewhat: *libc::c_char, + pub what: *libc::c_char, + pub source: *libc::c_char, + pub currentline: c_int, + pub linedefined: c_int, + pub lastlinedefined: c_int, + pub nups: libc::c_uchar, + pub nparams: libc::c_uchar, + pub isvararg: libc::c_char, + pub istailcall: libc::c_char, + pub short_src: [libc::c_char, ..60]//, + //i_ci: *CallInfo +} + +#[link(name = "lua")] +extern "C" { + pub fn lua_newstate(f: lua_Alloc, ud: *mut libc::c_void) -> *mut lua_State; + pub fn lua_close(L: *mut lua_State); + pub fn lua_newthread(L: *mut lua_State) -> *mut lua_State; + + pub fn lua_atpanic(L: *mut lua_State, panicf: lua_CFunction) -> lua_CFunction; + + pub fn lua_version(L: *mut lua_State) -> *lua_Number; + + pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_gettop(L: *mut lua_State) -> c_int; + pub fn lua_settop(L: *mut lua_State, idx: c_int); + pub fn lua_pushvalue(L: *mut lua_State, idx: c_int); + pub fn lua_remove(L: *mut lua_State, idx: c_int); + pub fn lua_insert(L: *mut lua_State, idx: c_int); + pub fn lua_replace(L: *mut lua_State, idx: c_int); + pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int); + pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int; + + pub fn lua_xmove(from: *mut lua_State, to: *mut lua_State, n: c_int); + + pub fn lua_isnumber(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_isstring(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_iscfunction(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_isuserdata(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_type(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_typename(L: *mut lua_State, tp: c_int) -> *libc::c_char; + + pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *c_int) -> lua_Number; + pub fn lua_tointegerx(L: *mut lua_State, idx: c_int, isnum: *c_int) -> lua_Integer; + pub fn lua_tounsignedx(L: *mut lua_State, idx: c_int, isnum: *c_int) -> lua_Unsigned; + pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut libc::size_t) -> *libc::c_char; + pub fn lua_rawlen(L: *mut lua_State, idx: c_int) -> libc::size_t; + pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option; + pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut libc::c_void; + pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State; + pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *libc::c_void; + + pub fn lua_arith(L: *mut lua_State, op: c_int); + pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int; + pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int; + + pub fn lua_pushnil(L: *mut lua_State); + pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number); + pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer); + pub fn lua_pushunsigned(L: *mut lua_State, n: lua_Unsigned); + pub fn lua_pushlstring(L: *mut lua_State, s: *libc::c_char, l: libc::size_t); + pub fn lua_pushstring(L: *mut lua_State, s: *libc::c_char); + // TODO: lua_pushvfstring() + pub fn lua_pushfstring(L: *mut lua_State, fmt: *libc::c_char, ...) -> *libc::c_char; + pub fn lua_pushcclosure(L: *mut lua_State, f: lua_CFunction, n: c_int); + pub fn lua_pushboolean(L: *mut lua_State, b: c_int); + pub fn lua_pushlightuserdata(L: *mut lua_State, p: *mut libc::c_void); + pub fn lua_pushthread(L: *mut lua_State) -> c_int; + + pub fn lua_getglobal(L: *mut lua_State, var: *libc::c_char); + pub fn lua_gettable(L: *mut lua_State, idx: c_int); + pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *libc::c_char); + pub fn lua_rawget(L: *mut lua_State, idx: c_int); + pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: c_int); + pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *libc::c_char); + pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int); + pub fn lua_newuserdata(L: *mut lua_State, sz: libc::size_t) -> *mut libc::c_void; + pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int; + pub fn lua_getfenv(L: *mut lua_State, idx: c_int); + + pub fn lua_setglobal(L: *mut lua_State, var: *libc::c_char); + pub fn lua_settable(L: *mut lua_State, idx: c_int); + pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *libc::c_char); + pub fn lua_rawset(L: *mut lua_State, idx: c_int); + pub fn lua_rawseti(L: *mut lua_State, idx: c_int, n: c_int); + pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *libc::c_char); + pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int; + pub fn lua_setfenv(L: *mut lua_State, idx: c_int) -> c_int; + + pub fn lua_callk(L: *mut lua_State, nargs: c_int, nresults: c_int, ctx: c_int, k: Option); + pub fn lua_getctx(L: *mut lua_State, ctx: c_int) -> c_int; + pub fn lua_pcallk(L: *mut lua_State, nargs: c_int, nresults: c_int, errfunc: c_int, ctx: c_int, k: Option) -> c_int; + pub fn lua_load(L: *mut lua_State, reader: lua_Reader, dt: *mut libc::c_void, chunkname: *libc::c_char, mode: *libc::c_char) -> c_int; + pub fn lua_dump(L: *mut lua_State, writer: lua_Writer, data: *mut libc::c_void) -> c_int; + + pub fn lua_yieldk(L: *mut lua_State, nresults: c_int, ctx: c_int, k: Option) -> c_int; + pub fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int) -> c_int; + pub fn lua_status(L: *mut lua_State) -> c_int; + + pub fn lua_gc(L: *mut lua_State, what: c_int, data: c_int) -> c_int; + + pub fn lua_error(L: *mut lua_State) -> c_int; + pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_concat(L: *mut lua_State, n: c_int); + pub fn lua_len(L: *mut lua_State, idx: c_int); + + pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut libc::c_void) -> lua_Alloc; + pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut libc::c_void); + + pub fn lua_getstack(L: *mut lua_State, level: c_int, ar: *mut lua_Debug) -> c_int; + pub fn lua_getinfo(L: *mut lua_State, what: *libc::c_char, ar: *mut lua_Debug) -> c_int; + pub fn lua_getlocal(L: *mut lua_State, ar: *lua_Debug, n: c_int) -> *libc::c_char; + pub fn lua_setlocal(L: *mut lua_State, ar: *mut lua_Debug, n: c_int) -> *libc::c_char; + pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *libc::c_char; + pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *libc::c_char; + + pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *libc::c_void; + pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int); + + pub fn lua_sethook(L: *mut lua_State, func: lua_Hook, mask: c_int, count: c_int) -> c_int; + pub fn lua_gethook(L: *mut lua_State) -> lua_Hook; + pub fn lua_gethookmask(L: *mut lua_State) -> c_int; + pub fn lua_gethookcount(L: *mut lua_State) -> c_int; +} + +#[inline(always)] +pub fn lua_upvalueindex(i: c_int) -> c_int { + LUA_GLOBALSINDEX - i +} + +#[inline(always)] +pub unsafe fn lua_call(L: *mut lua_State, nargs: c_int, nresults: c_int) { + lua_callk(L, nargs, nresults, 0, None) +} + +#[inline(always)] +pub unsafe fn lua_pcall(L: *mut lua_State, nargs: c_int, nresults: c_int, errfunc: c_int) -> c_int { + lua_pcallk(L, nargs, nresults, errfunc, 0, None) +} + +#[inline(always)] +pub unsafe fn lua_yield(L: *mut lua_State, nresults: c_int) -> c_int { + lua_yieldk(L, nresults, 0, None) +} + +#[inline(always)] +pub unsafe fn lua_pop(L: *mut lua_State, n: c_int) { + lua_settop(L, -n-1) +} + +#[inline(always)] +pub unsafe fn lua_newtable(L: *mut lua_State) { + lua_createtable(L, 0, 0) +} + +#[inline(always)] +pub unsafe fn lua_register(L: *mut lua_State, name: *libc::c_char, f: lua_CFunction) { + lua_pushcfunction(L, f); + lua_setglobal(L, name) +} + +#[inline(always)] +pub unsafe fn lua_pushcfunction(L: *mut lua_State, f: lua_CFunction) { + lua_pushcclosure(L, f, 0) +} + +#[inline(always)] +pub unsafe fn lua_isfunction(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TFUNCTION +} + +#[inline(always)] +pub unsafe fn lua_istable(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TTABLE +} + +#[inline(always)] +pub unsafe fn lua_islightuserdata(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TLIGHTUSERDATA +} + +#[inline(always)] +pub unsafe fn lua_isnil(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TNIL +} + +#[inline(always)] +pub unsafe fn lua_isboolean(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TBOOLEAN +} + +#[inline(always)] +pub unsafe fn lua_isthread(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TTHREAD +} + +#[inline(always)] +pub unsafe fn lua_isnone(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) == LUA_TNONE +} + +#[inline(always)] +pub unsafe fn lua_isnoneornil(L: *mut lua_State, idx: c_int) -> bool { + lua_type(L, idx) <= 0 +} + +// TODO: lua_pushliteral + +#[inline(always)] +pub unsafe fn lua_pushglobaltable(L: *mut lua_State) { + lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) +} + +#[inline(always)] +pub unsafe fn lua_tostring(L: *mut lua_State, i: c_int) -> *libc::c_char { + lua_tolstring(L, i, ptr::mut_null()) +} + + +impl default::Default for lua_Debug { + fn default() -> lua_Debug { + lua_Debug{ + event: 0, + name: ptr::null(), + namewhat: ptr::null(), + what: ptr::null(), + source: ptr::null(), + currentline: 0, + linedefined: 0, + lastlinedefined: 0, + nups: 0, + nparams: 0, + isvararg: 0, + istailcall: 0, + short_src: [0, ..60] + } + } +} diff --git a/src/value.rs b/src/value.rs new file mode 100644 index 0000000..cb02673 --- /dev/null +++ b/src/value.rs @@ -0,0 +1,104 @@ +extern crate libc; +extern crate std; +use super::liblua; +use super::Index; +use super::Lua; +use super::Pushable; +use super::Readable; + +impl Pushable for i32 { + fn push_to_lua(self, lua: &Lua) { + unsafe { liblua::lua_pushinteger(lua.lua, self) } + } +} + +impl Readable for i32 { + fn read_from_lua(lua: &Lua, index: i32) -> Option { + unsafe { + let mut success: libc::c_int = std::mem::uninitialized(); + let val = liblua::lua_tointegerx(lua.lua, index, std::mem::transmute(&success)); + match success { + 0 => None, + _ => Some(val) + } + } + } +} + +impl Index for i32 { +} + +impl Pushable for std::string::String { + fn push_to_lua(self, lua: &Lua) { + unsafe { + liblua::lua_pushstring(lua.lua, self.to_c_str().unwrap()) + } + } +} + +impl Readable for std::string::String { + fn read_from_lua(lua: &Lua, index: i32) -> Option { + unsafe { + let mut size: libc::size_t = std::mem::uninitialized(); + let cStr = liblua::lua_tolstring(lua.lua, index, std::mem::transmute(&size)); + if cStr.is_null() { + return None; + } + + // TODO: check this transmute, why is from_raw_parts taking a mut ptr? + let val = std::string::String::from_raw_parts(size as uint, size as uint, std::mem::transmute(cStr)); + + Some(val) + } + } +} + +impl Index for std::string::String { +} + +/*impl<'a> Pushable for &'a str { + fn push_to_lua(self, lua: &Lua) { + std::string::String::from_str(self).push_to_lua(lua) + } +} + +impl Readable for ~str { + fn read_from_lua(lua: &Lua, index: i32) -> Option<~str> { + let raw: Option = Readable::read_from_lua(lua, index); + // TODO: doesn't compile + match raw { + None => None, + Some(s) => Some(box s.as_slice() as ~str) + } + } +} + +impl Index for ~str { +}*/ + +impl Pushable for std::vec::Vec { + fn push_to_lua(self, lua: &Lua) { + unimplemented!() + } +} + +impl<'a, TRetValue> Pushable for ||:'a -> TRetValue { + fn push_to_lua(self, lua: &Lua) { + //unsafe { liblua::lua_pushinteger(lua.lua, self) } + } +} + +impl Pushable for fn() -> TRetValue { + fn push_to_lua(self, lua: &Lua) { + extern "C" fn wrapper(state: *liblua::lua_State) { + + } + } +} + +impl Pushable for fn(TParam1) -> TRetValue { + fn push_to_lua(self, lua: &Lua) { + //unsafe { liblua::lua_pushinteger(lua.lua, self) } + } +} +