Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

FFI C-ABI Reference

NicyRuntime exports 92 functions with a stable extern "C-unwind" ABI. This includes 90 Lua C API wrappers for complete Luau state management and 2 error code utilities.

Header File

πŸ“₯ Download NicyRuntime.h

Include in your C/C++ project:

#include "NicyRuntime.h"

Calling Convention

All functions use extern "C-unwind", allowing exceptions to propagate across FFI boundaries. In C, these are mapped according to the platform’s ABI (e.g., __cdecl on Windows).

Stack Operations

FunctionSignature
nicy_lua_gettopint nicy_lua_gettop(nicy_State *L);
nicy_lua_settopvoid nicy_lua_settop(nicy_State *L, int idx);
nicy_lua_pushvaluevoid nicy_lua_pushvalue(nicy_State *L, int idx);
nicy_lua_removevoid nicy_lua_remove(nicy_State *L, int idx);
nicy_lua_insertvoid nicy_lua_insert(nicy_State *L, int idx);
nicy_lua_absindexint nicy_lua_absindex(nicy_State *L, int idx);
nicy_lua_checkstackint nicy_lua_checkstack(nicy_State *L, int extra);
nicy_lua_popvoid nicy_lua_pop(nicy_State *L, int n); (macro: settop(L, -n-1))

Push Operations

FunctionSignature
nicy_lua_pushnilvoid nicy_lua_pushnil(nicy_State *L);
nicy_lua_pushbooleanvoid nicy_lua_pushboolean(nicy_State *L, int b);
nicy_lua_pushnumbervoid nicy_lua_pushnumber(nicy_State *L, nicy_Number n);
nicy_lua_pushintegervoid nicy_lua_pushinteger(nicy_State *L, nicy_Integer n);
nicy_lua_pushstringvoid nicy_lua_pushstring(nicy_State *L, const char *s);
nicy_lua_pushlstringvoid nicy_lua_pushlstring(nicy_State *L, const char *s, size_t len);
nicy_lua_pushcfunctionvoid nicy_lua_pushcfunction(nicy_State *L, nicy_CFunction f);
nicy_lua_pushcclosurevoid nicy_lua_pushcclosure(nicy_State *L, nicy_CFunction f, int n);
nicy_lua_pushlightuserdatavoid nicy_lua_pushlightuserdata(nicy_State *L, void *p);
nicy_lua_pushvectorvoid nicy_lua_pushvector(nicy_State *L, float x, float y, float z, float w);
nicy_lua_newuserdatavoid *nicy_lua_newuserdata(nicy_State *L, size_t sz);
nicy_lua_newbuffervoid *nicy_lua_newbuffer(nicy_State *L, size_t sz);
nicy_lua_newthreadnicy_State *nicy_lua_newthread(nicy_State *L);

Type Checking

FunctionSignature
nicy_lua_typeint nicy_lua_type(nicy_State *L, int idx);
nicy_lua_typenameconst char *nicy_lua_typename(nicy_State *L, int tp);
nicy_lua_isnilint nicy_lua_isnil(nicy_State *L, int idx);
nicy_lua_isbooleanint nicy_lua_isboolean(nicy_State *L, int idx);
nicy_lua_isnumberint nicy_lua_isnumber(nicy_State *L, int idx);
nicy_lua_isstringint nicy_lua_isstring(nicy_State *L, int idx);
nicy_lua_istableint nicy_lua_istable(nicy_State *L, int idx);
nicy_lua_isfunctionint nicy_lua_isfunction(nicy_State *L, int idx);
nicy_lua_isuserdataint nicy_lua_isuserdata(nicy_State *L, int idx);
nicy_lua_isthreadint nicy_lua_isthread(nicy_State *L, int idx);
nicy_lua_iscfunctionint nicy_lua_iscfunction(nicy_State *L, int idx);
nicy_lua_isintegerint nicy_lua_isinteger(nicy_State *L, int idx);
nicy_lua_isbufferint nicy_lua_isbuffer(nicy_State *L, int idx);
nicy_lua_isvectorint nicy_lua_isvector(nicy_State *L, int idx);

Get & Conversion

FunctionSignature
nicy_lua_tostringconst char *nicy_lua_tostring(nicy_State *L, int idx);
nicy_lua_tolstringconst char *nicy_lua_tolstring(nicy_State *L, int idx, size_t *len);
nicy_lua_tobooleanint nicy_lua_toboolean(nicy_State *L, int idx);
nicy_lua_tonumbernicy_Number nicy_lua_tonumber(nicy_State *L, int idx);
nicy_lua_tointegernicy_Integer nicy_lua_tointeger(nicy_State *L, int idx);
nicy_lua_touserdatavoid *nicy_lua_touserdata(nicy_State *L, int idx);
nicy_lua_tobuffervoid *nicy_lua_tobuffer(nicy_State *L, int idx, size_t *len);
nicy_lua_tovectorconst float *nicy_lua_tovector(nicy_State *L, int idx);

Table Access

FunctionSignature
nicy_lua_getfieldvoid nicy_lua_getfield(nicy_State *L, int idx, const char *k);
nicy_lua_getglobalvoid nicy_lua_getglobal(nicy_State *L, const char *k);
nicy_lua_setglobalvoid nicy_lua_setglobal(nicy_State *L, const char *k);
nicy_lua_gettablevoid nicy_lua_gettable(nicy_State *L, int idx);
nicy_lua_settablevoid nicy_lua_settable(nicy_State *L, int idx);
nicy_lua_rawgetvoid nicy_lua_rawget(nicy_State *L, int idx);
nicy_lua_rawgetivoid nicy_lua_rawgeti(nicy_State *L, int idx, nicy_Integer n);
nicy_lua_rawsetvoid nicy_lua_rawset(nicy_State *L, int idx);
nicy_lua_rawsetivoid nicy_lua_rawseti(nicy_State *L, int idx, nicy_Integer n);
nicy_lua_getmetatableint nicy_lua_getmetatable(nicy_State *L, int idx);
nicy_lua_setmetatableint nicy_lua_setmetatable(nicy_State *L, int idx);
nicy_lua_createtablevoid nicy_lua_createtable(nicy_State *L, int narr, int nrec);
nicy_lua_nextint nicy_lua_next(nicy_State *L, int idx);

Call & Execution

FunctionSignature
nicy_lua_callvoid nicy_lua_call(nicy_State *L, int nargs, int nresults);
nicy_lua_pcallint nicy_lua_pcall(nicy_State *L, int nargs, int nresults, int errfunc);
nicy_lua_errorint nicy_lua_error(nicy_State *L);
nicy_lua_resumeint nicy_lua_resume(nicy_State *L, nicy_State *from, int nargs, int *nres);
nicy_lua_yieldint nicy_lua_yield(nicy_State *L, int nresults);

Comparison & Other

FunctionSignature
nicy_lua_equalint nicy_lua_equal(nicy_State *L, int idx1, int idx2);
nicy_lua_lessthanint nicy_lua_lessthan(nicy_State *L, int idx1, int idx2);
nicy_lua_rawequalint nicy_lua_rawequal(nicy_State *L, int idx1, int idx2);
nicy_lua_concatvoid nicy_lua_concat(nicy_State *L, int n);
nicy_lua_gcint nicy_lua_gc(nicy_State *L, int what, int data);
nicy_lua_rawlensize_t nicy_lua_rawlen(nicy_State *L, int idx);

Lua 5.1 Compatibility

FunctionSignature
nicy_lua_getfenvvoid nicy_lua_getfenv(nicy_State *L, int idx);
nicy_lua_setfenvint nicy_lua_setfenv(nicy_State *L, int idx);

Auxiliary Library (lauxlib)

FunctionSignature
nicy_luaL_checkstringconst char *nicy_luaL_checkstring(nicy_State *L, int narg);
nicy_luaL_checklstringconst char *nicy_luaL_checklstring(nicy_State *L, int narg, size_t *len);
nicy_luaL_checknumbernicy_Number nicy_luaL_checknumber(nicy_State *L, int narg);
nicy_luaL_checkbooleanint nicy_luaL_checkboolean(nicy_State *L, int narg);
nicy_luaL_checkintegernicy_Integer nicy_luaL_checkinteger(nicy_State *L, int narg);
nicy_luaL_checktypevoid nicy_luaL_checktype(nicy_State *L, int narg, int t);
nicy_luaL_checkanyvoid nicy_luaL_checkany(nicy_State *L, int narg);
nicy_luaL_checkbuffervoid *nicy_luaL_checkbuffer(nicy_State *L, int narg, size_t *len);
nicy_luaL_optstringconst char *nicy_luaL_optstring(nicy_State *L, int narg, const char *d);
nicy_luaL_optintegernicy_Integer nicy_luaL_optinteger(nicy_State *L, int narg, nicy_Integer d);
nicy_luaL_optnumbernicy_Number nicy_luaL_optnumber(nicy_State *L, int narg, nicy_Number d);
nicy_luaL_argerrorint nicy_luaL_argerror(nicy_State *L, int narg, const char *extramsg);
nicy_luaL_wherevoid nicy_luaL_where(nicy_State *L, int lvl);
nicy_luaL_tracebackvoid nicy_luaL_traceback(nicy_State *L, nicy_State *L1, const char *msg, int level);
nicy_luaL_refint nicy_luaL_ref(nicy_State *L, int t);
nicy_luaL_unrefvoid nicy_luaL_unref(nicy_State *L, int t, int ref);
nicy_luaL_lennicy_Integer nicy_luaL_len(nicy_State *L, int idx);
nicy_luaL_newmetatableint nicy_luaL_newmetatable(nicy_State *L, const char *tname);
nicy_luaL_getmetatableint nicy_luaL_getmetatable(nicy_State *L, const char *tname);
nicy_luaL_errorint nicy_luaL_error(nicy_State *L, const char *msg);

Error Code Utilities

These functions help FFI integrators work with NicyRuntime’s error codes:

FunctionSignatureDescription
nicy_error_nameconst char *nicy_error_name(int code);Convert error code to name string (e.g., 103 β†’ "NICY_ERR_CYCLIC_REQUIRE")
nicy_is_nicy_errorint nicy_is_nicy_error(int code);Returns 1 if code is Nicy-specific (100+), 0 if standard Luau

Example (C)

int err = nicy_start("script.luau");
if (err != 0) {
    const char* name = nicy_error_name(err);
    int is_nicy = nicy_is_nicy_error(err);
    
    if (is_nicy) {
        fprintf(stderr, "Nicy error: %s\n", name);
    } else {
        fprintf(stderr, "Luau error: %s\n", name);
    }
}

Source Code (NicyRuntime.h)

Below is the complete, automatically synchronized source code of the NicyRuntime.h C header file.

/*
 * NicyRuntime.h β€” C header for the Nicy Runtime Luau engine.
 *
 * Provides:
 *   1. Core runtime functions (start, eval, compile, version)
 *   2. Full Lua C API wrappers prefixed with nicy_lua_*
 *   3. Auxlib wrappers prefixed with nicy_luaL_*
 *   4. Type definitions, constants, and calling-convention macros
 *
 * Link against nicyruntime.dll / libnicyruntime.so / libnicyruntime.dylib
 *
 * Copyright (C) 2026 Yanlvl99 | Nicy Luau Runtime Development
 * Licensed under the Mozilla Public License 2.0.
 */

#ifndef NICY_RUNTIME_H
#define NICY_RUNTIME_H

#include <stddef.h>
#include <stdint.h>

/* ================================================================
 * Calling convention
 * ================================================================ */

#if defined(_WIN32) || defined(__WIN32__)
  #define NICY_CAPI __cdecl
#else
  #define NICY_CAPI
#endif

#if defined(__cplusplus)
  #define NICY_EXTERN_C extern "C"
#else
  #define NICY_EXTERN_C extern
#endif

/* ================================================================
 * Opaque types
 * ================================================================ */

typedef struct lua_State nicy_State;

/* ================================================================
 * Integer and Number types (match Luau internals)
 * ================================================================ */

typedef intptr_t nicy_Integer;   /* lua_Integer  β€” signed integer  */
typedef double   nicy_Number;    /* lua_Number   β€” floating point  */

/* C function pointer type */
typedef int (NICY_CAPI *nicy_CFunction)(nicy_State *L);

/* ================================================================
 * Lua type codes  (lua_type() return values)
 * ================================================================ */

#define NICY_LUA_TNONE        (-1)
#define NICY_LUA_TNIL          0
#define NICY_LUA_TBOOLEAN      1
#define NICY_LUA_TLIGHTUSERDATA 2
#define NICY_LUA_TNUMBER       3
#define NICY_LUA_TINTEGER      4
#define NICY_LUA_TVECTOR       5
#define NICY_LUA_TSTRING       6
#define NICY_LUA_TTABLE        7
#define NICY_LUA_TFUNCTION     8
#define NICY_LUA_TUSERDATA     9
#define NICY_LUA_TTHREAD       10
#define NICY_LUA_TBUFFER       11

/* ================================================================
 * Lua status / error codes
 * ================================================================ */

#define NICY_LUA_OK            0
#define NICY_LUA_YIELD         1
#define NICY_LUA_ERRRUN        2
#define NICY_LUA_ERRSYNTAX     3
#define NICY_LUA_ERRMEM        4
#define NICY_LUA_ERRERR        5
#define NICY_LUA_ERRFILE       6

/* ================================================================
 * GC options  (for nicy_lua_gc)
 * ================================================================ */

#define NICY_LUA_GCSTOP        0
#define NICY_LUA_GCRESTART     1
#define NICY_LUA_GCCOLLECT     2
#define NICY_LUA_GCCOUNT       3
#define NICY_LUA_GCCOUNTB      4
#define NICY_LUA_GCSTEP        5
#define NICY_LUA_GCSETPAUSE     6
#define NICY_LUA_GCSETSTEPMUL   7
#define NICY_LUA_GCISRUNNING    9

/* ================================================================
 * Registry pseudo-index
 * ================================================================ */

#define NICY_LUA_REGISTRYINDEX  (-10000)

/* Number of multiple results (used as nresults in pcall/call) */
#define NICY_LUA_MULTRET        (-1)

/* ================================================================
 * 1. Core Runtime API
 * ================================================================ */

/**
 * nicy_start β€” Load and execute a Luau script file.
 *
 * @param filepath  Absolute or relative path to a .luau, .lua, or .luauc file.
 *
 * Creates a new Lua state, loads standard libraries, registers the
 * `runtime` and `task` globals, resolves require(), and runs the
 * script to completion (including all scheduled tasks).
 *
 * Prints errors to stderr and exits on fatal failures.
 * Thread-safe β€” each call creates an independent Lua state.
 */
NICY_EXTERN_C void NICY_CAPI nicy_start(const char *filepath);

/**
 * nicy_eval β€” Evaluate a string of Luau source code.
 *
 * @param code  NUL-terminated Luau source code.
 *
 * Creates an isolated Lua state with standard libraries, compiles
 * and runs the code, then tears everything down.  Errors are
 * printed to stderr.
 *
 * Useful for quick one-liners or embedding small scripts.
 */
NICY_EXTERN_C void NICY_CAPI nicy_eval(const char *code);

/**
 * nicy_compile β€” Compile a Luau script to bytecode (.luauc).
 *
 * @param filepath  Path to a .luau or .lua source file.
 *
 * Reads the source, applies compiler directives (--!native, --!optimize,
 * etc.), and writes the bytecode to <basename>.luauc in the same
 * directory.
 */
NICY_EXTERN_C void NICY_CAPI nicy_compile(const char *filepath);

/**
 * nicy_version β€” Return a human-readable version string.
 *
 * @return  Static string such as "Nicy Runtime 1.0.0-alpha".
 *          Do not free.
 */
NICY_EXTERN_C const char * NICY_CAPI nicy_version(void);

/**
 * nicy_luau_version β€” Return the embedded Luau version string.
 *
 * @return  Static string such as "0.709".  Do not free.
 */
NICY_EXTERN_C const char * NICY_CAPI nicy_luau_version(void);

/* ================================================================
 * 2. Stack manipulation
 * ================================================================ */

NICY_EXTERN_C int  NICY_CAPI nicy_lua_gettop(nicy_State *L);
NICY_EXTERN_C void NICY_CAPI nicy_lua_settop(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushvalue(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_remove(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_insert(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_checkstack(nicy_State *L, int extra);

/* ================================================================
 * 3. Push operations
 * ================================================================ */

NICY_EXTERN_C void NICY_CAPI nicy_lua_pushnil(nicy_State *L);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushboolean(nicy_State *L, int b);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushnumber(nicy_State *L, nicy_Number n);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushinteger(nicy_State *L, nicy_Integer n);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushstring(nicy_State *L, const char *s);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushlstring(nicy_State *L, const char *s, size_t len);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushcfunction(nicy_State *L, nicy_CFunction f);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushcclosure(nicy_State *L, nicy_CFunction f, int n);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushlightuserdata(nicy_State *L, void *p);
NICY_EXTERN_C void NICY_CAPI nicy_lua_pushvector(nicy_State *L, float x, float y, float z, float w);
NICY_EXTERN_C void *NICY_CAPI nicy_lua_newuserdata(nicy_State *L, size_t sz);
NICY_EXTERN_C void *NICY_CAPI nicy_lua_newbuffer(nicy_State *L, size_t sz);
NICY_EXTERN_C nicy_State *NICY_CAPI nicy_lua_newthread(nicy_State *L);

/* ================================================================
 * 4. Query / check type
 * ================================================================ */

NICY_EXTERN_C int  NICY_CAPI nicy_lua_type(nicy_State *L, int idx);
NICY_EXTERN_C const char *NICY_CAPI nicy_lua_typename(nicy_State *L, int tp);

NICY_EXTERN_C int  NICY_CAPI nicy_lua_isnil(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isboolean(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isnumber(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isstring(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_istable(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isfunction(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isuserdata(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isthread(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_iscfunction(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isinteger(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isbuffer(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_isvector(nicy_State *L, int idx);

/* ================================================================
 * 5. Get / conversion operations
 * ================================================================ */

NICY_EXTERN_C const char *NICY_CAPI nicy_lua_tostring(nicy_State *L, int idx);
NICY_EXTERN_C const char *NICY_CAPI nicy_lua_tolstring(nicy_State *L, int idx, size_t *len);
NICY_EXTERN_C int         NICY_CAPI nicy_lua_toboolean(nicy_State *L, int idx);
NICY_EXTERN_C nicy_Number NICY_CAPI nicy_lua_tonumber(nicy_State *L, int idx);
NICY_EXTERN_C nicy_Integer NICY_CAPI nicy_lua_tointeger(nicy_State *L, int idx);
NICY_EXTERN_C void *      NICY_CAPI nicy_lua_touserdata(nicy_State *L, int idx);
NICY_EXTERN_C void *      NICY_CAPI nicy_lua_tobuffer(nicy_State *L, int idx, size_t *len);
NICY_EXTERN_C const float *NICY_CAPI nicy_lua_tovector(nicy_State *L, int idx);

/* ================================================================
 * 6. Table and global access β€” get
 * ================================================================ */

NICY_EXTERN_C void NICY_CAPI nicy_lua_getfield(nicy_State *L, int idx, const char *k);
NICY_EXTERN_C void NICY_CAPI nicy_lua_getglobal(nicy_State *L, const char *k);
NICY_EXTERN_C void NICY_CAPI nicy_lua_gettable(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_rawget(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_rawgeti(nicy_State *L, int idx, nicy_Integer n);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_getmetatable(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_next(nicy_State *L, int idx);

/* ================================================================
 * 7. Table and global access β€” set
 * ================================================================ */

NICY_EXTERN_C void NICY_CAPI nicy_lua_setfield(nicy_State *L, int idx, const char *k);
NICY_EXTERN_C void NICY_CAPI nicy_lua_setglobal(nicy_State *L, const char *k);
NICY_EXTERN_C void NICY_CAPI nicy_lua_settable(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_rawset(nicy_State *L, int idx);
NICY_EXTERN_C void NICY_CAPI nicy_lua_rawseti(nicy_State *L, int idx, nicy_Integer n);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_setmetatable(nicy_State *L, int idx);

/* ================================================================
 * 8. Table / array creation
 * ================================================================ */

NICY_EXTERN_C void NICY_CAPI nicy_lua_createtable(nicy_State *L, int narr, int nrec);

/* ================================================================
 * 9. Call and execution
 * ================================================================ */

NICY_EXTERN_C void NICY_CAPI nicy_lua_call(nicy_State *L, int nargs, int nresults);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_pcall(nicy_State *L, int nargs, int nresults, int errfunc);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_error(nicy_State *L);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_resume(nicy_State *L, nicy_State *from, int nargs, int *nres);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_yield(nicy_State *L, int nresults);

/* ================================================================
 * 10. Comparison
 * ================================================================ */

NICY_EXTERN_C int NICY_CAPI nicy_lua_equal(nicy_State *L, int idx1, int idx2);
NICY_EXTERN_C int NICY_CAPI nicy_lua_lessthan(nicy_State *L, int idx1, int idx2);
NICY_EXTERN_C int NICY_CAPI nicy_lua_rawequal(nicy_State *L, int idx1, int idx2);

/* ================================================================
 * 11. Other operations
 * ================================================================ */

NICY_EXTERN_C void  NICY_CAPI nicy_lua_concat(nicy_State *L, int n);
NICY_EXTERN_C int   NICY_CAPI nicy_lua_gc(nicy_State *L, int what, int data);
NICY_EXTERN_C size_t NICY_CAPI nicy_lua_rawlen(nicy_State *L, int idx);
NICY_EXTERN_C int   NICY_CAPI nicy_lua_absindex(nicy_State *L, int idx);

/* ================================================================
 * 12. Environment (Lua 5.1 compat)
 * ================================================================ */

NICY_EXTERN_C void NICY_CAPI nicy_lua_getfenv(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_lua_setfenv(nicy_State *L, int idx);

/* ================================================================
 * 13. lauxlib β€” check / opt helpers
 * ================================================================ */

NICY_EXTERN_C const char *NICY_CAPI nicy_luaL_checkstring(nicy_State *L, int narg);
NICY_EXTERN_C const char *NICY_CAPI nicy_luaL_checklstring(nicy_State *L, int narg, size_t *len);
NICY_EXTERN_C void *       NICY_CAPI nicy_luaL_checkbuffer(nicy_State *L, int narg, size_t *len);
NICY_EXTERN_C nicy_Number  NICY_CAPI nicy_luaL_checknumber(nicy_State *L, int narg);
NICY_EXTERN_C int          NICY_CAPI nicy_luaL_checkboolean(nicy_State *L, int narg);
NICY_EXTERN_C nicy_Integer NICY_CAPI nicy_luaL_checkinteger(nicy_State *L, int narg);
NICY_EXTERN_C void         NICY_CAPI nicy_luaL_checktype(nicy_State *L, int narg, int t);
NICY_EXTERN_C void         NICY_CAPI nicy_luaL_checkany(nicy_State *L, int narg);

NICY_EXTERN_C const char *NICY_CAPI nicy_luaL_optstring(nicy_State *L, int narg, const char *d);
NICY_EXTERN_C nicy_Integer NICY_CAPI nicy_luaL_optinteger(nicy_State *L, int narg, nicy_Integer d);
NICY_EXTERN_C nicy_Number  NICY_CAPI nicy_luaL_optnumber(nicy_State *L, int narg, nicy_Number d);

/* ================================================================
 * 14. lauxlib β€” errors, traceback, refs
 * ================================================================ */

NICY_EXTERN_C int  NICY_CAPI nicy_luaL_error(nicy_State *L, const char *msg);
NICY_EXTERN_C int  NICY_CAPI nicy_luaL_argerror(nicy_State *L, int narg, const char *extramsg);
NICY_EXTERN_C void NICY_CAPI nicy_luaL_where(nicy_State *L, int lvl);
NICY_EXTERN_C void NICY_CAPI nicy_luaL_traceback(nicy_State *L, nicy_State *L1, const char *msg, int level);

NICY_EXTERN_C int  NICY_CAPI nicy_luaL_ref(nicy_State *L, int t);
NICY_EXTERN_C void NICY_CAPI nicy_luaL_unref(nicy_State *L, int t, int ref);

/* ================================================================
 * 15. lauxlib β€” metatables and length
 * ================================================================ */

NICY_EXTERN_C nicy_Integer NICY_CAPI nicy_luaL_len(nicy_State *L, int idx);
NICY_EXTERN_C int  NICY_CAPI nicy_luaL_newmetatable(nicy_State *L, const char *tname);
NICY_EXTERN_C int  NICY_CAPI nicy_luaL_getmetatable(nicy_State *L, const char *tname);

/* ================================================================
 * 16. Convenience macros
 * ================================================================ */

/**
 * nicy_lua_isnoneornil β€” True if index is invalid or value is nil.
 */
#define nicy_lua_isnoneornil(L, n) \
    (nicy_lua_type(L, (n)) <= 0)

/**
 * nicy_lua_pop β€” Pop n values from the stack.
 */
#define nicy_lua_pop(L, n)  nicy_lua_settop((L), -(n) - 1)

/* ================================================================
 * 17. Error code helpers
 * ================================================================ */

/**
 * nicy_error_name β€” Convert an error code number to its human-readable name.
 *
 * @param code  Error code (e.g. 103 for NICY_ERR_CYCLIC_REQUIRE).
 * @return  Static string such as "NICY_ERR_CYCLIC_REQUIRE".  Do not free.
 */
NICY_EXTERN_C const char * NICY_CAPI nicy_error_name(int code);

/**
 * nicy_is_nicy_error β€” Check if an error code is Nicy-specific (100+ range).
 *
 * @return  1 if Nicy-specific, 0 if standard Luau code.
 */
NICY_EXTERN_C int NICY_CAPI nicy_is_nicy_error(int code);

/* ================================================================
 * Notes for embedders
 * ================================================================
 *
 * 1. Thread safety
 *    Each Lua state is NOT thread-safe.  One state must be accessed
 *    from a single thread at a time.  nicy_start(), nicy_eval(), and
 *    nicy_compile() each create and destroy their own state internally
 *    so they are safe to call from any thread.
 *
 * 2. Calling convention
 *    On Windows the functions use __cdecl.  On other platforms this
 *    macro expands to nothing (default ABI).
 *
 * 3. Linking
 *    - Windows: link against nicyruntime.lib (import lib) or
 *               LoadLibrary("nicyruntime.dll") + GetProcAddress.
 *    - macOS:   link against libnicyruntime.dylib  (-lnicyruntime)
 *    - Linux:   link against libnicyruntime.so     (-lnicyruntime)
 *
 * 4. Lifetime of returned strings
 *    nicy_version() and nicy_luau_version() return pointers to
 *    statically allocated, NUL-terminated strings.  Do NOT free them.
 *
 * 5. Compiler directives in source code
 *    When loading source files (not bytecode), the following first-line
 *    directives are recognised:
 *      --!native              Enable JIT/CodeGen for this file
 *      --!optimize 0|1|2      Set optimisation level (default 1)
 *    Directives are stripped before compilation.
 *
 * 6. Bytecode files
 *    Files with the .luauc extension are loaded as pre-compiled
 *    bytecode and executed directly.  CodeGen is applied automatically
 *    when supported by the platform.
 *
 */

#endif /* NICY_RUNTIME_H */