lua.odin 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847
  1. package lua_5_4
  2. import "base:intrinsics"
  3. import "base:builtin"
  4. import c "core:c/libc"
  5. #assert(size_of(c.int) == size_of(b32))
  6. LUA_SHARED :: #config(LUA_SHARED, false)
  7. when LUA_SHARED {
  8. when ODIN_OS == .Windows {
  9. // LUA_SHARED does nothing special on windows
  10. foreign import lib "windows/lua54dll.lib"
  11. } else when ODIN_OS == .Linux {
  12. foreign import lib "linux/liblua54.so"
  13. } else {
  14. // Note(bumbread): My linux system has a few aliases for this shared object
  15. // lublua5.4.so, liblua.so, lublua.so.5.4, liblua.so.5.4.6. I don't know
  16. // who enforces these numbers (probably ld?), and if it can be done in a
  17. // unix-generic way, but in any way I think the most sane thing to do is to
  18. // keep it close to what linux does and if it breaks, just special case those
  19. // operating systems.
  20. // Also there was no alias for liblua54.so, that seems to suggest that way
  21. // of specifying it isn't portable
  22. foreign import lib "system:liblua.so.5.4"
  23. }
  24. } else {
  25. when ODIN_OS == .Windows {
  26. foreign import lib "windows/lua54dll.lib"
  27. } else when ODIN_OS == .Linux {
  28. foreign import lib "linux/liblua54.a"
  29. } else {
  30. foreign import lib "system:liblua54.a"
  31. }
  32. }
  33. VERSION_MAJOR :: "5"
  34. VERSION_MINOR :: "4"
  35. VERSION_RELEASE :: "2"
  36. VERSION_NUM :: 504
  37. VERSION_RELEASE_NUM :: VERSION_NUM * 100 + 0
  38. VERSION :: "Lua " + VERSION_MAJOR + "." + VERSION_MINOR
  39. RELEASE :: VERSION + "." + VERSION_RELEASE
  40. COPYRIGHT :: RELEASE + " Copyright (C) 1994-2020 Lua.org, PUC-Rio"
  41. AUTHORS :: "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
  42. /* mark for precompiled code ('<esc>Lua') */
  43. SIGNATURE :: "\x1bLua"
  44. /* option for multiple returns in 'lua_pcall' and 'lua_call' */
  45. MULTRET :: -1
  46. REGISTRYINDEX :: -MAXSTACK - 1000
  47. /*
  48. @@ LUAI_MAXSTACK limits the size of the Lua stack.
  49. ** CHANGE it if you need a different limit. This limit is arbitrary;
  50. ** its only purpose is to stop Lua from consuming unlimited stack
  51. ** space (and to reserve some numbers for pseudo-indices).
  52. ** (It must fit into max(size_t)/32.)
  53. */
  54. MAXSTACK :: 1000000
  55. /*
  56. @@ LUA_EXTRASPACE defines the size of a raw memory area associated with
  57. ** a Lua state with very fast access.
  58. ** CHANGE it if you need a different size.
  59. */
  60. EXTRASPACE :: size_of(rawptr)
  61. /*
  62. @@ LUA_IDSIZE gives the maximum size for the description of the source
  63. @@ of a function in debug information.
  64. ** CHANGE it if you want a different size.
  65. */
  66. IDSIZE :: 60
  67. /*
  68. @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
  69. */
  70. L_BUFFERSIZE :: c.int(16 * size_of(rawptr) * size_of(Number))
  71. MAXALIGNVAL :: max(align_of(Number), align_of(f64), align_of(rawptr), align_of(Integer), align_of(c.long))
  72. Status :: enum c.int {
  73. OK = 0,
  74. YIELD = 1,
  75. ERRRUN = 2,
  76. ERRSYNTAX = 3,
  77. ERRMEM = 4,
  78. ERRERR = 5,
  79. ERRFILE = 6,
  80. }
  81. /* thread status */
  82. OK :: Status.OK
  83. YIELD :: Status.YIELD
  84. ERRRUN :: Status.ERRRUN
  85. ERRSYNTAX :: Status.ERRSYNTAX
  86. ERRMEM :: Status.ERRMEM
  87. ERRERR :: Status.ERRERR
  88. ERRFILE :: Status.ERRFILE
  89. /*
  90. ** basic types
  91. */
  92. Type :: enum c.int {
  93. NONE = -1,
  94. NIL = 0,
  95. BOOLEAN = 1,
  96. LIGHTUSERDATA = 2,
  97. NUMBER = 3,
  98. STRING = 4,
  99. TABLE = 5,
  100. FUNCTION = 6,
  101. USERDATA = 7,
  102. THREAD = 8,
  103. }
  104. TNONE :: Type.NONE
  105. TNIL :: Type.NIL
  106. TBOOLEAN :: Type.BOOLEAN
  107. TLIGHTUSERDATA :: Type.LIGHTUSERDATA
  108. TNUMBER :: Type.NUMBER
  109. TSTRING :: Type.STRING
  110. TTABLE :: Type.TABLE
  111. TFUNCTION :: Type.FUNCTION
  112. TUSERDATA :: Type.USERDATA
  113. TTHREAD :: Type.THREAD
  114. NUMTYPES :: 9
  115. ArithOp :: enum c.int {
  116. ADD = 0, /* ORDER TM, ORDER OP */
  117. SUB = 1,
  118. MUL = 2,
  119. MOD = 3,
  120. POW = 4,
  121. DIV = 5,
  122. IDIV = 6,
  123. BAND = 7,
  124. BOR = 8,
  125. BXOR = 9,
  126. SHL = 10,
  127. SHR = 11,
  128. UNM = 12,
  129. BNOT = 13,
  130. }
  131. CompareOp :: enum c.int {
  132. EQ = 0,
  133. LT = 1,
  134. LE = 2,
  135. }
  136. OPADD :: ArithOp.ADD
  137. OPSUB :: ArithOp.SUB
  138. OPMUL :: ArithOp.MUL
  139. OPMOD :: ArithOp.MOD
  140. OPPOW :: ArithOp.POW
  141. OPDIV :: ArithOp.DIV
  142. OPIDIV :: ArithOp.IDIV
  143. OPBAND :: ArithOp.BAND
  144. OPBOR :: ArithOp.BOR
  145. OPBXOR :: ArithOp.BXOR
  146. OPSHL :: ArithOp.SHL
  147. OPSHR :: ArithOp.SHR
  148. OPUNM :: ArithOp.UNM
  149. OPBNOT :: ArithOp.BNOT
  150. OPEQ :: CompareOp.EQ
  151. OPLT :: CompareOp.LT
  152. OPLE :: CompareOp.LE
  153. /* minimum Lua stack available to a C function */
  154. MINSTACK :: 20
  155. /* predefined values in the registry */
  156. RIDX_MAINTHREAD :: 1
  157. RIDX_GLOBALS :: 2
  158. RIDX_LAST :: RIDX_GLOBALS
  159. /* type of numbers in Lua */
  160. Number :: distinct (f32 when size_of(uintptr) == 4 else f64)
  161. /* type for integer functions */
  162. Integer :: distinct (i32 when size_of(uintptr) == 4 else i64)
  163. /* unsigned integer type */
  164. Unsigned :: distinct (u32 when size_of(uintptr) == 4 else u64)
  165. /* type for continuation-function contexts */
  166. KContext :: distinct int
  167. /*
  168. ** Type for C functions registered with Lua
  169. */
  170. CFunction :: #type proc "c" (L: ^State) -> c.int
  171. /*
  172. ** Type for continuation functions
  173. */
  174. KFunction :: #type proc "c" (L: ^State, status: c.int, ctx: KContext) -> c.int
  175. /*
  176. ** Type for functions that read/write blocks when loading/dumping Lua chunks
  177. */
  178. Reader :: #type proc "c" (L: ^State, ud: rawptr, sz: ^c.size_t) -> cstring
  179. Writer :: #type proc "c" (L: ^State, p: rawptr, sz: ^c.size_t, ud: rawptr) -> c.int
  180. /*
  181. ** Type for memory-allocation functions
  182. */
  183. Alloc :: #type proc "c" (ud: rawptr, ptr: rawptr, osize, nsize: c.size_t) -> rawptr
  184. /*
  185. ** Type for warning functions
  186. */
  187. WarnFunction :: #type proc "c" (ud: rawptr, msg: rawptr, tocont: c.int)
  188. GCWhat :: enum c.int {
  189. STOP = 0,
  190. RESTART = 1,
  191. COLLECT = 2,
  192. COUNT = 3,
  193. COUNTB = 4,
  194. STEP = 5,
  195. SETPAUSE = 6,
  196. SETSTEPMUL = 7,
  197. ISRUNNING = 9,
  198. GEN = 10,
  199. INC = 11,
  200. }
  201. GCSTOP :: GCWhat.STOP
  202. GCRESTART :: GCWhat.RESTART
  203. GCCOLLECT :: GCWhat.COLLECT
  204. GCCOUNT :: GCWhat.COUNT
  205. GCCOUNTB :: GCWhat.COUNTB
  206. GCSTEP :: GCWhat.STEP
  207. GCSETPAUSE :: GCWhat.SETPAUSE
  208. GCSETSTEPMUL :: GCWhat.SETSTEPMUL
  209. GCISRUNNING :: GCWhat.ISRUNNING
  210. GCGEN :: GCWhat.GEN
  211. GCINC :: GCWhat.INC
  212. /*
  213. ** Event codes
  214. */
  215. HookEvent :: enum c.int {
  216. CALL = 0,
  217. RET = 1,
  218. LINE = 2,
  219. COUNT = 3,
  220. TAILCALL = 4,
  221. }
  222. HOOKCALL :: HookEvent.CALL
  223. HOOKRET :: HookEvent.RET
  224. HOOKLINE :: HookEvent.LINE
  225. HOOKCOUNT :: HookEvent.COUNT
  226. HOOKTAILCALL :: HookEvent.TAILCALL
  227. /*
  228. ** Event masks
  229. */
  230. HookMask :: distinct bit_set[HookEvent; c.int]
  231. MASKCALL :: HookMask{.CALL}
  232. MASKRET :: HookMask{.RET}
  233. MASKLINE :: HookMask{.LINE}
  234. MASKCOUNT :: HookMask{.COUNT}
  235. /* activation record */
  236. Debug :: struct {
  237. event: HookEvent,
  238. name: cstring, /* (n) */
  239. namewhat: cstring, /* (n) 'global', 'local', 'field', 'method' */
  240. what: cstring, /* (S) 'Lua', 'C', 'main', 'tail' */
  241. source: cstring, /* (S) */
  242. srclen: c.size_t, /* (S) */
  243. currentline: c.int, /* (l) */
  244. linedefined: c.int, /* (S) */
  245. lastlinedefined: c.int, /* (S) */
  246. nups: u8, /* (u) number of upvalues */
  247. nparams: u8, /* (u) number of parameters */
  248. isvararg: bool, /* (u) */
  249. istailcall: bool, /* (t) */
  250. ftransfer: u16, /* (r) index of first value transferred */
  251. ntransfer: u16, /* (r) number of transferred values */
  252. short_src: [IDSIZE]u8 `fmt:"s"`, /* (S) */
  253. /* private part */
  254. i_ci: rawptr, /* active function */
  255. }
  256. /* Functions to be called by the debugger in specific events */
  257. Hook :: #type proc "c" (L: ^State, ar: ^Debug)
  258. State :: struct {} // opaque data type
  259. @(link_prefix="lua_")
  260. @(default_calling_convention="c")
  261. foreign lib {
  262. /*
  263. ** RCS ident string
  264. */
  265. ident: [^]u8 // TODO(bill): is this correct?
  266. /*
  267. ** state manipulation
  268. */
  269. newstate :: proc(f: Alloc, ud: rawptr) -> ^State ---
  270. close :: proc(L: ^State) ---
  271. newthread :: proc(L: ^State) -> ^State ---
  272. resetthread :: proc(L: ^State) -> Status ---
  273. atpanic :: proc(L: ^State, panicf: CFunction) -> CFunction ---
  274. version :: proc(L: ^State) -> Number ---
  275. /*
  276. ** basic stack manipulation
  277. */
  278. absindex :: proc (L: ^State, idx: c.int) -> c.int ---
  279. gettop :: proc (L: ^State) -> c.int ---
  280. settop :: proc (L: ^State, idx: c.int) ---
  281. pushvalue :: proc (L: ^State, idx: c.int) ---
  282. rotate :: proc (L: ^State, idx: c.int, n: c.int) ---
  283. copy :: proc (L: ^State, fromidx, toidx: c.int) ---
  284. checkstack :: proc (L: ^State, n: c.int) -> c.int ---
  285. xmove :: proc(from, to: ^State, n: c.int) ---
  286. /*
  287. ** access functions (stack -> C)
  288. */
  289. isnumber :: proc(L: ^State, idx: c.int) -> b32 ---
  290. isstring :: proc(L: ^State, idx: c.int) -> b32 ---
  291. iscfunction :: proc(L: ^State, idx: c.int) -> b32 ---
  292. isinteger :: proc(L: ^State, idx: c.int) -> b32 ---
  293. isuserdata :: proc(L: ^State, idx: c.int) -> b32 ---
  294. type :: proc(L: ^State, idx: c.int) -> Type ---
  295. typename :: proc(L: ^State, tp: Type) -> cstring ---
  296. @(link_name="lua_tonumberx")
  297. tonumber :: proc(L: ^State, idx: c.int, isnum: ^b32 = nil) -> Number ---
  298. @(link_name="lua_tointegerx")
  299. tointeger :: proc(L: ^State, idx: c.int, isnum: ^b32 = nil) -> Integer ---
  300. toboolean :: proc(L: ^State, idx: c.int) -> b32 ---
  301. tolstring :: proc(L: ^State, idx: c.int, len: ^c.size_t) -> cstring ---
  302. rawlen :: proc(L: ^State, idx: c.int) -> Unsigned ---
  303. tocfunction :: proc(L: ^State, idx: c.int) -> CFunction ---
  304. touserdata :: proc(L: ^State, idx: c.int) -> rawptr ---
  305. tothread :: proc(L: ^State, idx: c.int) -> ^State ---
  306. topointer :: proc(L: ^State, idx: c.int) -> rawptr ---
  307. /*
  308. ** Comparison and arithmetic functions
  309. */
  310. arith :: proc(L: ^State, op: ArithOp) ---
  311. rawequal :: proc(L: ^State, idx1, idx2: c.int) -> b32 ---
  312. compare :: proc(L: ^State, idx1, idx2: c.int, op: CompareOp) -> b32 ---
  313. /*
  314. ** push functions (C -> stack)
  315. */
  316. pushnil :: proc(L: ^State) ---
  317. pushnumber :: proc(L: ^State, n: Number) ---
  318. pushinteger :: proc(L: ^State, n: Integer) ---
  319. pushlstring :: proc(L: ^State, s: cstring, len: c.size_t) -> cstring ---
  320. pushstring :: proc(L: ^State, s: cstring) -> cstring ---
  321. pushvfstring :: proc(L: ^State, fmt: cstring, argp: c.va_list) -> cstring ---
  322. pushfstring :: proc(L: ^State, fmt: cstring, #c_vararg args: ..any) -> cstring ---
  323. pushcclosure :: proc(L: ^State, fn: CFunction, n: c.int) ---
  324. pushboolean :: proc(L: ^State, b: b32) ---
  325. pushlightuserdata :: proc(L: ^State, p: rawptr) ---
  326. pushthread :: proc(L: ^State) -> Status ---
  327. /*
  328. ** get functions (Lua -> stack)
  329. */
  330. getglobal :: proc(L: ^State, name: cstring) -> c.int ---
  331. gettable :: proc(L: ^State, idx: c.int) -> c.int ---
  332. getfield :: proc(L: ^State, idx: c.int, k: cstring) -> c.int ---
  333. geti :: proc(L: ^State, idx: c.int, n: Integer) -> c.int ---
  334. rawget :: proc(L: ^State, idx: c.int) -> c.int ---
  335. rawgeti :: proc(L: ^State, idx: c.int, n: Integer) -> c.int ---
  336. rawgetp :: proc(L: ^State, idx: c.int, p: rawptr) -> c.int ---
  337. createtable :: proc(L: ^State, narr, nrec: c.int) ---
  338. newuserdatauv :: proc(L: ^State, sz: c.size_t, nuvalue: c.int) -> rawptr ---
  339. getmetatable :: proc(L: ^State, objindex: c.int) -> c.int ---
  340. getiuservalue :: proc(L: ^State, idx: c.int, n: c.int) -> c.int ---
  341. /*
  342. ** set functions (stack -> Lua)
  343. */
  344. setglobal :: proc(L: ^State, name: cstring) ---
  345. settable :: proc(L: ^State, idx: c.int) ---
  346. setfield :: proc(L: ^State, idx: c.int, k: cstring) ---
  347. seti :: proc(L: ^State, idx: c.int, n: Integer) ---
  348. rawset :: proc(L: ^State, idx: c.int) ---
  349. rawseti :: proc(L: ^State, idx: c.int, n: Integer) ---
  350. rawsetp :: proc(L: ^State, idx: c.int, p: rawptr) ---
  351. setmetatable :: proc(L: ^State, objindex: c.int) -> c.int ---
  352. setiuservalue :: proc(L: ^State, idx: c.int, n: c.int) -> c.int ---
  353. /*
  354. ** 'load' and 'call' functions (load and run Lua code)
  355. */
  356. @(link_name="lua_callk")
  357. call :: proc(L: ^State, nargs, nresults: c.int,
  358. ctx: KContext = 0, k: KFunction = nil) ---
  359. @(link_name="lua_pcallk")
  360. pcall :: proc(L: ^State, nargs, nresults: c.int, errfunc: c.int,
  361. ctx: KContext = 0, k: KFunction = nil) -> c.int ---
  362. load :: proc(L: ^State, reader: Reader, dt: rawptr,
  363. chunkname, mode: cstring) -> Status ---
  364. dump :: proc(L: ^State, writer: Writer, data: rawptr, strip: b32) -> Status ---
  365. /*
  366. ** coroutine functions
  367. */
  368. @(link_name="lua_yieldk")
  369. yield :: proc(L: ^State, nresults: c.int, ctx: KContext = 0, k: KFunction = nil) -> Status ---
  370. resume :: proc(L: ^State, from: ^State, narg: c.int, nres: ^c.int) -> Status ---
  371. status :: proc(L: ^State) -> Status ---
  372. isyieldable :: proc(L: ^State) -> b32 ---
  373. /*
  374. ** Warning-related functions
  375. */
  376. setwarnf :: proc(L: ^State, f: WarnFunction, ud: rawptr) ---
  377. warning :: proc(L: ^State, msg: string, tocont: b32) ---
  378. /*
  379. ** garbage-collection function and options
  380. */
  381. gc :: proc(L: ^State, what: GCWhat, #c_vararg args: ..any) -> c.int ---
  382. /*
  383. ** miscellaneous functions
  384. */
  385. error :: proc(L: ^State) -> Status ---
  386. next :: proc(L: ^State, idx: c.int) -> c.int ---
  387. concat :: proc(L: ^State, n: c.int) ---
  388. len :: proc(L: ^State, idx: c.int) ---
  389. stringtonumber :: proc(L: ^State, s: cstring) -> c.size_t ---
  390. getallocf :: proc(L: State, ud: ^rawptr) -> Alloc ---
  391. setallocf :: proc(L: ^State, f: Alloc, ud: rawptr) ---
  392. toclose :: proc(L: ^State, idx: c.int) ---
  393. /*
  394. ** {======================================================================
  395. ** Debug API
  396. ** =======================================================================
  397. */
  398. getstack :: proc(L: ^State, level: c.int, ar: ^Debug) -> c.int ---
  399. getinfo :: proc(L: ^State, what: cstring, ar: ^Debug) -> c.int ---
  400. getlocal :: proc(L: ^State, ar: ^Debug, n: c.int) -> cstring ---
  401. setlocal :: proc(L: ^State, ar: ^Debug, n: c.int) -> cstring ---
  402. getupvalue :: proc(L: ^State, funcindex: c.int, n: c.int) -> cstring ---
  403. setupvalue :: proc(L: ^State, funcindex: c.int, n: c.int) -> cstring ---
  404. upvalueid :: proc(L: ^State, fidx, n: c.int) -> rawptr ---
  405. upvaluejoin :: proc(L: ^State, fidx1, n1, fidx2, n2: c.int) ---
  406. sethook :: proc(L: ^State, func: Hook, mask: HookMask, count: c.int) ---
  407. gethook :: proc(L: ^State) -> Hook ---
  408. gethookmask :: proc(L: ^State) -> HookMask ---
  409. gethookcount :: proc(L: ^State) -> c.int ---
  410. setcstacklimit :: proc(L: ^State, limit: c.uint) -> c.int ---
  411. /* }============================================================== */
  412. }
  413. /* version suffix for environment variable names */
  414. VERSUFFIX :: "_" + VERSION_MAJOR + "_" + VERSION_MINOR
  415. COLIBNAME :: "coroutine"
  416. TABLIBNAME :: "table"
  417. IOLIBNAME :: "io"
  418. OSLIBNAME :: "os"
  419. STRLIBNAME :: "string"
  420. UTF8LIBNAME :: "utf8"
  421. MATHLIBNAME :: "math"
  422. DBLIBNAME :: "debug"
  423. LOADLIBNAME :: "package"
  424. @(link_prefix="lua")
  425. @(default_calling_convention="c")
  426. foreign lib {
  427. open_base :: proc(L: ^State) -> c.int ---
  428. open_coroutine :: proc(L: ^State) -> c.int ---
  429. open_table :: proc(L: ^State) -> c.int ---
  430. open_io :: proc(L: ^State) -> c.int ---
  431. open_os :: proc(L: ^State) -> c.int ---
  432. open_string :: proc(L: ^State) -> c.int ---
  433. open_utf8 :: proc(L: ^State) -> c.int ---
  434. open_math :: proc(L: ^State) -> c.int ---
  435. open_debug :: proc(L: ^State) -> c.int ---
  436. open_package :: proc(L: ^State) -> c.int ---
  437. /* open all previous libraries */
  438. L_openlibs :: proc(L: ^State) ---
  439. }
  440. GNAME :: "_G"
  441. /* key, in the registry, for table of loaded modules */
  442. LOADED_TABLE :: "_LOADED"
  443. /* key, in the registry, for table of preloaded loaders */
  444. PRELOAD_TABLE :: "_PRELOAD"
  445. L_Reg :: struct {
  446. name: cstring,
  447. func: CFunction,
  448. }
  449. L_NUMSIZES :: size_of(Integer)*16 + size_of(Number)
  450. /* predefined references */
  451. NOREF :: -2
  452. REFNIL :: -1
  453. @(link_prefix="lua")
  454. @(default_calling_convention="c")
  455. foreign lib {
  456. @(link_name="luaL_checkversion_")
  457. L_checkversion :: proc(L: ^State, ver: Number = VERSION_NUM, sz: c.size_t = L_NUMSIZES) ---
  458. L_getmetafield :: proc(L: ^State, obj: c.int, e: cstring) -> c.int ---
  459. L_callmeta :: proc(L: ^State, obj: c.int, e: cstring) -> c.int ---
  460. @(link_name="luaL_tolstring")
  461. L_tostring :: proc(L: ^State, idx: c.int, len: ^c.size_t = nil) -> cstring ---
  462. L_argerror :: proc(L: ^State, arg: c.int, extramsg: cstring) -> c.int ---
  463. L_typeerror :: proc(L: ^State, arg: c.int, tname: cstring) -> c.int ---
  464. @(link_name="luaL_checklstring")
  465. L_checkstring :: proc(L: ^State, arg: c.int, l: ^c.size_t = nil) -> cstring ---
  466. @(link_name="luaL_optlstring")
  467. L_optstring :: proc(L: ^State, arg: c.int, def: cstring, l: ^c.size_t = nil) -> cstring ---
  468. L_checknumber :: proc(L: ^State, arg: c.int) -> Number ---
  469. L_optnumber :: proc(L: ^State, arg: c.int, def: Number) -> Number ---
  470. L_checkinteger :: proc(L: ^State, arg: c.int) -> Integer ---
  471. L_optinteger :: proc(L: ^State, arg: c.int, def: Integer) -> Integer ---
  472. L_checkstack :: proc(L: ^State, sz: c.int, msg: cstring) ---
  473. L_checktype :: proc(L: ^State, arg: c.int, t: c.int) ---
  474. L_checkany :: proc(L: ^State, arg: c.int) ---
  475. L_newmetatable :: proc(L: ^State, tname: cstring) -> c.int ---
  476. L_setmetatable :: proc(L: ^State, tname: cstring) ---
  477. L_testudata :: proc(L: ^State, ud: c.int, tname: cstring) -> rawptr ---
  478. L_checkudata :: proc(L: ^State, ud: c.int, tname: cstring) -> rawptr ---
  479. L_where :: proc(L: ^State, lvl: c.int) ---
  480. L_error :: proc(L: ^State, fmt: cstring, #c_vararg args: ..any) -> Status ---
  481. L_checkoption :: proc(L: ^State, arg: c.int, def: cstring, lst: [^]cstring) -> c.int ---
  482. L_fileresult :: proc(L: ^State, stat: c.int, fname: cstring) -> c.int ---
  483. L_execresult :: proc(L: ^State, stat: c.int) -> c.int ---
  484. L_ref :: proc(L: ^State, t: c.int) -> c.int ---
  485. L_unref :: proc(L: ^State, t: c.int, ref: c.int) ---
  486. @(link_name="luaL_loadfilex")
  487. L_loadfile :: proc (L: ^State, filename: cstring, mode: cstring = nil) -> Status ---
  488. @(link_name="luaL_loadbufferx")
  489. L_loadbuffer :: proc(L: ^State, buff: [^]byte, sz: c.size_t, name: cstring, mode: cstring = nil) -> Status ---
  490. L_loadstring :: proc(L: ^State, s: cstring) -> Status ---
  491. L_newstate :: proc() -> ^State ---
  492. L_len :: proc(L: ^State, idx: c.int) -> Integer ---
  493. L_addgsub :: proc(b: ^L_Buffer, s, p, r: cstring) ---
  494. L_gsub :: proc(L: ^State, s, p, r: cstring) -> cstring ---
  495. L_setfuncs :: proc(L: ^State, l: [^]L_Reg, nup: c.int) ---
  496. L_getsubtable :: proc(L: ^State, idx: c.int, fname: cstring) -> c.int ---
  497. L_traceback :: proc(L: ^State, L1: ^State, msg: cstring, level: c.int) ---
  498. L_requiref :: proc(L: ^State, modname: cstring, openf: CFunction, glb: c.int) ---
  499. }
  500. /*
  501. ** {======================================================
  502. ** Generic Buffer manipulation
  503. ** =======================================================
  504. */
  505. L_Buffer :: struct {
  506. b: [^]byte, /* buffer address */
  507. size: c.size_t, /* buffer size */
  508. n: c.size_t, /* number of characters in buffer */
  509. L: ^State,
  510. init: struct #raw_union {
  511. n: Number, u: f64, s: rawptr, i: Integer, l: c.long,
  512. b: [L_BUFFERSIZE]byte, /* initial buffer */
  513. },
  514. }
  515. L_bufflen :: #force_inline proc "c" (bf: ^L_Buffer) -> c.size_t {
  516. return bf.n
  517. }
  518. L_buffaddr :: #force_inline proc "c" (bf: ^L_Buffer) -> [^]byte {
  519. return bf.b
  520. }
  521. L_addchar :: #force_inline proc "c" (B: ^L_Buffer, c: byte) {
  522. if B.n < B.size {
  523. L_prepbuffsize(B, 1)
  524. }
  525. B.b[B.n] = c
  526. B.n += 1
  527. }
  528. L_addsize :: #force_inline proc "c" (B: ^L_Buffer, s: c.size_t) -> c.size_t {
  529. B.n += s
  530. return B.n
  531. }
  532. L_buffsub :: #force_inline proc "c" (B: ^L_Buffer, s: c.size_t) -> c.size_t {
  533. B.n -= s
  534. return B.n
  535. }
  536. L_prepbuffer :: #force_inline proc "c" (B: ^L_Buffer) -> [^]byte {
  537. return L_prepbuffsize(B, c.size_t(L_BUFFERSIZE))
  538. }
  539. @(link_prefix="lua")
  540. @(default_calling_convention="c")
  541. foreign lib {
  542. L_buffinit :: proc(L: ^State, B: ^L_Buffer) ---
  543. L_prepbuffsize :: proc(B: ^L_Buffer, sz: c.size_t) -> [^]byte ---
  544. L_addlstring :: proc(B: ^L_Buffer, s: cstring, l: c.size_t) ---
  545. L_addstring :: proc(B: ^L_Buffer, s: cstring) ---
  546. L_addvalue :: proc(B: ^L_Buffer) ---
  547. L_pushresult :: proc(B: ^L_Buffer) ---
  548. L_pushresultsize :: proc(B: ^L_Buffer, sz: c.size_t) ---
  549. L_buffinitsize :: proc(L: ^State, B: ^L_Buffer, sz: c.size_t) -> [^]byte ---
  550. }
  551. /* }====================================================== */
  552. /*
  553. ** {==============================================================
  554. ** some useful macros
  555. ** ===============================================================
  556. */
  557. getextraspace :: #force_inline proc "c" (L: ^State) -> rawptr {
  558. return rawptr(([^]byte)(L)[-EXTRASPACE:])
  559. }
  560. pop :: #force_inline proc "c" (L: ^State, n: c.int) {
  561. settop(L, -n-1)
  562. }
  563. newtable :: #force_inline proc "c" (L: ^State) {
  564. createtable(L, 0, 0)
  565. }
  566. register :: #force_inline proc "c" (L: ^State, n: cstring, f: CFunction) {
  567. pushcfunction(L, f)
  568. setglobal(L, n)
  569. }
  570. pushcfunction :: #force_inline proc "c" (L: ^State, f: CFunction) {
  571. pushcclosure(L, f, 0)
  572. }
  573. isfunction :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .FUNCTION }
  574. istable :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .TABLE }
  575. islightuserdata :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .LIGHTUSERDATA }
  576. isnil :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .NIL }
  577. isboolean :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .BOOLEAN }
  578. isthread :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .THREAD }
  579. isnone :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) == .NONE }
  580. isnoneornil :: #force_inline proc "c" (L: ^State, n: c.int) -> bool { return type(L, n) <= .NIL }
  581. pushliteral :: pushstring
  582. pushglobaltable :: #force_inline proc "c" (L: ^State) {
  583. rawgeti(L, REGISTRYINDEX, RIDX_GLOBALS)
  584. }
  585. tostring :: #force_inline proc "c" (L: ^State, i: c.int) -> cstring {
  586. return tolstring(L, i, nil)
  587. }
  588. insert :: #force_inline proc "c" (L: ^State, idx: c.int) {
  589. rotate(L, idx, 1)
  590. }
  591. remove :: #force_inline proc "c" (L: ^State, idx: c.int) {
  592. rotate(L, idx, -1)
  593. pop(L, 1)
  594. }
  595. replace :: #force_inline proc "c" (L: ^State, idx: c.int) {
  596. copy(L, -1, idx)
  597. pop(L, 1)
  598. }
  599. L_newlibtable :: #force_inline proc "c" (L: ^State, l: []L_Reg) {
  600. createtable(L, 0, c.int(builtin.len(l) - 1))
  601. }
  602. L_newlib :: proc(L: ^State, l: []L_Reg) {
  603. L_checkversion(L)
  604. L_newlibtable(L, l)
  605. L_setfuncs(L, raw_data(l), 0)
  606. }
  607. L_argcheck :: #force_inline proc "c" (L: ^State, cond: bool, arg: c.int, extramsg: cstring) {
  608. if cond {
  609. L_argerror(L, arg, extramsg)
  610. }
  611. }
  612. L_argexpected :: #force_inline proc "c" (L: ^State, cond: bool, arg: c.int, tname: cstring) {
  613. if cond {
  614. L_typeerror(L, arg, tname)
  615. }
  616. }
  617. L_typename :: #force_inline proc "c" (L: ^State, i: c.int) -> cstring {
  618. return typename(L, type(L, i))
  619. }
  620. L_dofile :: #force_inline proc "c" (L: ^State, s: cstring) -> c.int {
  621. err := L_loadfile(L, s)
  622. return pcall(L, 0, MULTRET, 0) if err == nil else c.int(err)
  623. }
  624. L_dostring :: #force_inline proc "c" (L: ^State, s: cstring) -> c.int {
  625. err := L_loadstring(L, s)
  626. return pcall(L, 0, MULTRET, 0) if err == nil else c.int(err)
  627. }
  628. L_getmetatable :: #force_inline proc "c" (L: ^State, n: cstring) -> c.int {
  629. return getfield(L, REGISTRYINDEX, n)
  630. }
  631. L_opt :: #force_inline proc "c" (L: ^State, f: $F, n: c.int, d: $T) -> T where intrinsics.type_is_proc(F) {
  632. return d if isnoneornil(L, n) else f(L, n)
  633. }
  634. /* push the value used to represent failure/error */
  635. pushfail :: pushnil
  636. /* }============================================================== */
  637. /*
  638. ** {==============================================================
  639. ** compatibility macros
  640. ** ===============================================================
  641. */
  642. newuserdata :: #force_inline proc "c" (L: ^State, s: c.size_t) -> rawptr {
  643. return newuserdatauv(L, s, 1)
  644. }
  645. getuservalue :: #force_inline proc "c" (L: ^State, idx: c.int) -> c.int {
  646. return getiuservalue(L, idx, 1)
  647. }
  648. setuservalue :: #force_inline proc "c" (L: ^State, idx: c.int) -> c.int {
  649. return setiuservalue(L, idx, 1)
  650. }