Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ jobs:
cancel-in-progress: true
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"

- uses: jkl1337/gh-actions-lua@v11
with:
Expand All @@ -58,7 +56,6 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
fetch-depth: 0
fetch-tags: true
- name: install just
Expand Down Expand Up @@ -106,7 +103,6 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
fetch-depth: 0
fetch-tags: "true"
- name: Download love package
Expand Down Expand Up @@ -152,7 +148,6 @@ jobs:

- uses: actions/checkout@v4
with:
submodules: "recursive"
fetch-depth: 0
fetch-tags: "true"
- name: Download love package
Expand Down Expand Up @@ -236,7 +231,6 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
fetch-tags: "true"
fetch-depth: 0
- name: Download love package
Expand Down
8 changes: 0 additions & 8 deletions .gitmodules

This file was deleted.

19 changes: 6 additions & 13 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
## Cloning

Clone this project recursively, because libraries are included
as submodules:
A plain clone gives you everything:

```shell
git clone --recurse-submodules
# or
git clone --recurse-submodules --shallow-submodules
git clone
```

If it's already cloned without, and you don't want to start over,
they can be initialized with:

```shell
git submodule update --init
# or
git submodule update --init --depth 1
```
The libraries under `src/lib/` are tracked files, so there is
nothing to initialize afterwards. Each carries its own `README.md`
recording where it came from and at which commit; edit those copies
here rather than upstream.

## Installing

Expand Down
1 change: 0 additions & 1 deletion src/lib/metalua
Submodule metalua deleted from d0dbd0
20 changes: 20 additions & 0 deletions src/lib/metalua/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2006-2013 Fabien Fleutot and others.
Copyright (c) 2024-2025 the Compy contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
56 changes: 56 additions & 0 deletions src/lib/metalua/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# metalua (vendored)

The part of [Metalua](https://github.com/compy-toys/metalua) the Compy editor
reads: the front end that turns Lua source into a checked AST, plus the printer
that turns an AST back into source.

## Origin

- Upstream: `https://github.com/compy-toys/metalua.git`, branch `dev`
- Imported at commit `d0dbd0d982f87512b806949ea697ea71f39cd0b4`
- That commit is `refs/pull/3/head`. PR #3 was merged into `dev` by
rebase, so `dev` carries the same five commits under different
hashes and its head `a42b3918` has an identical tree
(`5e4d41cc483fad980d742b92a1ab44cd05b93665`). The import is `dev`'s
content, reached by the hash the IDE was pinned at.
- Upstream of that fork: Eclipse Koneki Metalua 0.7.2

## What is here

`metalua-parser`'s modules, which upstream packages separately from the
bytecode compiler:

- `metalua/grammar/lexer.lua`, `metalua/grammar/generator.lua`
- `metalua/compiler/parser.lua` and `metalua/compiler/parser/*`
- `metalua/compiler.lua` — the front end `model.lang.lua.parser` instantiates
- `metalua/pprint.lua`
- `checks.lua` — argument checking, required by the front end; installs a
global `checkers` table

Plus one module from `metalua-compiler`:

- `metalua/compiler/ast_to_src.lua` — the source printer the editor uses to
render a chunk back to text

`checks.lua` and `ast_to_src.lua`'s stringutils dependency resolve through the
editor's own `src/util/string`, reached as `util.string.string`.

## What was left behind

The bytecode compiler (`metalua/compiler/bytecode*`), the metaprogramming
loader (`metalua/loader.lua`, `metalua/compiler/globals.lua`), the CLI
(`metalua.lua`), and every `.mlua` source — extensions, `repl`, `treequery`,
`dollar`. Nothing loads the Metalua loader at runtime, so no `.mlua` file is
reachable. The AST test corpus moved to `tests/interpreter/ast_inputs.lua`.

## License

Metalua is dual-licensed MIT and EPL-1.0 upstream. This copy is carried under
MIT alone; see `LICENSE`. The per-file headers keep the authors' copyright and
contributor lines and name MIT as the single grant.

## Changing this code

Edit it here. This is a vendored copy, not a submodule, and the fork it came
from already diverges from Eclipse Metalua in `grammar/lexer.lua`,
`grammar/generator.lua`, `compiler.lua`, and `compiler/ast_to_src.lua`.
52 changes: 52 additions & 0 deletions src/lib/metalua/checks.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
--------------------------------------------------------------------------------
-- Copyright (c) 2006-2013 Fabien Fleutot and others.
--
-- Made available under the terms of the MIT public license, which
-- accompanies this distribution in LICENSE and is available at
-- http://www.lua.org/license.html
--
-- Contributors:
-- Fabien Fleutot - API and implementation
--
--------------------------------------------------------------------------------

-- Alternative implementation of checks() in Lua. Slower than
-- the C counterpart, but no compilation/porting concerns.

checkers = { }

local function check_one(expected, val)
if type(val)==expected then return true end
local mt = getmetatable(val)
if mt and mt.__type==expected then return true end
local f = checkers[expected]
if f and f(val) then return true end
return false
end

local function check_many(name, expected, val)
if expected=='?' then return true
elseif expected=='!' then return (val~=nil)
elseif type(expected) ~= 'string' then
error 'strings expected by checks()'
elseif val==nil and expected :sub(1,1) == '?' then return true end
for one in expected :gmatch "[^|?]+" do
if check_one(one, val) then return true end
end
return false
end

function checks(...)
for i, arg in ipairs{...} do
local name, val = debug.getlocal(2, i)
local success = check_many(name, arg, val)
if not success then
local fname = debug.getinfo(2, 'n').name
local fmt = "bad argument #%d to '%s' (%s expected, got %s)"
local msg = string.format(fmt, i, fname or "?", arg, type(val))
error(msg, 3)
end
end
end

return checks
183 changes: 183 additions & 0 deletions src/lib/metalua/metalua/compiler.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---------------------------------------------------------------------------
-- Copyright (c) 2006-2013 Fabien Fleutot and others.
--
-- Made available under the terms of the MIT public license, which
-- accompanies this distribution in LICENSE and is available at
-- http://www.lua.org/license.html
--
-- Contributors:
-- Fabien Fleutot - API and implementation
--
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------
--
-- Convert between various code representation formats. Atomic
-- converters are written in extenso, others are composed automatically
-- by chaining the atomic ones together in a closure.
--
-- Supported formats are:
--
-- * srcfile: the name of a file containing sources.
-- * src: these sources as a single string.
-- * lexstream: a stream of lexemes.
-- * ast: an abstract syntax tree.
-- * proto: a (Yueliang) struture containing a high level
-- representation of bytecode. Largely based on the
-- Proto structure in Lua's VM
-- * bytecode: a string dump of the function, as taken by
-- loadstring() and produced by string.dump().
-- * function: an executable lua function in RAM.
--
--------------------------------------------------------------------------------

require 'checks'

local M = {}

--------------------------------------------------------------------------------
-- Order of the transformations. if 'a' is on the left of 'b', then a 'a' can
-- be transformed into a 'b' (but not the other way around).
-- M.sequence goes for numbers to format names, M.order goes from format
-- names to numbers.
--------------------------------------------------------------------------------
M.sequence = {
'srcfile', 'src', 'lexstream', 'ast', 'proto', 'bytecode', 'function' }

local arg_types = {
srcfile = { 'string', '?string' },
src = { 'string', '?string' },
lexstream = { 'lexer.stream', '?string' },
ast = { 'table', '?string' },
proto = { 'table', '?string' },
bytecode = { 'string', '?string' },
}

if false then
-- if defined, runs on every newly-generated AST
function M.check_ast(ast)
local function rec(x, n, parent)
if not x.lineinfo and parent.lineinfo then
local pp = require 'metalua.pprint'
pp.printf("WARNING: Missing lineinfo in child #%s `%s{...} of node at %s",
n, x.tag or '', tostring(parent.lineinfo))
end
for i, child in ipairs(x) do
if type(child) == 'table' then rec(child, i, x) end
end
end
rec(ast, -1, {})
end
end


M.order = {}; for a, b in pairs(M.sequence) do M.order[b] = a end

local CONV = {} -- conversion metatable __index

function CONV:srcfile_to_src(x, name)
checks('metalua.compiler', 'string', '?string')
name = name or '@' .. x
local f, msg = io.open(x, 'rb')
if not f then error(msg) end
local r, msg = f:read '*a'
if not r then error("Cannot read file '" .. x .. "': " .. msg) end
f:close()
return r, name
end

function CONV:src_to_lexstream(src, name)
checks('metalua.compiler', 'string', '?string')
local r = self.parser.lexer:newstream(src, name)
return r, name
end

function CONV:lexstream_to_ast(lx, name)
checks('metalua.compiler', 'lexer.stream', '?string')
local r = self.parser.chunk(lx)
r.source = name
if M.check_ast then M.check_ast(r) end
return r, name
end

local bytecode_compiler = nil -- cache to avoid repeated `pcall(require(...))`
local function get_bytecode_compiler()
if bytecode_compiler then
return bytecode_compiler
else
local status, result = pcall(require, 'metalua.compiler.bytecode')
if status then
bytecode_compiler = result
return result
elseif string.match(result, "not found") then
error "Compilation only available with full Metalua"
else
error(result)
end
end
end

function CONV:ast_to_proto(ast, name)
checks('metalua.compiler', 'table', '?string')
return get_bytecode_compiler().ast_to_proto(ast, name), name
end

function CONV:proto_to_bytecode(proto, name)
return get_bytecode_compiler().proto_to_bytecode(proto), name
end

function CONV:bytecode_to_function(bc, name)
checks('metalua.compiler', 'string', '?string')
return loadstring(bc, name)
end

-- Create all sensible combinations
for i = 1, #M.sequence do
local src = M.sequence[i]
for j = i + 2, #M.sequence do
local dst = M.sequence[j]
local dst_name = src .. "_to_" .. dst
local my_arg_types = arg_types[src]
local functions = {}
for k = i, j - 1 do
local name = M.sequence[k] .. "_to_" .. M.sequence[k + 1]
local f = assert(CONV[name], name)
table.insert(functions, f)
end
CONV[dst_name] = function(self, a, b)
checks('metalua.compiler', unpack(my_arg_types))
for _, f in ipairs(functions) do
a, b = f(self, a, b)
end
return a, b
end
--printf("Created M.%s out of %s", dst_name, table.concat(n, ', '))
end
end


--------------------------------------------------------------------------------
-- This one goes in the "wrong" direction, cannot be composed.
--------------------------------------------------------------------------------
function CONV:function_to_bytecode(...) return string.dump(...) end

local ast2 = require 'metalua.compiler.ast_to_src'

function CONV:a2s(...)
return ast2.new(...)
end

function CONV:ast_to_src(...)
return ast2:oneshot(...)
end

local MT = { __index = CONV, __type = 'metalua.compiler' }

function M.new()
local parser = require 'metalua.compiler.parser'.new()
local self = { parser = parser }
setmetatable(self, MT)
return self
end

return M
Loading
Loading