### Compile and Run C Example Source: https://github.com/luau-lang/luau/blob/master/extern/isocline/readme.md Compile the example using GCC, linking the isocline library, and then run the executable. ```bash $ gcc -o example -Iinclude test/example.c src/isocline.c $ ./example ``` -------------------------------- ### Compile and Run Haskell Example Source: https://github.com/luau-lang/luau/blob/master/extern/isocline/readme.md Compile the Haskell example using GHC, linking the isocline C source, and then run the executable. ```bash $ ghc -ihaskell test/Example.hs src/isocline.c $ ./test/Example ``` -------------------------------- ### Native Code Generation Setup Source: https://context7.com/luau-lang/luau/llms.txt Demonstrates how to initialize native code generation for a Luau VM, either with a VM-specific context or a shared context across multiple VMs. It also shows how to compile Luau source code with native compilation hints and then compile the loaded bytecode into machine code. ```APIDOC ## Native Code Generation — `Luau::CodeGen::create` / `compile` Enable JIT-style native code generation for a Luau VM. Functions annotated with `--!native` (or all functions when `typeInfoLevel=1`) are compiled to machine code at load time. ```cpp #include "lua.h" #include "lualib.h" #include "luacode.h" #include "Luau/CodeGen.h" void setupNativeCodegen() { if (!Luau::CodeGen::isSupported()) { printf("native codegen not supported on this platform\n"); return; } lua_State* L = luaL_newstate(); luaL_openlibs(L); // Initialize native codegen on this VM (VM-private context) Luau::CodeGen::create(L); // -- OR -- use a shared context across multiple VMs auto sharedCtx = Luau::CodeGen::createSharedCodeGenContext(); lua_State* L2 = luaL_newstate(); Luau::CodeGen::create(L2, sharedCtx.get()); // Compile source with native hints luau_CompileOptions compileOpts = {}; compileOpts.optimizationLevel = 2; // required for effective native compilation compileOpts.typeInfoLevel = 1; // emit type info for all modules const char* source = "--!native\nlocal function fib(n: number): number\n" " if n < 2 then return n end\n" " return fib(n-1) + fib(n-2)\nend\nreturn fib"; size_t bcSize = 0; char* bc = luau_compile(source, strlen(source), &compileOpts, &bcSize); luau_load(L, "fib", bc, bcSize, 0); free(bc); // Compile the loaded function to native code Luau::CodeGen::CompilationStats stats{}; Luau::CodeGen::CompilationResult result = Luau::CodeGen::compile(L, -1, Luau::CodeGen::CompilationOptions{}, &stats); if (!result.hasErrors()) { printf("native: %zu bytecode bytes -> %zu native bytes\n", stats.bytecodeSizeBytes, stats.nativeCodeSizeBytes); printf("functions compiled: %u / %u\n", stats.functionsCompiled, stats.functionsTotal); } lua_close(L); lua_close(L2); } ``` ``` -------------------------------- ### Get User Input with Isocline Source: https://github.com/luau-lang/luau/blob/master/extern/isocline/readme.md Call `ic_readline` to obtain user input with rich editing capabilities. It returns NULL on errors or when Ctrl+D/Ctrl+C is pressed. ```c char* input; while( (input = ic_readline("prompt")) != NULL ) { // ctrl+d/c or errors return NULL printf("you typed:\n%s\n", input); // use the input free(input); } ``` -------------------------------- ### Setup Native Code Generation with Luau::CodeGen::create Source: https://context7.com/luau-lang/luau/llms.txt Initializes native code generation for a Luau VM, either with a VM-private context or a shared context across multiple VMs. Functions annotated with `--!native` or all functions when `typeInfoLevel=1` are compiled to machine code at load time. Requires `optimizationLevel=2` and `typeInfoLevel=1` for effective native compilation. ```cpp #include "lua.h" #include "lualib.h" #include "luacode.h" #include "Luau/CodeGen.h" void setupNativeCodegen() { if (!Luau::CodeGen::isSupported()) { printf("native codegen not supported on this platform\n"); return; } lua_State* L = luaL_newstate(); luaL_openlibs(L); // Initialize native codegen on this VM (VM-private context) Luau::CodeGen::create(L); // -- OR -- use a shared context across multiple VMs auto sharedCtx = Luau::CodeGen::createSharedCodeGenContext(); lua_State* L2 = luaL_newstate(); Luau::CodeGen::create(L2, sharedCtx.get()); // Compile source with native hints luau_CompileOptions compileOpts = {}; compileOpts.optimizationLevel = 2; // required for effective native compilation compileOpts.typeInfoLevel = 1; // emit type info for all modules const char* source = "--!native\nlocal function fib(n: number): number\n" " if n < 2 then return n end\n" " return fib(n-1) + fib(n-2)\nend\nreturn fib"; size_t bcSize = 0; char* bc = luau_compile(source, strlen(source), &compileOpts, &bcSize); luau_load(L, "fib", bc, bcSize, 0); free(bc); // Compile the loaded function to native code Luau::CodeGen::CompilationStats stats{}; Luau::CodeGen::CompilationResult result = Luau::CodeGen::compile(L, -1, Luau::CodeGen::CompilationOptions{}, &stats); if (!result.hasErrors()) { printf("native: %zu bytecode bytes -> %zu native bytes\n", stats.bytecodeSizeBytes, stats.nativeCodeSizeBytes); printf("functions compiled: %u / %u\n", stats.functionsCompiled, stats.functionsTotal); } lua_close(L); lua_close(L2); } ``` -------------------------------- ### Get Autocomplete Suggestions with Luau::autocomplete Source: https://context7.com/luau-lang/luau/llms.txt Retrieves a map of completion candidates for a given cursor position within a type-checked module. This function requires a pre-initialized Frontend and a string completion callback. ```cpp #include "Luau/Autocomplete.h" #include "Luau/Frontend.h" void getCompletions(Luau::Frontend& frontend, const std::string& moduleName, int line, int col) { // String completion callback: invoked for string literal contexts Luau::StringCompletionCallback strCb = [](std::string tag, std::optional ctx, std::optional contents) -> std::optional { return std::nullopt; // no custom string completions }; Luau::Position pos{(unsigned)line, (unsigned)col}; Luau::AutocompleteResult result = Luau::autocomplete(frontend, moduleName, pos, strCb); printf("context: %d\n", (int)result.context); for (const auto& [name, entry] : result.entryMap) { const char* kind = ""; switch (entry.kind) { case Luau::AutocompleteEntryKind::Property: kind = "prop"; break; case Luau::AutocompleteEntryKind::Binding: kind = "bind"; break; case Luau::AutocompleteEntryKind::Keyword: kind = "kw"; break; default: kind = "other"; break; } printf(" [%s] %s%s\n", kind, name.c_str(), entry.deprecated ? " (deprecated)" : ""); } } ``` -------------------------------- ### Initialize and Typecheck Module with Luau::Frontend Source: https://context7.com/luau-lang/luau/llms.txt Demonstrates setting up an in-memory file resolver, a null configuration resolver, and the Luau Frontend to typecheck a single module. Use this for initial type checking of a module. ```cpp #include "Luau/Frontend.h" #include "Luau/FileResolver.h" // Minimal in-memory file resolver struct MemFileResolver : Luau::FileResolver { std::unordered_map files; std::optional readSource(const Luau::ModuleName& name) override { auto it = files.find(name); if (it == files.end()) return std::nullopt; return Luau::SourceCode{it->second, Luau::SourceCode::Module}; } }; struct NullConfigResolver : Luau::ConfigResolver { const Luau::Config& getConfig(const Luau::ModuleName&) const override { static Luau::Config cfg; return cfg; } }; void typecheckModule() { MemFileResolver fileResolver; fileResolver.files["game/combat.luau"] = R"( --!strict local function damage(target: string, amount: number): number return amount end local result = damage("enemy", 10) )"; NullConfigResolver configResolver; Luau::FrontendOptions opts; opts.retainFullTypeGraphs = true; Luau::Frontend frontend(&fileResolver, &configResolver, opts); Luau::CheckResult result = frontend.check("game/combat.luau"); for (const auto& err : result.errors) { printf("type error at %d:%d — %s\n", err.location.begin.line + 1, err.location.begin.column + 1, Luau::toString(err).c_str()); } printf("type errors: %zu\n", result.errors.size()); // expects 0 } ``` -------------------------------- ### Stack Manipulation — Push / Get / Type Checking Source: https://context7.com/luau-lang/luau/llms.txt Luau uses a register-based stack for communication between C and Lua. This section covers functions for manipulating the stack, retrieving values, and checking types. ```APIDOC ## Stack Manipulation — Push / Get / Type Checking ### Description Luau uses a register-based stack for communication between C and Lua. Positive indices count from the bottom of the current frame; negative from the top. ### C Code Example ```cpp #include "lua.h" #include "lualib.h" // Example C function exposed to Luau: add(a: number, b: number): number static int l_add(lua_State* L) { luaL_checktype(L, 1, LUA_TNUMBER); // raises error if wrong type luaL_checktype(L, 2, LUA_TNUMBER); double a = lua_tonumber(L, 1); double b = lua_tonumber(L, 2); lua_pushnumber(L, a + b); // push result return 1; // number of return values } // Example: build a Lua table from C and call a Luau function with it void buildTableAndCall(lua_State* L) { lua_createtable(L, 0, 3); // {} with 3 hash slots hint lua_pushstring(L, "Alice"); lua_setfield(L, -2, "name"); // t.name = "Alice" lua_pushnumber(L, 30); lua_setfield(L, -2, "age"); // t.age = 30 lua_pushboolean(L, 1); lua_setfield(L, -2, "active"); // t.active = true lua_setreadonly(L, -1, 1); // make table read-only (Luau extension) // Register a C function globally lua_pushcfunction(L, l_add, "add"); lua_setglobal(L, "add"); // Inspect type of something on the stack lua_getglobal(L, "someValue"); if (lua_type(L, -1) == LUA_TSTRING) { printf("got string: %s\n", lua_tostring(L, -1)); } lua_pop(L, 1); } ``` ``` -------------------------------- ### Run a Coroutine with `lua_resume` and `lua_yield` Source: https://context7.com/luau-lang/luau/llms.txt Demonstrates how to create, resume, and yield Luau coroutines. Ensure the coroutine function is pushed onto the new thread's stack before resuming. ```cpp #include "lua.h" #include "lualib.h" static int l_produce(lua_State* L) { for (int i = 1; i <= 3; i++) { lua_pushnumber(L, i); // value to yield lua_yield(L, 1); // suspend, pass 1 value to resumer } return 0; } void runCoroutine(lua_State* L) { lua_State* co = lua_newthread(L); // new coroutine thread int coRef = lua_ref(L, -1); // pin it against GC lua_pop(L, 1); lua_pushcfunction(co, l_produce, "produce"); // Resume with 0 args (first resume starts the function) int status; while ((status = lua_resume(co, L, 0)) == LUA_YIELD) { // Each yield delivers values on co's stack printf("yielded: %.0f\n", lua_tonumber(co, -1)); lua_pop(co, lua_gettop(co)); // consume yielded values } if (status != LUA_OK) { fprintf(stderr, "coroutine error: %s\n", lua_tostring(co, -1)); } lua_unref(L, coRef); } ``` -------------------------------- ### Create and Destroy Luau VM State Source: https://context7.com/luau-lang/luau/llms.txt Use `lua_newstate` with a custom allocator or `luaL_newstate` for the default. Remember to open standard libraries and sandbox the environment. `lua_close` destroys the state and all its threads. ```cpp #include "lua.h" #include "lualib.h" #include "luacode.h" // Custom allocator (optional) static void* luaAlloc(void* ud, void* ptr, size_t osize, size_t nsize) { (void)ud; (void)osize; if (nsize == 0) { free(ptr); return nullptr; } return realloc(ptr, nsize); } int main() { // Create VM with custom allocator lua_State* L = lua_newstate(luaAlloc, nullptr); // -- or simply -- // lua_State* L = luaL_newstate(); luaL_openlibs(L); // open all standard libraries // Sandbox: protect built-ins and isolate per-thread globals luaL_sandbox(L); // make global table read-only lua_State* T = lua_newthread(L); // create a new coroutine/thread luaL_sandboxthread(T); // give T its own sandboxed environment // ... use T for script execution ... lua_close(L); // destroys all threads + GC return 0; } ``` -------------------------------- ### Build Luau Binaries with Make Source: https://github.com/luau-lang/luau/blob/master/README.md On Linux and macOS, you can use 'make' to build the Luau and Luau-Analyze targets. ```sh make config=release luau luau-analyze ``` -------------------------------- ### Build Isocline with CMake Source: https://github.com/luau-lang/luau/blob/master/extern/isocline/readme.md Clone the repository and use CMake to build a static library. This process includes creating a build directory and running CMake commands. ```bash $ git clone https://github.com/daanx/isocline $ cd isocline $ mkdir -p build/release $ cd build/release $ cmake ../.. $ cmake --build . ``` -------------------------------- ### Define and Use Custom Style Source: https://github.com/luau-lang/luau/blob/master/extern/isocline/readme.md Define a new style using `ic_style_def` and then use it with `ic_println`. ```c ic_style_def("warning", "crimson u"); ``` ```c ic_println( "[warning]this is a warning![/] ``` -------------------------------- ### Build Luau Binaries with CMake Source: https://github.com/luau-lang/luau/blob/master/README.md Use these CMake commands to build Luau's REPL and analysis CLIs from source. Ensure you are in a 'cmake' directory within your project. ```sh mkdir cmake && cd cmake cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo cmake --build . --target Luau.Repl.CLI --config RelWithDebInfo cmake --build . --target Luau.Analyze.CLI --config RelWithDebInfo ``` -------------------------------- ### Manually Build Luau Bytecode with BytecodeBuilder Source: https://context7.com/luau-lang/luau/llms.txt Demonstrates direct usage of Luau::BytecodeBuilder to construct bytecode programmatically. This is useful for custom code generators or bytecode transformation passes. No encoder is used, resulting in an identity transformation. ```cpp // Direct BytecodeBuilder usage (for custom code generators) void buildBytecodeManually() { Luau::BytecodeBuilder bb; // no encoder = identity uint32_t fid = bb.beginFunction(0, false); // 0 params, not vararg bb.emitABC(LOP_LOADN, 0, 42, 0); // R(0) = 42 bb.emitABC(LOP_RETURN, 0, 2, 0); // return R(0) (1 value: count+1=2) bb.endFunction(/*maxstack=*/1, /*upvalues=*/0); bb.setMainFunction(fid); bb.finalize(); const std::string& bytecode = bb.getBytecode(); printf("hand-built bytecode: %zu bytes\n", bytecode.size()); } ``` -------------------------------- ### Compile and Test Color Functionality Source: https://github.com/luau-lang/luau/blob/master/extern/isocline/readme.md Compile the `test_colors.c` program using `gcc` and run it to test different color modes. ```bash gcc -o test_colors -Iinclude test/test_colors.c src/isocline.c ./test_colors COLORTERM=truecolor ./test_colors COLORTERM=16color ./test_colors ``` -------------------------------- ### Load Type Definition Files Source: https://context7.com/luau-lang/luau/llms.txt Explains how to register external type definition files (`.d.luau`) to describe library APIs within a named environment scope using `frontend.loadDefinitionFile`. ```APIDOC ## Load Type Definition Files — `frontend.loadDefinitionFile` Register external type definition files (`.d.luau`) to describe library APIs, such as Roblox's built-in types. Definitions are loaded into a named environment scope. ```cpp #include "Luau/Frontend.h" void loadTypeDefs(Luau::Frontend& frontend) { // Minimal definition for a hypothetical "MyLib" library std::string_view typeDefs = R"( declare class MyLib function add(a: number, b: number): number Count: number end )"; Luau::ScopePtr envScope = frontend.addEnvironment("myEnv"); Luau::LoadDefinitionFileResult res = frontend.loadDefinitionFile( frontend.globals, // target GlobalTypes envScope, // target scope typeDefs, // definition source "@mylib", // package name (shown in errors) false, // captureComments false // typeCheckForAutocomplete ); if (!res.success) { for (const auto& err : res.parseResult.errors) { printf("def parse error: %s\n", err.getMessage().c_str()); } } else { printf("definition loaded successfully\n"); // Now modules checked with "myEnv" environment will know about MyLib } } ``` ``` -------------------------------- ### VM State Management Source: https://context7.com/luau-lang/luau/llms.txt Create and destroy a Luau VM state. `lua_newstate` takes a custom allocator; `luaL_newstate` uses the default system allocator. Every VM is independent; threads are created from an existing state with `lua_newthread`. ```APIDOC ## VM State Management — `lua_newstate` / `luaL_newstate` / `lua_close` ### Description Create and destroy a Luau VM state. `lua_newstate` takes a custom allocator; `luaL_newstate` uses the default system allocator. Every VM is independent; threads are created from an existing state with `lua_newthread`. ### Method C API / C++ API ### Example Usage ```cpp #include "lua.h" #include "lualib.h" #include "luacode.h" // Custom allocator (optional) static void* luaAlloc(void* ud, void* ptr, size_t osize, size_t nsize) { (void)ud; (void)osize; if (nsize == 0) { free(ptr); return nullptr; } return realloc(ptr, nsize); } int main() { // Create VM with custom allocator lua_State* L = lua_newstate(luaAlloc, nullptr); // -- or simply -- // lua_State* L = luaL_newstate(); luaL_openlibs(L); // open all standard libraries // Sandbox: protect built-ins and isolate per-thread globals luaL_sandbox(L); // make global table read-only lua_State* T = lua_newthread(L); // create a new coroutine/thread luaL_sandboxthread(T); // give T its own sandboxed environment // ... use T for script execution ... lua_close(L); // destroys all threads + GC return 0; } ``` ``` -------------------------------- ### Load Bytecode into VM Source: https://context7.com/luau-lang/luau/llms.txt Use `luau_load` to deserialize a bytecode blob and push the chunk function onto the stack. It returns `LUA_OK` on success and can surface compilation errors directly. ```c #include "lua.h" #include "luacode.h" // Returns 0 on success, non-zero on error (message on stack) int loadBytecode(lua_State* L, const char* chunkname, const char* bytecode, size_t size) { int result = luau_load(L, chunkname, bytecode, size, 0); if (result != LUA_OK) { // Error string is on top of stack fprintf(stderr, "luau_load error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } return result; // 0 = success, chunk function pushed on stack } // Typical compile + load + call pattern void executeSource(lua_State* L, const char* source) { size_t bcSize = 0; char* bc = luau_compile(source, strlen(source), nullptr, &bcSize); if (luau_load(L, "=source", bc, bcSize, 0) == LUA_OK) { lua_pcall(L, 0, 0, 0); } free(bc); } ``` -------------------------------- ### Callbacks Source: https://context7.com/luau-lang/luau/llms.txt Set up hooks for interrupt, panic, thread lifecycle, and other events using `lua_Callbacks`. ```APIDOC ## Callbacks — `lua_callbacks` The `lua_Callbacks` struct provides hooks for interrupt, panic, thread lifecycle, atom assignment, and debugger events. All callbacks (except `interrupt`) must be set before the VM runs any code. ```cpp #include "lua.h" static void onInterrupt(lua_State* L, int gc) { // Called at every safepoint (loop back-edges, calls, GC assists) // Use to implement script timeouts or cooperative scheduling if (gc == 0) { // Not a GC step — check time budget // if (timeExpired()) lua_error(L); // throw a timeout error } } static void onUserThread(lua_State* LP, lua_State* L) { if (LP) printf("thread created (parent=%p)\n", (void*)LP); else printf("thread destroyed\n"); } void setupCallbacks(lua_State* L) { lua_Callbacks* cb = lua_callbacks(L); cb->interrupt = onInterrupt; // safe to set from any thread cb->userthread = onUserThread; // must be set before threads are created } ``` ``` -------------------------------- ### Set Up Callbacks with `lua_callbacks` Source: https://context7.com/luau-lang/luau/llms.txt Configure hooks for VM events like interrupts and thread lifecycles. The `interrupt` callback can be set from any thread, but `userthread` must be set before threads are created. ```cpp #include "lua.h" static void onInterrupt(lua_State* L, int gc) { // Called at every safepoint (loop back-edges, calls, GC assists) // Use to implement script timeouts or cooperative scheduling if (gc == 0) { // Not a GC step — check time budget // if (timeExpired()) lua_error(L); // throw a timeout error } } static void onUserThread(lua_State* LP, lua_State* L) { if (LP) printf("thread created (parent=%p)\n", (void*)LP); else printf("thread destroyed\n"); } void setupCallbacks(lua_State* L) { lua_Callbacks* cb = lua_callbacks(L); cb->interrupt = onInterrupt; // safe to set from any thread cb->userthread = onUserThread; // must be set before threads are created } ``` -------------------------------- ### Load Type Definition Files with frontend.loadDefinitionFile Source: https://context7.com/luau-lang/luau/llms.txt Registers external type definition files (`.d.luau`) into a named environment scope to describe library APIs. This allows modules checked with the specified environment to understand the defined types. Ensure the `Luau::Frontend` object is properly initialized before use. ```cpp #include "Luau/Frontend.h" void loadTypeDefs(Luau::Frontend& frontend) { // Minimal definition for a hypothetical "MyLib" library std::string_view typeDefs = R"( declare class MyLib function add(a: number, b: number): number Count: number end )"; Luau::ScopePtr envScope = frontend.addEnvironment("myEnv"); Luau::LoadDefinitionFileResult res = frontend.loadDefinitionFile( frontend.globals, // target GlobalTypes envScope, // target scope typeDefs, // definition source "@mylib", // package name (shown in errors) false, // captureComments false // typeCheckForAutocomplete ); if (!res.success) { for (const auto& err : res.parseResult.errors) { printf("def parse error: %s\n", err.getMessage().c_str()); } } else { printf("definition loaded successfully\n"); // Now modules checked with "myEnv" environment will know about MyLib } } ``` -------------------------------- ### Fragment Autocomplete with Luau::tryFragmentAutocomplete Source: https://context7.com/luau-lang/luau/llms.txt Provides low-latency autocomplete by re-typechecking only the changed fragment around the cursor. Falls back to full autocomplete if fragment check fails. Requires Luau/FragmentAutocomplete.h and Luau/Frontend.h. ```cpp #include "Luau/FragmentAutocomplete.h" #include "Luau/Frontend.h" void fragmentComplete(Luau::Frontend& frontend, const std::string& moduleName, const std::string& newSrc, Luau::Position cursorPos) { // Parse the full updated source first (cheap) Luau::Allocator alloc; Luau::AstNameTable names(alloc); Luau::ParseOptions pOpts; pOpts.captureComments = true; Luau::ParseResult freshParse = Luau::Parser::parse(newSrc.c_str(), newSrc.size(), names, alloc, pOpts); Luau::FragmentContext ctx{ newSrc, freshParse, std::nullopt, // FrontendOptions override std::nullopt, // deprecated fragment end position nullptr // reporter }; Luau::StringCompletionCallback strCb = [](auto, auto, auto) -> std::optional { return std::nullopt; }; auto result = Luau::tryFragmentAutocomplete( frontend, moduleName, cursorPos, ctx, strCb ); if (result.status == Luau::FragmentAutocompleteStatus::Success && result.result) { printf("fragment completions: %zu\n", result.result->acResults.entryMap.size()); } else { // Fragment check failed — fall back to full autocomplete auto full = Luau::autocomplete(frontend, moduleName, cursorPos, strCb); printf("full completions: %zu\n", full.entryMap.size()); } } ``` -------------------------------- ### Linting Source Code with Luau::lint Source: https://context7.com/luau-lang/luau/llms.txt Runs the built-in linter on a parsed AST with an optional type-checked module, returning categorized warnings and errors. Requires Luau/Linter.h, Luau/LinterConfig.h, Luau/Parser.h, and Luau/Frontend.h. Use lintOpts to enable/disable specific checks. ```cpp #include "Luau/Linter.h" #include "Luau/LinterConfig.h" #include "Luau/Parser.h" #include "Luau/Frontend.h" void lintSource(Luau::Frontend& frontend, const std::string& moduleName) { Luau::LintOptions lintOpts; lintOpts.setDefaults(); // Enable specific checks lintOpts.enableWarning(Luau::LintWarning::Code_LocalUnused); lintOpts.enableWarning(Luau::LintWarning::Code_UnreachableCode); lintOpts.enableWarning(Luau::LintWarning::Code_DuplicateLocal); lintOpts.disableWarning(Luau::LintWarning::Code_LocalShadow); Luau::FrontendOptions opts; opts.runLintChecks = true; opts.enabledLintWarnings = lintOpts; Luau::CheckResult result = frontend.check(moduleName, opts); for (const auto& w : result.lintResult.warnings) { printf("warn [%s] at %d:%d — %s\n", Luau::LintWarning::getName(w.code), w.location.begin.line + 1, w.location.begin.column + 1, w.text.c_str()); } for (const auto& e : result.lintResult.errors) { printf("error [%s] at %d:%d — %s\n", Luau::LintWarning::getName(e.code), e.location.begin.line + 1, e.location.begin.column + 1, e.text.c_str()); } } ``` -------------------------------- ### Parsing Source: https://context7.com/luau-lang/luau/llms.txt Convert source text into an Abstract Syntax Tree (AST) using `Luau::Parser::parse`. ```APIDOC ## Parsing — `Luau::Parser::parse` Convert source text into an AST. The result includes the root `AstStatBlock*`, parse errors (non-fatal; partial AST is still produced), hot-comments, and comment locations. ```cpp #include "Luau/Parser.h" #include "Luau/Allocator.h" #include "Luau/ParseResult.h" void parseSource(const std::string& source) { Luau::Allocator allocator; Luau::AstNameTable names(allocator); Luau::ParseOptions opts; opts.captureComments = true; // include comment locations in result opts.storeCstData = false; // CST not needed for analysis Luau::ParseResult result = Luau::Parser::parse( source.c_str(), source.size(), names, allocator, opts ); if (!result.errors.empty()) { for (const auto& err : result.errors) { auto loc = err.getLocation(); printf("parse error at %d:%d — %s\n", loc.begin.line + 1, loc.begin.column + 1, err.getMessage().c_str()); } // Partial AST is still present in result.root } // Traverse the AST // result.root is an AstStatBlock* (the top-level block) printf("parsed %zu lines, %zu hot-comments\n", result.lines, result.hotcomments.size()); } ``` ``` -------------------------------- ### Parse Source Code to AST with `Luau::Parser::parse` Source: https://context7.com/luau-lang/luau/llms.txt Convert source text into an Abstract Syntax Tree (AST). Configure parse options to capture comments or disable CST data. Errors are reported but a partial AST is still produced. ```cpp #include "Luau/Parser.h" #include "Luau/Allocator.h" #include "Luau/ParseResult.h" void parseSource(const std::string& source) { Luau::Allocator allocator; Luau::AstNameTable names(allocator); Luau::ParseOptions opts; opts.captureComments = true; // include comment locations in result opts.storeCstData = false; // CST not needed for analysis Luau::ParseResult result = Luau::Parser::parse( source.c_str(), source.size(), names, allocator, opts ); if (!result.errors.empty()) { for (const auto& err : result.errors) { auto loc = err.getLocation(); printf("parse error at %d:%d — %s\n", loc.begin.line + 1, loc.begin.column + 1, err.getMessage().c_str()); } // Partial AST is still present in result.root } // Traverse the AST // result.root is an AstStatBlock* (the top-level block) printf("parsed %zu lines, %zu hot-comments\n", result.lines, result.hotcomments.size()); } ``` -------------------------------- ### Configure Luau CLI Targets Source: https://github.com/luau-lang/luau/blob/master/CMakeLists.txt Sets compile options, include directories, and link libraries for various Luau CLI targets when LUAU_BUILD_CLI is enabled. This includes setting C++17 standard for Luau.Reduce.CLI. ```cmake target_compile_options(Luau.Repl.CLI PRIVATE ${LUAU_OPTIONS}) target_compile_options(Luau.Reduce.CLI PRIVATE ${LUAU_OPTIONS}) target_compile_options(Luau.Analyze.CLI PRIVATE ${LUAU_OPTIONS}) target_compile_options(Luau.Ast.CLI PRIVATE ${LUAU_OPTIONS}) target_compile_options(Luau.Compile.CLI PRIVATE ${LUAU_OPTIONS}) target_compile_options(Luau.Bytecode.CLI PRIVATE ${LUAU_OPTIONS}) ``` ```cmake target_include_directories(Luau.Repl.CLI PRIVATE extern extern/isocline/include) ``` ```cmake target_link_libraries(Luau.Repl.CLI PRIVATE Luau.Compiler Luau.Config Luau.CodeGen Luau.VM Luau.Require Luau.CLI.lib isocline) ``` ```cmake target_link_libraries(Luau.Repl.CLI PRIVATE osthreads) target_link_libraries(Luau.Reduce.CLI PRIVATE osthreads) target_link_libraries(Luau.Analyze.CLI PRIVATE osthreads) target_link_libraries(Luau.Ast.CLI PRIVATE osthreads) target_link_libraries(Luau.Compile.CLI PRIVATE osthreads) target_link_libraries(Luau.Bytecode.CLI PRIVATE osthreads) ``` ```cmake target_link_libraries(Luau.Analyze.CLI PRIVATE Luau.Analysis Luau.CLI.lib Luau.Require) ``` ```cmake target_link_libraries(Luau.Ast.CLI PRIVATE Luau.Ast Luau.Analysis Luau.CLI.lib) ``` ```cmake target_compile_features(Luau.Reduce.CLI PRIVATE cxx_std_17) target_include_directories(Luau.Reduce.CLI PUBLIC Reduce/include) target_link_libraries(Luau.Reduce.CLI PRIVATE Luau.Common Luau.Ast Luau.Analysis Luau.CLI.lib) ``` ```cmake target_link_libraries(Luau.Compile.CLI PRIVATE Luau.Compiler Luau.VM Luau.CodeGen Luau.CLI.lib) ``` ```cmake target_link_libraries(Luau.Bytecode.CLI PRIVATE Luau.Compiler Luau.VM Luau.CodeGen Luau.CLI.lib) ``` -------------------------------- ### Compile Luau Source to Bytecode (C++ API) Source: https://context7.com/luau-lang/luau/llms.txt The C++ API `Luau::compile` allows specifying `CompileOptions` for optimization, debugging, and coverage levels. It returns a string containing the bytecode or encoded errors. ```cpp #include "Luau/Compiler.h" #include "Luau/BytecodeBuilder.h" std::string compileToBytecode(const std::string& source) { Luau::CompileOptions opts; opts.optimizationLevel = 1; // 0=none, 1=baseline, 2=aggressive opts.debugLevel = 1; // 0=none, 1=line info, 2=full debug opts.coverageLevel = 0; // 0=none, 1=statement, 2=expression // Returns bytecode blob or encoded error return Luau::compile(source, opts); } ``` -------------------------------- ### AST Position Queries Source: https://context7.com/luau-lang/luau/llms.txt Provides methods for querying the type-annotated Abstract Syntax Tree (AST) to support tooling like hover information, go-to-definition, and find-references, using `findTypeAtPosition` and `findNodeAtPosition`. ```APIDOC ## AST Position Queries — `findTypeAtPosition` / `findNodeAtPosition` Query the type-annotated AST for hover, go-to-definition, and find-references tooling. ```cpp #include "Luau/AstQuery.h" #include "Luau/Frontend.h" #include "Luau/ToString.h" void hoverInfo(Luau::Frontend& frontend, const std::string& moduleName, unsigned line, unsigned col) { frontend.check(moduleName); const Luau::SourceModule* sm = frontend.getSourceModule(moduleName); Luau::ModulePtr mod = frontend.moduleResolver.getModule(moduleName); if (!sm || !mod) return; Luau::Position pos{line, col}; // Find the AST node under cursor Luau::AstNode* node = Luau::findNodeAtPosition(*sm, pos); if (node) { printf("AST node class id: %d\n", node->classIndex); } // Find the inferred type at cursor (for hover) auto ty = Luau::findTypeAtPosition(*mod, *sm, pos); if (ty) { printf("type: %s\n", Luau::toString(*ty).c_str()); } // Find the expected type (for signature help) auto ety = Luau::findExpectedTypeAtPosition(*mod, *sm, pos); if (ety) { printf("expected: %s\n", Luau::toString(*ety).c_str()); } // Find the binding (variable declaration) at cursor auto binding = Luau::findBindingAtPosition(*mod, *sm, pos); if (binding) { printf("binding type: %s\n", Luau::toString(binding->typeId).c_str()); } } ``` ``` -------------------------------- ### Compile Source to Bytecode Source: https://context7.com/luau-lang/luau/llms.txt Converts Luau source text into a bytecode blob. The C function `luau_compile` is the minimal entry point; the C++ `Luau::compile` exposes full `CompileOptions`. The bytecode blob can be passed directly to `luau_load`. ```APIDOC ## Compile Source to Bytecode — `luau_compile` (C API) / `Luau::compile` (C++ API) ### Description Converts Luau source text into a bytecode blob. The C function `luau_compile` is the minimal entry point; the C++ `Luau::compile` exposes full `CompileOptions`. The bytecode blob can be passed directly to `luau_load`. ### Method C API (`luau_compile`) / C++ API (`Luau::compile`) ### Parameters (C++ API `Luau::compile`) - `source` (std::string) - The Luau source code to compile. - `opts` (Luau::CompileOptions) - Compilation options. - `optimizationLevel` (int) - 0=none, 1=baseline, 2=aggressive. - `debugLevel` (int) - 0=none, 1=line info, 2=full debug. - `coverageLevel` (int) - 0=none, 1=statement, 2=expression. ### Request Example (C API) ```cpp #include "lua.h" #include "luacode.h" #include void runScript(lua_State* L, const char* source) { size_t bytecodeSize = 0; // Returns a malloc'd blob; errors are encoded inside the blob (luau_load decodes them) char* bytecode = luau_compile(source, strlen(source), nullptr, &bytecodeSize); int status = luau_load(L, "mychunk", bytecode, bytecodeSize, 0); free(bytecode); // always free, even on error if (status != LUA_OK) { fprintf(stderr, "load error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); return; } // Chunk is now a function on top of the stack; call it lua_pcall(L, 0, LUA_MULTRET, 0); } ``` ### Request Example (C++ API) ```cpp #include "Luau/Compiler.h" #include "Luau/BytecodeBuilder.h" std::string compileToBytecode(const std::string& source) { Luau::CompileOptions opts; opts.optimizationLevel = 1; // 0=none, 1=baseline, 2=aggressive opts.debugLevel = 1; // 0=none, 1=line info, 2=full debug opts.coverageLevel = 0; // 0=none, 1=statement, 2=expression // Returns bytecode blob or encoded error return Luau::compile(source, opts); } ``` ``` -------------------------------- ### Load Bytecode into VM Source: https://context7.com/luau-lang/luau/llms.txt Deserializes a bytecode blob and pushes the resulting chunk function onto the Lua stack. On success returns `LUA_OK` (0); the blob encodes compilation errors so `luau_load` can surface them without a separate compile step. ```APIDOC ## Load Bytecode into VM — `luau_load` ### Description Deserializes a bytecode blob and pushes the resulting chunk function onto the Lua stack. On success returns `LUA_OK` (0); the blob encodes compilation errors so `luau_load` can surface them without a separate compile step. ### Method C API ### Parameters - `L` (lua_State*) - The VM state. - `chunkname` (const char*) - The name of the chunk for error messages. - `bytecode` (const char*) - The bytecode blob. - `size` (size_t) - The size of the bytecode blob. - `mode` (int) - Load mode (typically 0). ### Return Value - `0` on success, non-zero on error (error message will be on the stack). ### Example Usage ```cpp #include "lua.h" #include "luacode.h" // Returns 0 on success, non-zero on error (message on stack) int loadBytecode(lua_State* L, const char* chunkname, const char* bytecode, size_t size) { int result = luau_load(L, chunkname, bytecode, size, 0); if (result != LUA_OK) { // Error string is on top of stack fprintf(stderr, "luau_load error: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } return result; // 0 = success, chunk function pushed on stack } // Typical compile + load + call pattern void executeSource(lua_State* L, const char* source) { size_t bcSize = 0; char* bc = luau_compile(source, strlen(source), nullptr, &bcSize); if (luau_load(L, "=source", bc, bcSize, 0) == LUA_OK) { lua_pcall(L, 0, 0, 0); } free(bc); } ``` ``` -------------------------------- ### Handle File Edits with frontend.markDirty and frontend.check Source: https://context7.com/luau-lang/luau/llms.txt Updates a module's source code in the file resolver, marks the module and its dependents as dirty, and then re-checks them. This is efficient for handling edits as only changed modules are reprocessed. ```cpp #include "Luau/Frontend.h" void onFileEdited(Luau::Frontend& frontend, MemFileResolver& fileResolver, const std::string& moduleName, const std::string& newSource) { // Update source fileResolver.files[moduleName] = newSource; // Invalidate the module and all its dependents std::vector markedDirty; frontend.markDirty(moduleName, &markedDirty); printf("marked %zu modules dirty\n", markedDirty.size()); // Re-check (only dirty modules are reprocessed) Luau::CheckResult result = frontend.check(moduleName); printf("errors after re-check: %zu\n", result.errors.size()); } ``` -------------------------------- ### Configure Luau Web Target Source: https://github.com/luau-lang/luau/blob/master/CMakeLists.txt Sets compile options and link libraries for the Luau web target when LUAU_BUILD_WEB is enabled. It also configures Emscripten-specific link options for exporting functions, enabling exceptions, and creating a single output file. ```cmake target_compile_options(Luau.Web PRIVATE ${LUAU_OPTIONS}) target_link_libraries(Luau.Web PRIVATE Luau.Compiler Luau.VM Luau.Analysis) ``` ```cmake target_link_options(Luau.Web PRIVATE -sEXPORTED_FUNCTIONS=["_executeScript","_checkScript"] -sEXPORTED_RUNTIME_METHODS=["ccall","cwrap"]) ``` ```cmake target_link_options(Luau.Web PRIVATE -fexceptions) ``` ```cmake target_link_options(Luau.Web PRIVATE -sSINGLE_FILE=1) ```