Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - corepunch/zilscript: ZIL language implementation (both compiler and runtime in one) · GitHub
Skip to content

Repository files navigation

63a454c1-f42a-4a1b-889c-1933c12541af

A Lua-based compiler and runtime for the Zork Implementation Language (ZIL).

Overview

This project provides a runtime environment for executing ZIL programs, including the classic Zork adventure games.

For a repo-level system summary, see ARCHITECTURE.md. Agent-specific guidance lives in AGENTS.md.

For the proposed state-aware action-card layer used by parser-free and illustrated play, see Companion ZIL Files. To add that layer to an adventure, follow Generating companion.zil or invoke the repository's @companion-author agent.

A released companion must author and validate every reachable room and material state family, and must complete the game in companion mode using numbered choices only. Automatic suggestions keep unfinished areas operable but do not count as complete authored coverage.

Features

  • ZIL to Lua Compilation: Compiles ZIL source code to Lua for execution
  • Require System: Load .zil files using Lua's require() function, just like moonscript
  • Source Mapping: Error messages automatically reference ZIL source files instead of generated Lua files (see SOURCE_MAPPING.md)
  • Interactive Gameplay: Full support for classic text adventure games
  • Comprehensive Testing: Unit and integration tests for all components

Requirements

  • Lua 5.4 or compatible version

Running the Game

The default interface presents numbered, state-aware companion choices:

lua5.4 main.lua

Companion mode shows every eligible grouped choice. Select one by number or type any parser command:

lua5.4 main.lua --companion

Use the original free-text parser interface with:

lua5.4 main.lua --text

Run lua5.4 main.lua --help for story-module and choice-count options. Games without an authored companion.zil use conservative visible-object and direct-exit suggestions.

Testing

The project includes comprehensive testing at multiple levels: unit tests (134+), integration tests, game walkthroughs, and pure ZIL tests.

Quick Start

make test# Run all tests (unit + integration)
make test-unit # Run unit tests only
make test-integration # Run integration tests only
make test-pure-zil # Run pure ZIL tests (new!)

Test Categories

  • Unit Tests: Parser (60 tests), Compiler (44 tests), Runtime (25 tests), Source Mapping (5 tests)
  • Integration Tests: Zork1 game tests, parser/runtime tests, horror game tests
  • Parser/Runtime Tests: Directions, containers, light, take, pronouns
  • Pure ZIL Tests: Self-contained tests written entirely in ZIL using ASSERT function

Writing Pure ZIL Tests (New!)

You can now write tests entirely in ZIL without Lua wrappers:

<ROUTINETEST-MY-FEATURE ()
<TELL"Testing..." CR>
<ASSERT T"This passes">
<ASSERT <==?55> "Numbers match">
<ASSERT <FSET?,APPLE,TAKEBIT> "Apple is takeable">
<TELL"All tests completed!" CR>>
<ROUTINEGO () <TEST-MY-FEATURE>>

Run with the generic test runner:

lua5.4 run-zil-test.lua tests.my-test

Features:

  • ASSERT checks condition and prints [PASS] or [FAIL]
  • Combine with ZIL operators: ==?, FSET?, LOC, etc.
  • Simple, minimal setup
  • Only ZIL test files needed - one generic Lua runner for all tests

For integration test documentation, see tests/TESTS.md.

Project Structure

  • main.lua - Main entry point for running the game
  • zilscript/ - ZIL runtime implementation
    • init.lua - Main module for require system (loads when you require "zilscript")
    • base.lua - Core loader functionality for .zil files
    • bootstrap.lua - Core runtime functions and globals (includes ASSERT function)
    • parser.lua - ZIL parser
    • compiler.lua - ZIL to Lua compiler
    • evaluate.lua - Expression evaluator
    • runtime.lua - Runtime loader utilities
    • sourcemap.lua - Source mapping for error messages
  • tests/ - Test framework and test files
    • run_tests.lua - Integration test runner
    • Pure ZIL test examples (test-simple-new.zil, test-insert-file.zil, etc.)
    • zork1_basic.lua - Basic integration tests
    • zork1_walkthrough.lua - Extended integration tests
    • unit/ - Unit tests directory
      • test_framework.lua - Unit testing framework
      • test_parser.lua - Parser unit tests
      • test_compiler.lua - Compiler unit tests
      • test_runtime.lua - Runtime unit tests
      • run_all.lua - Unit test runner
  • infocom/zork1/ - Zork 1 game files
  • books/blackwood-horror/ - Additional adventure files

Configuring ZIL Files

The list of ZIL files to compile is specified in main.lua:

localfiles= {
"infocom/zork1/globals.zil",
"infocom/zork1/parser.zil",
"infocom/zork1/verbs.zil",
"infocom/zork1/syntax.zil",
"books/blackwood-horror/horror.zil",
"infocom/zork1/main.zil",
}

You can modify this list to load different ZIL files or create your own adventure.

Using the Require System

The ZIL runtime now supports a require-based loading system similar to moonscript, allowing you to load .zil files using Lua's standard require() function.

Basic Usage

-- Initialize the ZIL loaderrequire"zil"-- Now you can require .zil files just like Lua modules-- This will automatically compile and load infocom/zork1/actions.zillocalactions=require"infocom.zork1.actions"

How It Works

When you require "zil":

  1. The ZIL loader is automatically installed into Lua's package system
  2. A package.zilpath is created (similar to package.path) that tells Lua where to find .zil files
  3. When you require a module, Lua will search for both .lua and .zil files
  4. If a .zil file is found, it's automatically compiled to Lua and executed
  5. The compiled module is cached by Lua's require system (no recompilation on subsequent requires)

Example

require"zil" -- Initialize the loader-- Load ZIL moduleslocaltest=require"tests.test-require" -- Loads tests/test-require.zil-- The compiled code is cachedlocaltest2=require"tests.test-require" -- Reuses cached version

For a complete example, see examples/require_example.lua.

Advanced Usage

The zil module also provides utility functions:

localzil=require"zil"-- Compile ZIL code to Lualocallua_code=zil.to_lua('<ROUTINE FOO () <RETURN 1>>')
-- Load ZIL code from a stringlocalchunk=zil.loadstring('<ROUTINE BAR () <TELL "Hello">>')
-- Load and execute a ZIL filezil.dofile("myfile.zil")
-- Manage the loaderzil.remove_loader() -- Remove the ZIL loaderzil.insert_loader() -- Re-insert the ZIL loader

Debugging: Saving Compiled Lua Files

By default, .zil files are compiled to Lua in memory only. For debugging purposes, you can enable saving of the compiled .lua files:

localzil=require"zil"-- Enable saving compiled .lua files for moduleszil.config.save_lua=true-- Now when you require a .zil module, it will save the compiled .lua filerequire"mymodule" -- Creates mymodule.zil.lua-- Disable to stop saving fileszil.config.save_lua=false

When enabled, each .zil module loaded via require() will save its compiled Lua code to a .zil.lua file in the same directory. This is useful for:

  • Debugging compilation issues
  • Understanding how ZIL code translates to Lua
  • Examining generated code for performance analysis

Note: The generated .zil.lua files are automatically excluded from git via .gitignore.

Development

Architecture

The ZIL runtime is modular and well-tested, with a compiler architecture inspired by TypeScript:

  • Parser (zilscript/parser.lua): Parses ZIL source code into AST
  • Compiler (zilscript/compiler/): Compiles ZIL AST to Lua code (12 focused modules)
    • Core modules: init, buffer, utils, value, fields, forms, toplevel, print_node
    • TypeScript-inspired modules ✨: visitor, diagnostics, emitter, checker
  • Runtime (zilscript/runtime.lua): Executes compiled Lua code
  • Bootstrap (zilscript/bootstrap.lua): Core runtime functions and globals
  • Source Mapping (zilscript/sourcemap.lua): Maps Lua errors back to ZIL source locations

See zilscript/compiler/README.md for detailed compiler module documentation.

Key Features

  • Source Mapping: Error messages reference ZIL source files, not generated Lua files (see SOURCE_MAPPING.md)
  • Modular Compiler: Clean separation of concerns across 12 focused modules
  • TypeScript-Inspired Architecture: Visitor pattern, diagnostic collection, semantic checking, and structured emission
  • Test Infrastructure: 149+ unit test assertions plus comprehensive integration tests
  • Test Assertions: Built-in test commands for verifying game state

Debugging

Generated Lua files (with zil_ prefix) are created during compilation and excluded from git via .gitignore.

License

See individual game files for their respective licenses.

About

ZIL language implementation (both compiler and runtime in one)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages