' ******************************************************************************
' * Copyright (C) 1994-2008 Lua.org, PUC-Rio.  All rights reserved.
' *
' * Permission is hereby granted, free of charge, to any person obtaining
' * a copy of this software and associated documentation files (the
' * "Software"), to deal in the Software without restriction, including
' * without limitation the rights to use, copy, modify, merge, publish,
' * distribute, sublicense, and/or sell copies of the Software, and to
' * permit persons to whom the Software is furnished to do so, subject to
' * the following conditions:
' *
' * The above copyright notice and this permission notice shall be
' * included in all copies or substantial portions of the Software.
' *
' * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
' * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
' * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
' * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
' * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
' * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
' * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
' ******************************************************************************
'
' Ported to BaCon INCLUDE file by Doyle Whisenant.
'
' Version 1.0: Initial release
' Version 1.1: Fixes for BaCon 3.0 and higher.

TRAP LOCAL
CATCH GOTO lua_handle_error

lib_Lua$ = "liblua5.1.so"
lua_seq = -1

LABEL lua_import_retry
    INCR lua_seq
    lua_retry = FALSE
    IMPORT "luaL_newstate" FROM lib_Lua$ TYPE void*
    IF lua_retry THEN GOTO lua_import_retry

GOTO lua_continue

LABEL lua_handle_error
    IF lua_seq = 0 THEN  lib_Lua$ = "liblua5.1.so.0"
    ELSE lib_Lua$ = CONCAT$(LEFT$(lib_Lua$, INSTRREV(lib_Lua$, ".")), STR$(lua_seq))

    IF lua_seq < 10 THEN
        lua_retry = TRUE
    ELSE
        PRINT "No Lua library found!"
    END
    END IF
    RESUME

LABEL lua_continue

 CONST LUA_VERSION = "Lua 5.1"
 CONST LUA_RELEASE = "Lua 5.1.4"
 CONST LUA_VERSION_NUM = 501
 CONST LUA_COPYRIGHT     = "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
 CONST LUA_AUTHORS   = "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"

'** mark for precompiled code (`<esc>Lua') 
 CONST LUA_SIGNATURE    = "\033Lua"

'** pseudo-indices

 CONST LUA_REGISTRYINDEX    = -10000
 CONST LUA_ENVIRONINDEX = -10001
 CONST LUA_GLOBALSINDEX = -10002
 DEF FN lua_upvalueindex(i) = (LUA_GLOBALSINDEX-(i))

 CONST LUA_MULTRET  =   -1

' garbage-collection function and options

 CONST LUA_GCSTOP       = 0
 CONST LUA_GCRESTART        = 1
 CONST LUA_GCCOLLECT    = 2
 CONST LUA_GCCOUNT      = 3
 CONST LUA_GCCOUNTB     = 4
 CONST LUA_GCSTEP       = 5
 CONST LUA_GCSETPAUSE   = 6
 CONST LUA_GCSETSTEPMUL = 7

' thread status; 0 is OK 
CONST LUA_YIELD     = 1
CONST LUA_ERRRUN    = 2
CONST LUA_ERRSYNTAX = 3
CONST LUA_ERRMEM    = 4
CONST LUA_ERRERR    = 5

USEC
typedef struct lua_State lua_State;
typedef int (*lua_CFunction) (lua_State *L);

// functions that read/write blocks when loading/dumping Lua chunks
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);

// prototype for memory-allocation functions
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
END USEC

'** state manipulation

 IMPORT "lua_close(long*)" FROM lib_Lua$ TYPE void
 IMPORT "lua_newthread(long*)" FROM lib_Lua$ TYPE long*
 IMPORT "lua_atpanic(long*, long)" FROM lib_Lua$ TYPE long
 IMPORT "luaL_openlibs(long*)" FROM lib_Lua$ TYPE void

'** basic stack manipulation

 IMPORT "lua_gettop(long*)" FROM lib_Lua$ TYPE int
 IMPORT "lua_settop(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushvalue(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_remove(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_insert(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_replace(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_checkstack(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_xmove(long*, long*, int)" FROM lib_Lua$ TYPE void

'** access functions (stack -> C)

 IMPORT "lua_isnumber(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_isstring(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_iscfunction(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_isuserdata(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_type(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_typename(long*, int)" FROM lib_Lua$ TYPE char*
 IMPORT "lua_equal(long*, int, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_rawequal(long*, int, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_lessthan(long*, int, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_tonumber(long*, int)" FROM lib_Lua$ TYPE double
 IMPORT "lua_tointeger(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_toboolean(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_tolstring(long*, int, void*)" FROM lib_Lua$ TYPE char*
 IMPORT "lua_objlen(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_tocfunction(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_touserdata(long*, int)" FROM lib_Lua$ TYPE void*
 IMPORT "lua_tothread(long*, int)" FROM lib_Lua$ TYPE long*
 IMPORT "lua_topointer(long*, int)" FROM lib_Lua$ TYPE void*

'** push functions (C -> stack)

 IMPORT "lua_pushnil(long*)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushnumber(long*, double)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushinteger(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushlstring(long*, char*, long)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushstring(long*, char*)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushvfstring(long*, char*,...)" FROM lib_Lua$ TYPE char*
 IMPORT "lua_pushfstring(long*, char*,...)" FROM lib_Lua$ TYPE char*
 IMPORT "lua_pushcclosure(long*, long,int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushboolean(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushlightuserdata(long*, void*)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pushthread(long*)" FROM lib_Lua$ TYPE int

'** get functions (Lua -> stack)

 IMPORT "lua_gettable(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_getfield(long*, int, char*)" FROM lib_Lua$ TYPE void
 IMPORT "lua_rawget(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_rawgeti(long*, int, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_createtable(long*, int, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_newuserdata(long*, int)" FROM lib_Lua$ TYPE void*
 IMPORT "lua_getmetatable(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_getfenv(long*, int)" FROM lib_Lua$ TYPE void

'** set functions (stack -> Lua)

 IMPORT "lua_settable(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_setfield(long*, int, char*)" FROM lib_Lua$ TYPE void
 IMPORT "lua_rawset(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_rawseti(long*, int, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_setmetatable(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_setfenv(long*, int)" FROM lib_Lua$ TYPE int

'** `load' and `call' functions (load and run Lua code)

 IMPORT "lua_call(long*,int, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_pcall(long*,int, int,int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_cpcall(long*,long*, void*)" FROM lib_Lua$ TYPE int
 IMPORT "lua_load(long*,long*, void*,char*)" FROM lib_Lua$ TYPE int
 IMPORT "lua_dump(long*,long*, void*)" FROM lib_Lua$ TYPE int

'** coroutine functions

 IMPORT "lua_yield(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_resume(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_status(long*)" FROM lib_Lua$ TYPE int

'** garbage-collection function and options

 IMPORT "lua_gc(long*, int, int)" FROM lib_Lua$ TYPE int

'** miscellaneous functions

 IMPORT "lua_error(long*)" FROM lib_Lua$ TYPE int
 IMPORT "lua_next(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "lua_concat(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "lua_getallocf(long*,void**)" FROM lib_Lua$ TYPE void*
 IMPORT "lua_setallocf(long*, long, void*)" FROM lib_Lua$ TYPE void

' basic types
 CONST LUA_TNONE            = -1
 CONST LUA_TNIL             = 0
 CONST LUA_TBOOLEAN         = 1
 CONST LUA_TLIGHTUSERDATA   = 2
 CONST LUA_TNUMBER          = 3
 CONST LUA_TSTRING          = 4
 CONST LUA_TTABLE           = 5
 CONST LUA_TFUNCTION            = 6
 CONST LUA_TUSERDATA            = 7
 CONST LUA_TTHREAD          = 8

' minimum Lua stack available to a C function 
 CONST LUA_MINSTACK = 20

USEC
// type of numbers in Lua
//typedef LUA_NUMBER lua_Number;

// type for integer functions
//typedef LUA_INTEGER lua_Integer;
END USEC

' // some useful macros
 DEF FN lua_pop(L,n)        = lua_settop(L, -(n)-1)
 DEF FN lua_newtable(L)     = lua_createtable(L, 0, 0)
 DEF FN lua_register(L,n,f)     = (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
 DEF FN lua_pushcfunction(L,f)  = lua_pushcclosure(L, (f), 0)
 DEF FN lua_strlen(L,i)     = lua_objlen(L, (i))
 DEF FN lua_isfunction(L,n) = (lua_type(L, (n)) == LUA_TFUNCTION)
 DEF FN lua_istable(L,n)        = (lua_type(L, (n)) == LUA_TTABLE)
 DEF FN lua_islightuserdata(L,n) = (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
 DEF FN lua_isnil(L,n)      = (lua_type(L, (n)) == LUA_TNIL)
 DEF FN lua_isboolean(L,n)  = (lua_type(L, (n)) == LUA_TBOOLEAN)
 DEF FN lua_isthread(L,n)       = (lua_type(L, (n)) == LUA_TTHREAD)
 DEF FN lua_isnone(L,n)     = (lua_type(L, (n)) == LUA_TNONE)
 DEF FN lua_isnoneornil(L, n)   = (lua_type(L, (n)) <= 0)
 DEF FN lua_pushliteral(L, s)   = lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
 DEF FN lua_setglobal(L,s)  = lua_setfield(L, LUA_GLOBALSINDEX, (s))
 DEF FN lua_getglobal(L,s)  = lua_getfield(L, LUA_GLOBALSINDEX, (s))
 DEF FN lua_tostring(L,i)       = lua_tolstring(L, (i), NULL)

' // compatibility macros and functions

 DEF FN lua_open()          = luaL_newstate()
 DEF FN lua_getregistry(L)  = lua_pushvalue(L, LUA_REGISTRYINDEX)
 DEF FN lua_getgccount(L)   = lua_gc(L, LUA_GCCOUNT, 0)
 DEF FN lua_Chunkreader = lua_Reader
 DEF FN lua_Chunkwriter     = lua_Writer

' // some useful macros

 DEF FN luaL_argcheck(L, cond,numarg,extramsg)   = ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
 DEF FN luaL_checkstring(L,n)    = (luaL_checklstring(L, (n), NULL))
 DEF FN luaL_optstring(L,n,d)    = (luaL_optlstring(L, (n), (d), NULL))
 DEF FN luaL_checkint(L,n)   = ((int)luaL_checkinteger(L, (n)))
 DEF FN luaL_optint(L,n,d)   = ((int)luaL_optinteger(L, (n), (d)))
 DEF FN luaL_checklong(L,n)  = ((long)luaL_checkinteger(L, (n)))
 DEF FN luaL_optlong(L,n,d)  = ((long)luaL_optinteger(L, (n), (d)))
 DEF FN luaL_typename(L,i)   = lua_typename(L, lua_type(L,(i)))
 DEF FN luaL_dofile(L, fn)   = (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
 DEF FN luaL_dostring(L, s)      = (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
 DEF FN luaL_getmetatable(L,n) = (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
 'DEF FN luaL_opt(L,f,n,d)   = (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))

 IMPORT "luaL_error(long*, char*,...)" FROM lib_Lua$ TYPE int

'* extra error code for `luaL_load' 
 DEF FN LUA_ERRFILE  =   (LUA_ERRERR+1)

USEC
typedef struct luaL_Reg {
  const char *name;
  lua_CFunction func;
} luaL_Reg;
END USEC

 IMPORT "luaI_openlib(long*, char*, long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_register(long*, char*, long*)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_getmetafield(long*, int, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_callmeta(long*, int, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_typerror(long*, int, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_argerror(long*, int, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_checklstring(long*, int, long)" FROM lib_Lua$ TYPE char*
 IMPORT "luaL_optlstring(long*, int, char*, long)" FROM lib_Lua$ TYPE char*
 IMPORT "luaL_checknumber(long*, int)" FROM lib_Lua$ TYPE double
 IMPORT "luaL_optnumber(long*, int, double)" FROM lib_Lua$ TYPE double
 IMPORT "luaL_checkinteger(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_optinteger(long*, int, int)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_checkstack(long*, int, char*)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_checktype(long*, int, int)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_checkany(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_newmetatable(long*, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_checkudata(long*, int, char*)" FROM lib_Lua$ TYPE void*
 IMPORT "luaL_where(long*, int)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_error(long*, char*, ...)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_checkoption(long*, int, char*, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_ref(long*, int)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_unref(long*, int, int)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_loadfile(long*, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_loadbuffer(long*, char*, long, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_loadstring(long*, char*)" FROM lib_Lua$ TYPE int
 IMPORT "luaL_gsub(long*, char*, char*, char*)" FROM lib_Lua$ TYPE char*
 IMPORT "luaL_findtable(long*, int, char*, int)" FROM lib_Lua$ TYPE char*

' some useful macros
 DEF FN luaL_argcheck(L, cond,numarg,extramsg)  = ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
 DEF FN luaL_checkstring(L,n)    = (luaL_checklstring(L, (n), NULL))
 DEF FN luaL_optstring(L,n,d)    = (luaL_optlstring(L, (n), (d), NULL))
 DEF FN luaL_checkint(L,n)   = ((int)luaL_checkinteger(L, (n)))
 DEF FN luaL_optint(L,n,d)   = ((int)luaL_optinteger(L, (n), (d)))
 DEF FN luaL_checklong(L,n)  = ((long)luaL_checkinteger(L, (n)))
 DEF FN luaL_optlong(L,n,d)  = ((long)luaL_optinteger(L, (n), (d)))
 DEF FN luaL_typename(L,i)   = lua_typename(L, lua_type(L,(i)))
 DEF FN luaL_dofile(L, fn)   = (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
 DEF FN luaL_dostring(L, s)      = (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
 DEF FN luaL_getmetatable(L,n) = (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
 'DEF FN luaL_opt(L,f,n,d)       = (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))

CONST LUAL_BUFFERSIZE    = BUFSIZ

'** Generic Buffer manipulation
USEC
typedef struct luaL_Buffer {
  char *p;          /* current position in buffer */
  int lvl;  /* number of strings in the stack (level) */
  lua_State *L;
  char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;
END USEC

 DEF FN luaL_addchar(B,c) = ((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), (*(B)->p++ = (char)(c)))

' compatibility only 
 DEF FN luaL_putchar(B,c) = luaL_addchar(B,c)
 DEF FN luaL_addsize(B,n) = ((B)->p += (n))

 IMPORT "luaL_buffinit(long*, long*)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_prepbuffer(long*)" FROM lib_Lua$ TYPE char*
 IMPORT "luaL_addlstring(long*, char*, long)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_addvalue(long*)" FROM lib_Lua$ TYPE void
 IMPORT "luaL_pushresult(long*)" FROM lib_Lua$ TYPE void

' pre-defined references 
  DEF FN LUA_NOREF       = (-2)
  DEF FN LUA_REFNIL       = (-1)
 ' DEF FN lua_ref(L,lock)    = ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : (lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))
  DEF FN lua_unref(L,ref)  = luaL_unref(L, LUA_REGISTRYINDEX, (ref))
  DEF FN lua_getref(L,ref) = lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
  DEF FN luaL_reg          = luaL_Reg

' Key to file-handle type 
  DEF FN LUA_FILEHANDLE =   "FILE*"

  DEF FN LUA_COLIBNAME  "coroutine"
 IMPORT "luaopen_base(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_TABLIBNAME  = "table"
 IMPORT "luaopen_table(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_IOLIBNAME   = "io"
 IMPORT "luaopen_io(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_OSLIBNAME   = "os"
 IMPORT "luaopen_os(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_STRLIBNAME = "string"
 IMPORT "luaopen_string(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_MATHLIBNAME = "math"
 IMPORT "luaopen_math(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_DBLIBNAME   = "debug"
 IMPORT "luaopen_debug(long*)" FROM lib_Lua$ TYPE int

  DEF FN LUA_LOADLIBNAME = "package"
 IMPORT "luaopen_package(long*)" FROM lib_Lua$ TYPE int

TRAP SYSTEM
CATCH RESET