Compare commits
No commits in common. "main" and "9e5d32a42095427200c5260dd155a250fb739872" have entirely different histories.
main
...
9e5d32a420
|
|
@ -1,5 +1,2 @@
|
||||||
.venv/*
|
zig-cache
|
||||||
.idea/*
|
zig-out
|
||||||
*.egg-info/*
|
|
||||||
**/__pycache__/*
|
|
||||||
*.log
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "main",
|
|
||||||
"type": "python",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "/home/patrick/git/skill-ls/.venv/bin/skillls",
|
|
||||||
"python": "/home/patrick/git/skill-ls/.venv/bin/python"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"name": "main",
|
|
||||||
"type": "python",
|
|
||||||
"request": "launch",
|
|
||||||
"module": "skillls.parsing.iterative",
|
|
||||||
"python": "/home/patrick/git/skill-ls/.venv/bin/python"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// Although this function looks imperative, note that its job is to
|
||||||
|
// declaratively construct a build graph that will be executed by an external
|
||||||
|
// runner.
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
// Standard target options allows the person running `zig build` to choose
|
||||||
|
// what target to build for. Here we do not override the defaults, which
|
||||||
|
// means any target is allowed, and the default is native. Other options
|
||||||
|
// for restricting supported target set are available.
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
|
||||||
|
// Standard optimization options allow the person running `zig build` to select
|
||||||
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not
|
||||||
|
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const lib = b.addStaticLibrary(.{
|
||||||
|
.name = "skill-ls",
|
||||||
|
// In this case the main source file is merely a path, however, in more
|
||||||
|
// complicated build scripts, this could be a generated file.
|
||||||
|
.root_source_file = b.path("src/root.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
// This declares intent for the library to be installed into the standard
|
||||||
|
// location when the user invokes the "install" step (the default step when
|
||||||
|
// running `zig build`).
|
||||||
|
b.installArtifact(lib);
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "skill-ls",
|
||||||
|
.root_source_file = b.path("src/main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
// This declares intent for the executable to be installed into the
|
||||||
|
// standard location when the user invokes the "install" step (the default
|
||||||
|
// step when running `zig build`).
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
// This *creates* a Run step in the build graph, to be executed when another
|
||||||
|
// step is evaluated that depends on it. The next line below will establish
|
||||||
|
// such a dependency.
|
||||||
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
|
||||||
|
// By making the run step depend on the install step, it will be run from the
|
||||||
|
// installation directory rather than directly from within the cache directory.
|
||||||
|
// This is not necessary, however, if the application depends on other installed
|
||||||
|
// files, this ensures they will be present and in the expected location.
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
// This allows the user to pass arguments to the application in the build
|
||||||
|
// command itself, like this: `zig build run -- arg1 arg2 etc`
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This creates a build step. It will be visible in the `zig build --help` menu,
|
||||||
|
// and can be selected like this: `zig build run`
|
||||||
|
// This will evaluate the `run` step rather than the default, which is "install".
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
|
||||||
|
// Creates a step for unit testing. This only builds the test executable
|
||||||
|
// but does not run it.
|
||||||
|
const lib_unit_tests = b.addTest(.{
|
||||||
|
.root_source_file = b.path("src/root.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||||
|
|
||||||
|
const exe_unit_tests = b.addTest(.{
|
||||||
|
.root_source_file = b.path("src/main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
|
||||||
|
|
||||||
|
// Similar to creating the run step earlier, this exposes a `test` step to
|
||||||
|
// the `zig build --help` menu, providing a way for the user to request
|
||||||
|
// running the unit tests.
|
||||||
|
const test_step = b.step("test", "Run unit tests");
|
||||||
|
test_step.dependOn(&run_lib_unit_tests.step);
|
||||||
|
test_step.dependOn(&run_exe_unit_tests.step);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
.{
|
||||||
|
.name = "skill-ls",
|
||||||
|
// This is a [Semantic Version](https://semver.org/).
|
||||||
|
// In a future version of Zig it will be used for package deduplication.
|
||||||
|
.version = "0.0.0",
|
||||||
|
|
||||||
|
// This field is optional.
|
||||||
|
// This is currently advisory only; Zig does not yet do anything
|
||||||
|
// with this value.
|
||||||
|
//.minimum_zig_version = "0.11.0",
|
||||||
|
|
||||||
|
// This field is optional.
|
||||||
|
// Each dependency must either provide a `url` and `hash`, or a `path`.
|
||||||
|
// `zig build --fetch` can be used to fetch all dependencies of a package, recursively.
|
||||||
|
// Once all dependencies are fetched, `zig build` no longer requires
|
||||||
|
// internet connectivity.
|
||||||
|
.dependencies = .{
|
||||||
|
.lsfw = .{
|
||||||
|
.path = "lib/lsfw",
|
||||||
|
}
|
||||||
|
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
|
||||||
|
//.example = .{
|
||||||
|
// // When updating this field to a new URL, be sure to delete the corresponding
|
||||||
|
// // `hash`, otherwise you are communicating that you expect to find the old hash at
|
||||||
|
// // the new URL.
|
||||||
|
// .url = "https://example.com/foo.tar.gz",
|
||||||
|
//
|
||||||
|
// // This is computed from the file contents of the directory of files that is
|
||||||
|
// // obtained after fetching `url` and applying the inclusion rules given by
|
||||||
|
// // `paths`.
|
||||||
|
// //
|
||||||
|
// // This field is the source of truth; packages do not come from a `url`; they
|
||||||
|
// // come from a `hash`. `url` is just one of many possible mirrors for how to
|
||||||
|
// // obtain a package matching this `hash`.
|
||||||
|
// //
|
||||||
|
// // Uses the [multihash](https://multiformats.io/multihash/) format.
|
||||||
|
// .hash = "...",
|
||||||
|
//
|
||||||
|
// // When this is provided, the package is found in a directory relative to the
|
||||||
|
// // build root. In this case the package's hash is irrelevant and therefore not
|
||||||
|
// // computed. This field and `url` are mutually exclusive.
|
||||||
|
// .path = "foo",
|
||||||
|
|
||||||
|
// // When this is set to `true`, a package is declared to be lazily
|
||||||
|
// // fetched. This makes the dependency only get fetched if it is
|
||||||
|
// // actually used.
|
||||||
|
// .lazy = false,
|
||||||
|
//},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Specifies the set of files and directories that are included in this package.
|
||||||
|
// Only files and directories listed here are included in the `hash` that
|
||||||
|
// is computed for this package.
|
||||||
|
// Paths are relative to the build root. Use the empty string (`""`) to refer to
|
||||||
|
// the build root itself.
|
||||||
|
// A directory listed here means that all files within, recursively, are included.
|
||||||
|
.paths = .{
|
||||||
|
// This makes *all* files, recursively, included in this package. It is generally
|
||||||
|
// better to explicitly list the files and directories instead, to insure that
|
||||||
|
// fetching from tarballs, file system paths, and version control all result
|
||||||
|
// in the same contents hash.
|
||||||
|
"",
|
||||||
|
// For example...
|
||||||
|
//"build.zig",
|
||||||
|
//"build.zig.zon",
|
||||||
|
//"src",
|
||||||
|
//"LICENSE",
|
||||||
|
//"README.md",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
;;; this is some example module docstring
|
||||||
|
|
||||||
|
; random comment
|
||||||
|
|
||||||
|
a=1+2.0*3e2-4/ 5
|
||||||
|
b_var->a
|
||||||
|
|
||||||
|
|
||||||
|
(list 1 2 34)
|
||||||
|
'(1 2 3 4)
|
||||||
|
|
||||||
|
(procedure func_name(param1 param2 @keys (a nil))
|
||||||
|
; some struff to do
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
"srting"
|
||||||
|
|
||||||
|
"wqdwd\"qwesfwf"
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
example = nil
|
|
||||||
example2 = example
|
|
||||||
|
|
||||||
(call qdwdq)
|
|
||||||
|
|
||||||
;; func2(g_arg1 g_arg2 ?g_args1 1 ?g_argw 2) => nil
|
|
||||||
(procedure Func2(arg1 arg2 @keys (args "ss") (argw 2) "ggng")
|
|
||||||
(let ()
|
|
||||||
; some stuff to do
|
|
||||||
a = some_obj->field1
|
|
||||||
some_obj->field2 = 2
|
|
||||||
db_obj->help()
|
|
||||||
args = 2
|
|
||||||
args
|
|
||||||
|
|
||||||
(foreach inner arg2
|
|
||||||
|
|
||||||
;hi
|
|
||||||
)
|
|
||||||
|
|
||||||
(procedure Wqrqw(a1 a2 @keys (a "12") "sqd")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(let (some vars (default "sd"))
|
|
||||||
; ... some wall of text
|
|
||||||
"))\""
|
|
||||||
wqdqwf = '(doqwf)
|
|
||||||
'wq
|
|
||||||
var = 1.3
|
|
||||||
vars = 231
|
|
||||||
qqvwv
|
|
||||||
if(expr then expr else expr)
|
|
||||||
cfunc()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
let( (inner inner2)
|
|
||||||
; block
|
|
||||||
)
|
|
||||||
somefunccall("somecalcfunc()")
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
[project]
|
|
||||||
name = "skillls"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"parsimonious~=0.10.0",
|
|
||||||
"pygls~=2.0",
|
|
||||||
"rich",
|
|
||||||
"tree-sitter>=0.24.0",
|
|
||||||
"tree-sitter-skill>=0.1.5",
|
|
||||||
]
|
|
||||||
requires-python = ">= 3.11"
|
|
||||||
|
|
||||||
[project.optional-dependencies]
|
|
||||||
dev = [
|
|
||||||
"black",
|
|
||||||
"mypy",
|
|
||||||
"ruff",
|
|
||||||
"pytest",
|
|
||||||
"types-parsimonious",
|
|
||||||
]
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
build-backend = 'setuptools.build_meta'
|
|
||||||
requires = [
|
|
||||||
'setuptools',
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.scripts]
|
|
||||||
skillls = "skillls.main:main"
|
|
||||||
|
|
||||||
|
|
||||||
[tools.black]
|
|
||||||
line-length = 100
|
|
||||||
target-version = "py311"
|
|
||||||
include = "skillls"
|
|
||||||
|
|
||||||
[tools.ruff]
|
|
||||||
line-length = 100
|
|
||||||
include = ['ALL']
|
|
||||||
|
|
||||||
[tool.uv.sources]
|
|
||||||
tree-sitter-skill = { git = "ssh://git@git.acereca.net/acereca/tree-sitter-skill.git" }
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
from dataclasses import dataclass
|
|
||||||
from enum import Enum, auto
|
|
||||||
|
|
||||||
from lsprotocol.types import Location, Position, Range
|
|
||||||
|
|
||||||
from skillls.types import URI
|
|
||||||
|
|
||||||
|
|
||||||
class SyntaxError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ParenMismatchErrorKind(Enum):
|
|
||||||
TooManyClosed = "Found too many closing parens"
|
|
||||||
TooManyOpened = "Found too many open parens"
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ParenMismatchError(SyntaxError):
|
|
||||||
kind: ParenMismatchErrorKind
|
|
||||||
loc: Range
|
|
||||||
|
|
||||||
|
|
||||||
def _check_for_matching_parens(content: str) -> list[Exception]:
|
|
||||||
excs: list[Exception] = []
|
|
||||||
|
|
||||||
opened = 0
|
|
||||||
line = 0
|
|
||||||
col = 0
|
|
||||||
last_open: Position = Position(0, 0)
|
|
||||||
last_close: Position = Position(0, 0)
|
|
||||||
for char in content:
|
|
||||||
match char:
|
|
||||||
case "(":
|
|
||||||
opened += 1
|
|
||||||
last_open = Position(line, col)
|
|
||||||
|
|
||||||
case ")":
|
|
||||||
opened -= 1
|
|
||||||
if opened < 0:
|
|
||||||
excs.append(
|
|
||||||
ParenMismatchError(
|
|
||||||
ParenMismatchErrorKind.TooManyClosed,
|
|
||||||
Range(Position(line, col), Position(line, col + 1)),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
opened = 0
|
|
||||||
last_close = Position(line, col)
|
|
||||||
case "\n":
|
|
||||||
line += 1
|
|
||||||
col = -1
|
|
||||||
|
|
||||||
case _:
|
|
||||||
pass
|
|
||||||
|
|
||||||
col += 1
|
|
||||||
|
|
||||||
if opened > 0:
|
|
||||||
excs.append(
|
|
||||||
ParenMismatchError(
|
|
||||||
ParenMismatchErrorKind.TooManyOpened,
|
|
||||||
Range(last_open, Position(last_open.line, last_open.character + 1)),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return excs
|
|
||||||
|
|
||||||
|
|
||||||
def check_content_for_errors(clean_content: str) -> None:
|
|
||||||
excs: list[Exception] = []
|
|
||||||
|
|
||||||
excs.extend(_check_for_matching_parens(clean_content))
|
|
||||||
|
|
||||||
if excs:
|
|
||||||
raise ExceptionGroup("", excs)
|
|
||||||
|
|
@ -1,192 +0,0 @@
|
||||||
from copy import copy
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from logging import getLogger
|
|
||||||
from pathlib import Path
|
|
||||||
from pprint import pformat
|
|
||||||
from lsprotocol.types import DocumentSymbol, Position, Range, SymbolKind
|
|
||||||
from re import MULTILINE, compile as recompile, finditer
|
|
||||||
|
|
||||||
from pygls.workspace import TextDocument
|
|
||||||
|
|
||||||
from skillls.checker import check_content_for_errors
|
|
||||||
from skillls.types import URI, Node, NodeKind
|
|
||||||
|
|
||||||
logger = getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ParserCleanerState:
|
|
||||||
in_comment: bool = False
|
|
||||||
in_string: bool = False
|
|
||||||
|
|
||||||
|
|
||||||
NODE_KIND_OPTIONS = "|".join(k.value for k in NodeKind)
|
|
||||||
NAMESPACE_STARTERS = recompile(
|
|
||||||
(rf"(\(\s*(?P<typ>{NODE_KIND_OPTIONS})\b|\b(?P<ctyp>{NODE_KIND_OPTIONS})\()"),
|
|
||||||
MULTILINE,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def clean_content(content: str) -> str:
|
|
||||||
content_cleaned = ""
|
|
||||||
state = ParserCleanerState()
|
|
||||||
|
|
||||||
for cix, char in enumerate(content):
|
|
||||||
match (content[cix], state):
|
|
||||||
case ";", ParserCleanerState(in_comment=False, in_string=False):
|
|
||||||
state.in_comment = True
|
|
||||||
case '"', ParserCleanerState(in_comment=False):
|
|
||||||
if content[cix - 1] != "\\":
|
|
||||||
state.in_string = not state.in_string
|
|
||||||
content_cleaned += char
|
|
||||||
case "\n", ParserCleanerState(in_comment=True):
|
|
||||||
state.in_comment = False
|
|
||||||
content_cleaned += char
|
|
||||||
case _, ParserCleanerState(in_comment=False, in_string=False):
|
|
||||||
content_cleaned += char
|
|
||||||
|
|
||||||
case _, ParserCleanerState(in_comment=False, in_string=True):
|
|
||||||
content_cleaned += " "
|
|
||||||
case _:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return content_cleaned
|
|
||||||
|
|
||||||
|
|
||||||
def build_node_hierarchy(nodes: list[Node]) -> list[Node]:
|
|
||||||
to_be_sorted = copy(nodes)
|
|
||||||
sorted: list[Node] = []
|
|
||||||
|
|
||||||
while to_be_sorted:
|
|
||||||
node_to_sort = to_be_sorted.pop(0)
|
|
||||||
|
|
||||||
for sorted_node in sorted:
|
|
||||||
if sorted_node.should_contain(node_to_sort):
|
|
||||||
sorted_node.add_child(node_to_sort)
|
|
||||||
break
|
|
||||||
|
|
||||||
else:
|
|
||||||
sorted.append(node_to_sort)
|
|
||||||
|
|
||||||
return sorted
|
|
||||||
|
|
||||||
|
|
||||||
def find_scopes(content_cleaned: str, scope_prefix: str = "") -> list[Node]:
|
|
||||||
ret: list[Node] = []
|
|
||||||
|
|
||||||
for found in NAMESPACE_STARTERS.finditer(content_cleaned):
|
|
||||||
partial = content_cleaned[found.end() :]
|
|
||||||
open_brackets = 1
|
|
||||||
offset = 0
|
|
||||||
for offset, char in enumerate(partial):
|
|
||||||
match char:
|
|
||||||
case "(":
|
|
||||||
open_brackets += 1
|
|
||||||
case ")":
|
|
||||||
open_brackets -= 1
|
|
||||||
|
|
||||||
if open_brackets == 0:
|
|
||||||
break
|
|
||||||
|
|
||||||
case _:
|
|
||||||
pass
|
|
||||||
|
|
||||||
pre_lines = content_cleaned[: found.start()].splitlines()
|
|
||||||
start_line = len(pre_lines) - (
|
|
||||||
1 if pre_lines[-1] != "" and pre_lines[-1].strip() == "" else 0
|
|
||||||
)
|
|
||||||
start_char = len(pre_lines[-1])
|
|
||||||
|
|
||||||
inner_lines = content_cleaned[
|
|
||||||
found.start() : found.end() + offset + 1
|
|
||||||
].splitlines()
|
|
||||||
end_line = start_line + len(inner_lines) - 1
|
|
||||||
end_char = len(inner_lines[-1])
|
|
||||||
|
|
||||||
kind = NodeKind(found.group("typ") or found.group("ctyp"))
|
|
||||||
loc = Range(Position(start_line, start_char), Position(end_line, end_char))
|
|
||||||
|
|
||||||
node = Node(
|
|
||||||
node=f"{scope_prefix}.{kind.value}_{len([n for n in ret if n.kind == kind])}",
|
|
||||||
kind=kind,
|
|
||||||
location=loc,
|
|
||||||
)
|
|
||||||
ret.append(node)
|
|
||||||
|
|
||||||
next = found.end()
|
|
||||||
|
|
||||||
# allowed scoped locals syntax
|
|
||||||
# function(pos1 pos2)
|
|
||||||
# function(pos1 (pos2 default))
|
|
||||||
# function(pos1 @rest args)
|
|
||||||
# function(pos1 @key (kwarg1 default1) (kwarg2 default2))
|
|
||||||
|
|
||||||
while content_cleaned[next] != "(":
|
|
||||||
if content_cleaned[next] == "\n":
|
|
||||||
start_line += 1
|
|
||||||
start_char = 0
|
|
||||||
next += 1
|
|
||||||
start_char += 1
|
|
||||||
|
|
||||||
next += 1
|
|
||||||
last = 0
|
|
||||||
|
|
||||||
for positional in finditer(
|
|
||||||
r"(?P<leading>\s*)(?P<local>\w+|\(\w+\b[^)]*\))(?P<trailing>\s*)",
|
|
||||||
content_cleaned[next:],
|
|
||||||
):
|
|
||||||
if positional.start() != last:
|
|
||||||
logger.debug(
|
|
||||||
f"found ({positional}), but last ({last}) != ({positional.start()})"
|
|
||||||
)
|
|
||||||
break
|
|
||||||
|
|
||||||
last = positional.end()
|
|
||||||
|
|
||||||
leading_nls = positional.group("leading").count("\n")
|
|
||||||
inner_nls = positional.group("local").count("\n")
|
|
||||||
trailing_nls = positional.group("trailing").count("\n")
|
|
||||||
|
|
||||||
local_name = positional.group("local").split()[0]
|
|
||||||
local = DocumentSymbol(
|
|
||||||
name=local_name,
|
|
||||||
kind=SymbolKind.Variable,
|
|
||||||
range=Range(
|
|
||||||
Position(
|
|
||||||
start_line + leading_nls,
|
|
||||||
len(positional.group("leading")) + start_char,
|
|
||||||
),
|
|
||||||
Position(
|
|
||||||
start_line + leading_nls,
|
|
||||||
len(positional.group("leading")) + start_char + len(local_name),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
selection_range=Range(
|
|
||||||
Position(
|
|
||||||
start_line + leading_nls,
|
|
||||||
len(positional.group("leading")) + start_char,
|
|
||||||
),
|
|
||||||
Position(
|
|
||||||
start_line + leading_nls,
|
|
||||||
len(positional.group("leading")) + start_char + len(local_name),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
node.symbols[local_name] = local
|
|
||||||
|
|
||||||
start_line += leading_nls + inner_nls + trailing_nls
|
|
||||||
start_char += len(positional.group(0))
|
|
||||||
|
|
||||||
# other cases
|
|
||||||
|
|
||||||
logger.debug(pformat(node))
|
|
||||||
return build_node_hierarchy(ret)
|
|
||||||
|
|
||||||
|
|
||||||
def parse_file(file: TextDocument) -> list[Node]:
|
|
||||||
content = file.source
|
|
||||||
content_cleaned = clean_content(content)
|
|
||||||
|
|
||||||
check_content_for_errors(content_cleaned)
|
|
||||||
|
|
||||||
return find_scopes(content_cleaned, scope_prefix=Path(file.path).stem)
|
|
||||||
167
skillls/main.py
167
skillls/main.py
|
|
@ -1,167 +0,0 @@
|
||||||
from logging import DEBUG, basicConfig, getLogger
|
|
||||||
from pathlib import Path
|
|
||||||
from typing import Any
|
|
||||||
from lsprotocol.types import (
|
|
||||||
TEXT_DOCUMENT_DID_CHANGE,
|
|
||||||
TEXT_DOCUMENT_DID_CLOSE,
|
|
||||||
TEXT_DOCUMENT_DID_OPEN,
|
|
||||||
INITIALIZE,
|
|
||||||
TEXT_DOCUMENT_DID_SAVE,
|
|
||||||
TEXT_DOCUMENT_DOCUMENT_SYMBOL,
|
|
||||||
TEXT_DOCUMENT_INLAY_HINT,
|
|
||||||
Diagnostic,
|
|
||||||
DiagnosticSeverity,
|
|
||||||
DidChangeTextDocumentParams,
|
|
||||||
DidCloseTextDocumentParams,
|
|
||||||
DidOpenTextDocumentParams,
|
|
||||||
DocumentSymbol,
|
|
||||||
DocumentSymbolParams,
|
|
||||||
InitializeParams,
|
|
||||||
InlayHint,
|
|
||||||
InlayHintKind,
|
|
||||||
InlayHintParams,
|
|
||||||
NotebookDocumentSyncOptions,
|
|
||||||
PublishDiagnosticsParams,
|
|
||||||
TextDocumentSyncKind,
|
|
||||||
)
|
|
||||||
from pygls.lsp.server import LanguageServer
|
|
||||||
|
|
||||||
|
|
||||||
from skillls.checker import ParenMismatchError
|
|
||||||
from skillls.helpers import parse_file
|
|
||||||
from skillls.types import URI, Node
|
|
||||||
|
|
||||||
basicConfig(
|
|
||||||
filename="skillls.log",
|
|
||||||
filemode="w",
|
|
||||||
level=DEBUG,
|
|
||||||
format="%(asctime)s [%(levelname)s]: %(message)s",
|
|
||||||
)
|
|
||||||
logger = getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class SkillLanguageServer(LanguageServer):
|
|
||||||
ws_files: set[URI]
|
|
||||||
opened_files: set[URI]
|
|
||||||
scopes: dict[URI, list[Node]]
|
|
||||||
errs: dict[URI, ExceptionGroup]
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
name: str,
|
|
||||||
version: str,
|
|
||||||
text_document_sync_kind: TextDocumentSyncKind = TextDocumentSyncKind.Incremental,
|
|
||||||
notebook_document_sync: NotebookDocumentSyncOptions | None = None,
|
|
||||||
):
|
|
||||||
super().__init__(name, version, text_document_sync_kind, notebook_document_sync)
|
|
||||||
self.ws_files = set()
|
|
||||||
self.opened_files = set()
|
|
||||||
self.scopes = {}
|
|
||||||
self.errs = {}
|
|
||||||
|
|
||||||
def update_diagnostics(self) -> None:
|
|
||||||
for uri in self.opened_files:
|
|
||||||
diags: list[Diagnostic] = []
|
|
||||||
if eg := self.errs.get(uri):
|
|
||||||
for exc in eg.exceptions:
|
|
||||||
match exc:
|
|
||||||
case ParenMismatchError():
|
|
||||||
diags.append(
|
|
||||||
Diagnostic(
|
|
||||||
message=f"[skill_ls] {Path.from_uri(uri).name}:{exc.loc.start.line} {exc.kind.value}",
|
|
||||||
severity=DiagnosticSeverity.Error,
|
|
||||||
range=exc.loc,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# if diags:
|
|
||||||
self.text_document_publish_diagnostics(
|
|
||||||
PublishDiagnosticsParams(
|
|
||||||
uri=uri,
|
|
||||||
version=self.workspace.get_text_document(uri).version,
|
|
||||||
diagnostics=diags,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
server = SkillLanguageServer("SkillLS", "0.2.0")
|
|
||||||
|
|
||||||
|
|
||||||
@server.feature(INITIALIZE)
|
|
||||||
def lsp_initialize(server: SkillLanguageServer, params: InitializeParams) -> None:
|
|
||||||
init_options: dict[str, Any] = params.initialization_options or {}
|
|
||||||
|
|
||||||
logger.info("done init")
|
|
||||||
logger.debug(init_options)
|
|
||||||
ws_dir = server.workspace.root_path
|
|
||||||
|
|
||||||
logger.debug(ws_dir)
|
|
||||||
|
|
||||||
if ws_dir:
|
|
||||||
root_dir = Path(ws_dir)
|
|
||||||
for file in (*root_dir.rglob("*.il"), *root_dir.rglob("*.ocn")):
|
|
||||||
uri = file.as_uri()
|
|
||||||
logger.debug(uri)
|
|
||||||
|
|
||||||
server.ws_files.add(uri)
|
|
||||||
try:
|
|
||||||
server.scopes[uri] = parse_file(server.workspace.get_text_document(uri))
|
|
||||||
if server.errs.get(uri):
|
|
||||||
del server.errs[uri]
|
|
||||||
except ExceptionGroup as eg:
|
|
||||||
server.errs[uri] = eg
|
|
||||||
|
|
||||||
|
|
||||||
@server.feature(TEXT_DOCUMENT_DID_OPEN)
|
|
||||||
def on_open(server: SkillLanguageServer, params: DidOpenTextDocumentParams) -> None:
|
|
||||||
server.opened_files.add(params.text_document.uri)
|
|
||||||
|
|
||||||
server.update_diagnostics()
|
|
||||||
|
|
||||||
|
|
||||||
@server.feature(TEXT_DOCUMENT_DID_CLOSE)
|
|
||||||
def on_close(server: SkillLanguageServer, params: DidCloseTextDocumentParams) -> None:
|
|
||||||
server.opened_files.remove(params.text_document.uri)
|
|
||||||
|
|
||||||
|
|
||||||
@server.feature(TEXT_DOCUMENT_DID_CHANGE)
|
|
||||||
@server.feature(TEXT_DOCUMENT_DID_SAVE)
|
|
||||||
def on_change(server: SkillLanguageServer, params: DidChangeTextDocumentParams) -> None:
|
|
||||||
try:
|
|
||||||
server.scopes[params.text_document.uri] = parse_file(
|
|
||||||
server.workspace.get_text_document(params.text_document.uri)
|
|
||||||
)
|
|
||||||
if server.errs.get(params.text_document.uri):
|
|
||||||
del server.errs[params.text_document.uri]
|
|
||||||
except ExceptionGroup as eg:
|
|
||||||
server.errs[params.text_document.uri] = eg
|
|
||||||
|
|
||||||
server.update_diagnostics()
|
|
||||||
|
|
||||||
|
|
||||||
@server.feature(TEXT_DOCUMENT_INLAY_HINT)
|
|
||||||
def on_inlay(server: SkillLanguageServer, params: InlayHintParams) -> list[InlayHint]:
|
|
||||||
hints: list[InlayHint] = []
|
|
||||||
uri = params.text_document.uri
|
|
||||||
for node in server.scopes.get(uri, []):
|
|
||||||
hints.append(
|
|
||||||
InlayHint(
|
|
||||||
label=node.node,
|
|
||||||
kind=InlayHintKind.Type,
|
|
||||||
padding_left=True,
|
|
||||||
position=node.location.end,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return hints
|
|
||||||
|
|
||||||
|
|
||||||
@server.feature(TEXT_DOCUMENT_DOCUMENT_SYMBOL)
|
|
||||||
def on_symbols(
|
|
||||||
server: SkillLanguageServer, params: DocumentSymbolParams
|
|
||||||
) -> list[DocumentSymbol] | None:
|
|
||||||
return [node.as_doc_symbol() for node in server.scopes[params.text_document.uri]]
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
server.start_io()
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
from dataclasses import dataclass, field
|
|
||||||
from enum import Enum, auto
|
|
||||||
from lsprotocol.types import DocumentSymbol, Range, SymbolKind
|
|
||||||
|
|
||||||
URI = str
|
|
||||||
|
|
||||||
|
|
||||||
class NodeKind(Enum):
|
|
||||||
LET = "let"
|
|
||||||
PROCEDURE = "procedure"
|
|
||||||
PROC = "proc"
|
|
||||||
FOREACH = "foreach"
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Node:
|
|
||||||
node: str
|
|
||||||
kind: NodeKind
|
|
||||||
location: Range
|
|
||||||
children: list["Node"] = field(default_factory=list)
|
|
||||||
symbols: dict[str, DocumentSymbol] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def all_symbols(self) -> list[DocumentSymbol]:
|
|
||||||
return [
|
|
||||||
*self.symbols.values(),
|
|
||||||
*(sym for child in self.children for sym in child.all_symbols),
|
|
||||||
]
|
|
||||||
|
|
||||||
def should_contain(self, other: "Node") -> bool:
|
|
||||||
"""range based overlap check"""
|
|
||||||
|
|
||||||
start_after = (other.location.start.line > self.location.start.line) or (
|
|
||||||
(other.location.start.line == self.location.start.line)
|
|
||||||
and (other.location.start.character > self.location.start.character)
|
|
||||||
)
|
|
||||||
ends_before = (other.location.end.line < self.location.end.line) or (
|
|
||||||
(other.location.end.line == self.location.end.line)
|
|
||||||
and (other.location.end.character < self.location.start.character)
|
|
||||||
)
|
|
||||||
|
|
||||||
return start_after and ends_before
|
|
||||||
|
|
||||||
def add_child(self, new_child: "Node") -> None:
|
|
||||||
for existing_child in self.children:
|
|
||||||
if existing_child.should_contain(new_child):
|
|
||||||
existing_child.add_child(new_child)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.children.append(new_child)
|
|
||||||
|
|
||||||
def as_doc_symbol(self) -> DocumentSymbol:
|
|
||||||
return DocumentSymbol(
|
|
||||||
name=self.node,
|
|
||||||
kind=SymbolKind.Namespace,
|
|
||||||
range=self.location,
|
|
||||||
selection_range=self.location,
|
|
||||||
children=list(self.symbols.values())
|
|
||||||
+ [child.as_doc_symbol() for child in self.children],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DocumentSymbols:
|
|
||||||
uri: str
|
|
||||||
tree: Node
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
const tkz = @import("tokenize.zig");
|
||||||
|
const hlp = @import("helpers.zig");
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const TokenClass = enum {
|
||||||
|
symbol,
|
||||||
|
string,
|
||||||
|
comment,
|
||||||
|
docstring,
|
||||||
|
number,
|
||||||
|
nil,
|
||||||
|
t,
|
||||||
|
list_start,
|
||||||
|
list_lazy_start,
|
||||||
|
list_end,
|
||||||
|
operator,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ClassifiedToken = struct {
|
||||||
|
tok: tkz.Token,
|
||||||
|
cls: TokenClass,
|
||||||
|
};
|
||||||
|
|
||||||
|
const operators = std.ComptimeStringMap(void, .{
|
||||||
|
.{"->"},
|
||||||
|
.{"~>"},
|
||||||
|
.{"/="},
|
||||||
|
.{"*="},
|
||||||
|
.{"-="},
|
||||||
|
.{"+="},
|
||||||
|
.{"||"},
|
||||||
|
.{"&&"},
|
||||||
|
.{"="},
|
||||||
|
.{"+"},
|
||||||
|
.{"-"},
|
||||||
|
.{"*"},
|
||||||
|
.{"/"},
|
||||||
|
.{"~"},
|
||||||
|
.{"%"},
|
||||||
|
.{"@keys"},
|
||||||
|
.{"@rest"},
|
||||||
|
});
|
||||||
|
|
||||||
|
const numbers = std.ComptimeStringMap(void, .{
|
||||||
|
.{"0"},
|
||||||
|
.{"1"},
|
||||||
|
.{"2"},
|
||||||
|
.{"3"},
|
||||||
|
.{"4"},
|
||||||
|
.{"5"},
|
||||||
|
.{"6"},
|
||||||
|
.{"7"},
|
||||||
|
.{"8"},
|
||||||
|
.{"9"},
|
||||||
|
});
|
||||||
|
|
||||||
|
fn classify(tok: tkz.Token) ClassifiedToken {
|
||||||
|
return ClassifiedToken{
|
||||||
|
.tok = tok,
|
||||||
|
.cls = if (operators.has(tok.value))
|
||||||
|
TokenClass.operator
|
||||||
|
else if (std.mem.eql(u8, "'(", tok.value))
|
||||||
|
TokenClass.list_lazy_start
|
||||||
|
else if (std.mem.eql(u8, "(", tok.value))
|
||||||
|
TokenClass.list_start
|
||||||
|
else if (std.mem.eql(u8, ")", tok.value))
|
||||||
|
TokenClass.list_end
|
||||||
|
else if (std.mem.eql(u8, "\"", tok.value[0..1]))
|
||||||
|
TokenClass.string
|
||||||
|
else if (std.mem.eql(u8, "nil", tok.value))
|
||||||
|
TokenClass.nil
|
||||||
|
else if (std.mem.eql(u8, "t", tok.value))
|
||||||
|
TokenClass.t
|
||||||
|
else if (numbers.has(tok.value[0..1]))
|
||||||
|
TokenClass.number
|
||||||
|
else if (std.mem.eql(u8, ";", tok.value[0..1]))
|
||||||
|
if (tok.value.len >= 3 and std.mem.eql(u8, ";;;", tok.value[0..3])) TokenClass.docstring else TokenClass.comment
|
||||||
|
else
|
||||||
|
TokenClass.symbol,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn classifyTokens(toks: []const tkz.Token, allocator: std.mem.Allocator) !std.ArrayList(ClassifiedToken) {
|
||||||
|
var ctoks = std.ArrayList(ClassifiedToken).init(allocator);
|
||||||
|
|
||||||
|
for (toks) |tok| {
|
||||||
|
try ctoks.append(classify(tok));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctoks;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
const std = @import("std");
|
||||||
|
pub fn isPartOf(comptime T: type, haystack: [][]const T, needle: []const T) bool {
|
||||||
|
for (haystack) |straw| {
|
||||||
|
if (std.mem.eql(u8, straw, needle[0..straw.len])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5077a6cc6d6e0cf8ed95db234146aa14c42767f0
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const lsp_types = @import("lsfw/src/types.zig");
|
||||||
|
const lsp = @import("lsfw/src/lsp.zig");
|
||||||
|
const lsp_doc = @import("lsfw/src/document.zig");
|
||||||
|
const lsp_log = @import("lsfw/src/logger.zig");
|
||||||
|
const tkz = @import("tokenize.zig");
|
||||||
|
const cls = @import("classifier.zig");
|
||||||
|
|
||||||
|
const State = struct { symbols: std.ArrayList(cls.ClassifiedToken) };
|
||||||
|
const Lsp = lsp.Lsp(State);
|
||||||
|
const Scope = enum { hi };
|
||||||
|
|
||||||
|
fn handleHover(allocator: std.mem.Allocator, ctx: *Lsp.Context, pos: lsp_types.Position) ?[]const u8 {
|
||||||
|
if (null == ctx.state) {
|
||||||
|
lsp_log.notify(.info, "could not find token under cursor (at {})", .{pos});
|
||||||
|
return null;
|
||||||
|
} else if (0 == ctx.state.?.symbols.items.len) {
|
||||||
|
handleDocOpen(allocator, ctx);
|
||||||
|
}
|
||||||
|
lsp_log.notify(.err, "{}", .{ctx.state.?.symbols});
|
||||||
|
// for (ctx.state.?.symbols.items) |tok| {
|
||||||
|
// if (tok.tok.line == pos.line and tok.tok.char <= pos.character and (tok.tok.char + tok.tok.value.len) >= pos.character) {
|
||||||
|
// lsp_log.notify(.info, "{}", .{tok});
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleCompletion(allocator: std.mem.Allocator, context: *Lsp.Context, position: lsp_types.Position) ?lsp_types.CompletionList {
|
||||||
|
_ = context;
|
||||||
|
_ = position;
|
||||||
|
var completions = std.ArrayList(lsp_types.CompletionItem).init(allocator);
|
||||||
|
if (std.mem.Allocator.Error.OutOfMemory == completions.append(.{
|
||||||
|
.label = "(procedure)",
|
||||||
|
.insertText = "(procedure ${1:func_name}($2)\n\n)",
|
||||||
|
.insertTextFormat = .Snippet,
|
||||||
|
.kind = .Function,
|
||||||
|
})) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{ .items = completions.items };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleDocOpen(allocator: std.mem.Allocator, context: *Lsp.Context) void {
|
||||||
|
lsp_log.notify(.err, "opened doc {s}", .{context.document.uri});
|
||||||
|
const content = context.document.text;
|
||||||
|
const toks = tkz.tokenizeContent(content, allocator) catch unreachable;
|
||||||
|
// const toks = std.ArrayList(tkz.Token).init(allocator);
|
||||||
|
lsp_log.notify(.err, "toks {}", .{toks});
|
||||||
|
// defer toks.deinit();
|
||||||
|
const ctoks = cls.classifyTokens(toks.items, allocator) catch unreachable;
|
||||||
|
lsp_log.notify(.err, "ctoks {}", .{ctoks});
|
||||||
|
// defer ctoks.deinit();
|
||||||
|
// const ast = try stx.generateSyntaxTree(ctoks);
|
||||||
|
|
||||||
|
lsp_log.notify(.info, "opened {s}, found {d} tokens", .{ context.document.uri, ctoks.items.len });
|
||||||
|
if (context.state != null) {
|
||||||
|
context.state.?.symbols.deinit();
|
||||||
|
}
|
||||||
|
context.state = .{
|
||||||
|
.symbols = std.ArrayList(cls.ClassifiedToken).init(allocator),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn handleDocChanged(allocator: std.mem.Allocator, context: *Lsp.Context, _: []lsp_types.ChangeEvent) void {
|
||||||
|
handleDocOpen(allocator, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleDocClose(_: std.mem.Allocator, _: *Lsp.Context) void {}
|
||||||
|
|
||||||
|
pub fn start() !u8 {
|
||||||
|
const descr = lsp_types.ServerData{
|
||||||
|
.serverInfo = .{
|
||||||
|
.name = "skill lsp",
|
||||||
|
.version = "0.1.0",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
var server = Lsp.init(gpa.allocator(), descr);
|
||||||
|
|
||||||
|
server.registerHoverCallback(handleHover);
|
||||||
|
server.registerCompletionCallback(handleCompletion);
|
||||||
|
server.registerDocOpenCallback(handleDocOpen);
|
||||||
|
server.registerDocChangeCallback(handleDocChanged);
|
||||||
|
server.registerDocCloseCallback(handleDocClose);
|
||||||
|
return server.start();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const tkz = @import("tokenizer.zig");
|
||||||
|
// const cls = @import("classifier.zig");
|
||||||
|
// const stx = @import("syntax.zig");
|
||||||
|
const lsp = @import("lsp.zig");
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
// var file = try std.fs.cwd().openFile("data/example.il", .{});
|
||||||
|
// defer file.close();
|
||||||
|
//
|
||||||
|
// const content = try file.readToEndAlloc(std.heap.page_allocator, 4096 * ((1 << 10) << 10));
|
||||||
|
//
|
||||||
|
// const toks = try tkz.tokenizeContent(content);
|
||||||
|
// // for (toks.items) |tok| {
|
||||||
|
// // std.debug.print("{}:{} `{s}`\n", .{
|
||||||
|
// // tok.line,
|
||||||
|
// // tok.char,
|
||||||
|
// // tok.value,
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
//
|
||||||
|
// const ctoks = try cls.classifyTokens(toks);
|
||||||
|
// // for (ctoks.items) |ctok| {
|
||||||
|
// // std.debug.print("{}:{}\t`{s:<40}`({})\n", .{
|
||||||
|
// // ctok.tok.line,
|
||||||
|
// // ctok.tok.char,
|
||||||
|
// // ctok.tok.value,
|
||||||
|
// // ctok.cls,
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// const ast = try stx.generateSyntaxTree(ctoks);
|
||||||
|
// std.debug.print("{}\n", .{ast});
|
||||||
|
//
|
||||||
|
_ = try lsp.start();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,178 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const toks = @import("tokenizer.zig");
|
||||||
|
|
||||||
|
pub const ParseError = error{ no_fn_name, no_fn_params };
|
||||||
|
|
||||||
|
pub const Tag = enum {
|
||||||
|
///expression
|
||||||
|
///`<rhs...>`
|
||||||
|
///
|
||||||
|
///lhs ignored
|
||||||
|
expr,
|
||||||
|
|
||||||
|
///variable assignment
|
||||||
|
///`<lhs> = <rhs...>`
|
||||||
|
///
|
||||||
|
///lhs is overwritten to be variable
|
||||||
|
var_assign,
|
||||||
|
|
||||||
|
///lazy evaluated list
|
||||||
|
///`'(<rhs...>)`
|
||||||
|
///
|
||||||
|
///lhs ignored
|
||||||
|
llist,
|
||||||
|
|
||||||
|
///list (evaluated)
|
||||||
|
///`(<lhs> <rhs...>)`
|
||||||
|
///
|
||||||
|
///lhs needs to be a callable
|
||||||
|
list_eval,
|
||||||
|
|
||||||
|
///fn_def (procedure)
|
||||||
|
///`;;; <lhs>
|
||||||
|
///(procedure <main_token>(<lhs>) <rhs...>)`
|
||||||
|
fn_def,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Node = struct {
|
||||||
|
tag: Tag,
|
||||||
|
main_token: Index,
|
||||||
|
data: Data,
|
||||||
|
|
||||||
|
pub const Data = struct {
|
||||||
|
lhs: Index,
|
||||||
|
rhs: Index,
|
||||||
|
};
|
||||||
|
pub const Index = u32;
|
||||||
|
};
|
||||||
|
pub const AstError = error{};
|
||||||
|
|
||||||
|
pub const Parser = struct {
|
||||||
|
gpa: std.mem.Allocator,
|
||||||
|
source: [:0]const u8,
|
||||||
|
|
||||||
|
token_tags: []const toks.Token.Tag,
|
||||||
|
token_locs: []const toks.Token.Loc,
|
||||||
|
tok_i: Node.Index,
|
||||||
|
|
||||||
|
errs: std.ArrayList(AstError),
|
||||||
|
nodes: std.MultiArrayList(Node),
|
||||||
|
extra_data: std.ArrayList(Node.Index),
|
||||||
|
scratch: std.ArrayList(Node.Index),
|
||||||
|
|
||||||
|
pub fn init(buffer: [:0]const u8, mal: std.MultiArrayList(toks.Token), allocator: std.mem.Allocator) !Parser {
|
||||||
|
return .{
|
||||||
|
.gpa = allocator,
|
||||||
|
.source = buffer,
|
||||||
|
|
||||||
|
.token_tags = mal.items(.tag),
|
||||||
|
.token_locs = mal.items(.loc),
|
||||||
|
.tok_i = 0,
|
||||||
|
|
||||||
|
.errs = std.ArrayList(AstError).init(allocator),
|
||||||
|
.nodes = std.MultiArrayList(Node){},
|
||||||
|
.extra_data = std.ArrayList(Node.Index).init(allocator),
|
||||||
|
.scratch = std.ArrayList(Node.Index).init(allocator),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hasToken(self: *Parser, expected: toks.Token.Tag, offset: isize) ?toks.Token {
|
||||||
|
if (self.token_tags[@intCast(self.tok_i + offset)] == expected) {
|
||||||
|
return .{ .loc = self.token_locs[@intCast(self.tok_i + offset)], .tag = self.token_tags[@intCast(self.tok_i + offset)] };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
fn eatToken(self: *Parser, expected: toks.Token.Tag) ?Node.Index {
|
||||||
|
const tok = self.hasToken(expected, 0);
|
||||||
|
if (tok != null) {
|
||||||
|
self.tok_i += 1;
|
||||||
|
return self.tok_i - 1;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_fn_proc(self: *Parser) ?Node {
|
||||||
|
_ = self.eatToken(.sym);
|
||||||
|
if (self.hasToken(.list_l, -2) != null) {
|
||||||
|
// lisp style
|
||||||
|
} else if (self.eatToken(.list_l) != null) {
|
||||||
|
// c style
|
||||||
|
} else {
|
||||||
|
// not a procedure call or invalid syntax?
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = self.eatToken(.sym) orelse return null;
|
||||||
|
std.debug.print("found procedure def for `{s}`", .{self.source[self.token_locs[name].start..self.token_locs[name].end]});
|
||||||
|
_ = self.eatToken(.list_l) orelse return null;
|
||||||
|
var open_lists: usize = 0;
|
||||||
|
while (true) : (self.tok_i += 1) {
|
||||||
|
switch (self.token_tags[self.tok_i]) {
|
||||||
|
.list_l, .list_lz => {
|
||||||
|
open_lists += 1;
|
||||||
|
},
|
||||||
|
.list_r => {
|
||||||
|
if (open_lists > 0) {
|
||||||
|
open_lists -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) : (self.tok_i += 1) {
|
||||||
|
switch (self.token_tags[self.tok_i]) {
|
||||||
|
.list_l, .list_lz => {
|
||||||
|
open_lists += 1;
|
||||||
|
},
|
||||||
|
.list_r => {
|
||||||
|
if (open_lists > 0) {
|
||||||
|
open_lists -= 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.tok_i += 1;
|
||||||
|
|
||||||
|
return Node{ .tag = .fn_def, .main_token = name, .data = .{ .lhs = 0, .rhs = 0 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(self: *Parser) ?Node {
|
||||||
|
while (self.tok_i < self.token_tags.len) : (self.tok_i += 1) {
|
||||||
|
switch (self.token_tags[self.tok_i]) {
|
||||||
|
toks.Token.Tag.sym => {
|
||||||
|
if (std.mem.eql(u8, "procedure", self.source[self.token_locs[self.tok_i].start..self.token_locs[self.tok_i].end])) {
|
||||||
|
return self.parse_fn_proc();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
test "parsing of simple example" {
|
||||||
|
const example =
|
||||||
|
\\t
|
||||||
|
\\nil
|
||||||
|
\\a = b
|
||||||
|
\\"some string w/ escaped\""
|
||||||
|
\\(procedure a() )
|
||||||
|
;
|
||||||
|
|
||||||
|
var tokz = toks.Tokenizer.init(example);
|
||||||
|
var tokens = std.MultiArrayList(toks.Token){};
|
||||||
|
defer tokens.deinit(std.testing.allocator);
|
||||||
|
while (tokz.next()) |tok| {
|
||||||
|
try tokens.append(std.testing.allocator, tok);
|
||||||
|
std.debug.print("{}\n", .{tok});
|
||||||
|
}
|
||||||
|
var parse = try Parser.init(example, tokens, std.testing.allocator);
|
||||||
|
while (parse.next()) |ast_node| {
|
||||||
|
std.debug.print("{}\n", .{ast_node});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
export fn add(a: i32, b: i32) i32 {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "basic add functionality" {
|
||||||
|
try testing.expect(add(3, 7) == 10);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const cls = @import("classifier.zig");
|
||||||
|
|
||||||
|
pub const SyntaxNode = struct {
|
||||||
|
ctok: cls.ClassifiedToken,
|
||||||
|
nodes: ?std.ArrayList(SyntaxNode),
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn generateSyntaxTree(ctoks: std.ArrayList(cls.ClassifiedToken)) !std.ArrayList(SyntaxNode) {
|
||||||
|
var nodes = std.ArrayList(SyntaxNode).init(std.heap.page_allocator);
|
||||||
|
var actives = std.ArrayList(SyntaxNode).init(std.heap.page_allocator);
|
||||||
|
|
||||||
|
for (ctoks.items) |ctok| {
|
||||||
|
switch (ctok.cls) {
|
||||||
|
cls.TokenClass.comment, cls.TokenClass.docstring => {
|
||||||
|
try nodes.append(.{
|
||||||
|
.ctok = ctok,
|
||||||
|
.nodes = null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cls.TokenClass.list_start, cls.TokenClass.list_lazy_start => {
|
||||||
|
try actives.append(.{
|
||||||
|
.ctok = ctok,
|
||||||
|
.nodes = std.ArrayList(SyntaxNode).init(std.heap.page_allocator),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cls.TokenClass.list_end => {
|
||||||
|
if (actives.items.len > 0) {
|
||||||
|
try nodes.append(actives.pop());
|
||||||
|
} else {
|
||||||
|
std.debug.print("{}\n", .{actives});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
const active_top = actives.popOrNull();
|
||||||
|
if (active_top != null) {
|
||||||
|
var active = active_top.?;
|
||||||
|
var actives_nodes: std.ArrayList(SyntaxNode) = undefined;
|
||||||
|
if (active.nodes != null) {
|
||||||
|
actives_nodes = active.nodes.?;
|
||||||
|
} else {
|
||||||
|
active.nodes = std.ArrayList(SyntaxNode).init(std.heap.page_allocator);
|
||||||
|
actives_nodes = active.nodes.?;
|
||||||
|
}
|
||||||
|
try actives_nodes.append(.{
|
||||||
|
.ctok = ctok,
|
||||||
|
.nodes = null,
|
||||||
|
});
|
||||||
|
} else {}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const lsp = @import("lsfw/src/lsp.zig");
|
||||||
|
|
||||||
|
pub const Token = struct {
|
||||||
|
/// 0-based index of token start in whole file
|
||||||
|
start: usize,
|
||||||
|
/// 1-based line numbert token starts at
|
||||||
|
line: usize,
|
||||||
|
/// 1-based char numbert token starts at in line
|
||||||
|
char: usize,
|
||||||
|
|
||||||
|
value: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const TokenizationError = error{InvalidKeyword};
|
||||||
|
|
||||||
|
pub fn tokenizeContent(content: []u8, allocator: std.mem.Allocator) !std.ArrayList(Token) {
|
||||||
|
var toks = std.ArrayList(Token).init(allocator);
|
||||||
|
var lines = std.ArrayList(usize).init(allocator);
|
||||||
|
defer lines.deinit();
|
||||||
|
|
||||||
|
var index: usize = 0;
|
||||||
|
while (index < content.len) {
|
||||||
|
var l: usize = 1;
|
||||||
|
const char = content[index];
|
||||||
|
_ = switch (char) {
|
||||||
|
'\n' => {
|
||||||
|
try lines.append(index);
|
||||||
|
index += l;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
';' => {
|
||||||
|
while (switch (content[index + l]) {
|
||||||
|
'\n' => false,
|
||||||
|
else => true,
|
||||||
|
}) : (l += 1) {}
|
||||||
|
},
|
||||||
|
'"' => {
|
||||||
|
while (switch (content[index + l]) {
|
||||||
|
'"' => (content[index + l - 1] == '\\'),
|
||||||
|
else => true,
|
||||||
|
}) : (l += 1) {}
|
||||||
|
l += 1;
|
||||||
|
},
|
||||||
|
'a'...'z', 'A'...'Z', '_' => {
|
||||||
|
while (switch (content[index + l]) {
|
||||||
|
'a'...'z', 'A'...'Z', '0'...'9', '_' => true,
|
||||||
|
else => false,
|
||||||
|
}) : (l += 1) {}
|
||||||
|
},
|
||||||
|
'0'...'9' => {
|
||||||
|
while (switch (content[index + l]) {
|
||||||
|
'0'...'9', '.', 'e' => true,
|
||||||
|
else => false,
|
||||||
|
}) : (l += 1) {}
|
||||||
|
},
|
||||||
|
'+', '-', '~', '*', '/', '%', '<', '>', '=', '?', '|', '&', '(', ')', '\'' => {
|
||||||
|
for ([_]*const [2]u8{ "->", "~>", "||", "&&", "/=", "*=", "+=", "-=", "'(" }) |op| {
|
||||||
|
if (std.mem.eql(u8, op, content[index .. index + 2])) {
|
||||||
|
l = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'@' => {
|
||||||
|
while (switch (content[index + l]) {
|
||||||
|
'a'...'z', 'A'...'Z', '_', '0'...'9' => true,
|
||||||
|
else => false,
|
||||||
|
}) : (l += 1) {}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, "@keys", content[index .. index + l])) {} else if (std.mem.eql(u8, "@rest", content[index .. index + l])) {} else {
|
||||||
|
std.debug.print("line={d}, char={d}\n", .{
|
||||||
|
.line = lines.items.len,
|
||||||
|
.char = switch (lines.items.len) {
|
||||||
|
0 => index,
|
||||||
|
else => index - lines.items[lines.items.len - 1],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
index += l;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
try toks.append(.{
|
||||||
|
.start = index,
|
||||||
|
.value = try allocator.dupe(u8, content[index .. index + l]),
|
||||||
|
.line = lines.items.len,
|
||||||
|
.char = switch (lines.items.len) {
|
||||||
|
0 => index,
|
||||||
|
else => index - lines.items[lines.items.len - 1],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
index += l;
|
||||||
|
}
|
||||||
|
lsp.logger.notify(.err, "done with initial tokenization, generated {d} tokens", .{toks.items.len});
|
||||||
|
return toks;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,272 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub const Token = struct {
|
||||||
|
tag: Tag,
|
||||||
|
loc: Loc,
|
||||||
|
|
||||||
|
pub const Loc = struct {
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Tag = enum {
|
||||||
|
sym,
|
||||||
|
num,
|
||||||
|
str,
|
||||||
|
/// t
|
||||||
|
t,
|
||||||
|
/// nil
|
||||||
|
nil,
|
||||||
|
/// =
|
||||||
|
assign,
|
||||||
|
/// -=
|
||||||
|
assign_sub,
|
||||||
|
/// /=
|
||||||
|
assign_div,
|
||||||
|
/// *=
|
||||||
|
assign_mul,
|
||||||
|
/// +=
|
||||||
|
assign_add,
|
||||||
|
/// ==
|
||||||
|
op_eq,
|
||||||
|
/// >
|
||||||
|
op_gt,
|
||||||
|
/// >=
|
||||||
|
op_geq,
|
||||||
|
/// <
|
||||||
|
op_lt,
|
||||||
|
/// <=
|
||||||
|
op_leq,
|
||||||
|
/// /
|
||||||
|
op_div,
|
||||||
|
/// *
|
||||||
|
op_mul,
|
||||||
|
/// +
|
||||||
|
op_add,
|
||||||
|
/// -
|
||||||
|
op_sub,
|
||||||
|
/// ->
|
||||||
|
op_acc,
|
||||||
|
/// ~>
|
||||||
|
op_derefacc,
|
||||||
|
/// %
|
||||||
|
op_mod,
|
||||||
|
/// !
|
||||||
|
op_not,
|
||||||
|
/// !=
|
||||||
|
op_neq,
|
||||||
|
/// ||
|
||||||
|
op_or,
|
||||||
|
/// &&
|
||||||
|
op_and,
|
||||||
|
/// (
|
||||||
|
list_l,
|
||||||
|
/// '(
|
||||||
|
list_lz,
|
||||||
|
/// )
|
||||||
|
list_r,
|
||||||
|
/// @keys
|
||||||
|
kw_keys,
|
||||||
|
/// @rest
|
||||||
|
kw_rest,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn format(self: *const Token, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
|
||||||
|
try writer.print("{d}:{d} .{s}", .{ self.loc.start, self.loc.end, @tagName(self.tag) });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Tokenizer = struct {
|
||||||
|
buffer: [:0]const u8,
|
||||||
|
index: usize,
|
||||||
|
start: usize,
|
||||||
|
|
||||||
|
const State = enum {
|
||||||
|
start,
|
||||||
|
alphanum_identifier,
|
||||||
|
number_or_float,
|
||||||
|
decimals,
|
||||||
|
signed_exponent,
|
||||||
|
unsigned_exponent,
|
||||||
|
string,
|
||||||
|
op_plus,
|
||||||
|
op_minus,
|
||||||
|
op_star,
|
||||||
|
op_fslash,
|
||||||
|
op_pipe,
|
||||||
|
op_amp,
|
||||||
|
op_excl,
|
||||||
|
op_deref,
|
||||||
|
op_eq,
|
||||||
|
list_l,
|
||||||
|
list_lz,
|
||||||
|
list_r,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init(buf: [:0]const u8) Tokenizer {
|
||||||
|
return .{
|
||||||
|
.buffer = buf,
|
||||||
|
.index = 0,
|
||||||
|
.start = 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(self: *Tokenizer) ?Token {
|
||||||
|
var state: State = .start;
|
||||||
|
while (self.index < self.buffer.len) : (self.index += 1) {
|
||||||
|
const c = self.buffer[self.index];
|
||||||
|
const loc = Token.Loc{ .start = self.start, .end = self.index };
|
||||||
|
state = switch (state) {
|
||||||
|
.start => blk: {
|
||||||
|
self.start = self.index;
|
||||||
|
break :blk switch (c) {
|
||||||
|
'a'...'z', 'A'...'Z', '_' => .alphanum_identifier,
|
||||||
|
'0'...'9' => .number_or_float,
|
||||||
|
'.' => .decimals,
|
||||||
|
'"' => .string,
|
||||||
|
'+' => .op_plus,
|
||||||
|
'-' => .op_minus,
|
||||||
|
'*' => .op_star,
|
||||||
|
'/' => .op_fslash,
|
||||||
|
'|' => .op_pipe,
|
||||||
|
'&' => .op_amp,
|
||||||
|
'!' => .op_excl,
|
||||||
|
'~' => .op_deref,
|
||||||
|
'=' => .op_eq,
|
||||||
|
'(' => .list_l,
|
||||||
|
')' => .list_r,
|
||||||
|
'\'' => .list_lz,
|
||||||
|
else => .start,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.alphanum_identifier => switch (c) {
|
||||||
|
'a'...'z', 'A'...'Z', '0'...'9', '_' => .alphanum_identifier,
|
||||||
|
else => {
|
||||||
|
inline for (.{ Token.Tag.t, Token.Tag.nil }) |alphanum_tag| {
|
||||||
|
if (std.mem.eql(u8, self.buffer[self.start..self.index], @tagName(alphanum_tag))) {
|
||||||
|
return Token{ .tag = alphanum_tag, .loc = loc };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Token{ .tag = .sym, .loc = loc };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.number_or_float => switch (c) {
|
||||||
|
'0'...'9' => .number_or_float,
|
||||||
|
'.' => .decimals,
|
||||||
|
'e' => .signed_exponent,
|
||||||
|
' ', '\n' => {
|
||||||
|
return Token{ .tag = .num, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.decimals => switch (c) {
|
||||||
|
'0'...'9' => .decimals,
|
||||||
|
' ', '\n' => {
|
||||||
|
return Token{ .tag = .num, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.signed_exponent => switch (c) {
|
||||||
|
'0'...'9', '+', '-' => .unsigned_exponent,
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.unsigned_exponent => switch (c) {
|
||||||
|
'0'...'9' => .unsigned_exponent,
|
||||||
|
' ', '\n' => {
|
||||||
|
return Token{ .tag = .num, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.string => switch (c) {
|
||||||
|
'"' => {
|
||||||
|
return Token{ .tag = .str, .loc = loc };
|
||||||
|
},
|
||||||
|
'\\' => blk: {
|
||||||
|
self.index += 1;
|
||||||
|
break :blk .string;
|
||||||
|
},
|
||||||
|
else => .string,
|
||||||
|
},
|
||||||
|
.op_plus, .op_minus, .op_fslash, .op_star, .op_excl, .op_eq => switch (c) {
|
||||||
|
'=' => {
|
||||||
|
return Token{ .tag = switch (state) {
|
||||||
|
.op_plus => .assign_add,
|
||||||
|
.op_minus => .assign_sub,
|
||||||
|
.op_star => .assign_mul,
|
||||||
|
.op_fslash => .assign_div,
|
||||||
|
.op_excl => .op_neq,
|
||||||
|
.op_eq => .op_eq,
|
||||||
|
else => unreachable,
|
||||||
|
}, .loc = loc };
|
||||||
|
},
|
||||||
|
' ', '\n' => {
|
||||||
|
return Token{ .tag = switch (state) {
|
||||||
|
.op_plus => .op_add,
|
||||||
|
.op_minus => .op_sub,
|
||||||
|
.op_star => .op_mul,
|
||||||
|
.op_fslash => .op_div,
|
||||||
|
.op_excl => .op_not,
|
||||||
|
.op_eq => .assign,
|
||||||
|
else => unreachable,
|
||||||
|
}, .loc = loc };
|
||||||
|
},
|
||||||
|
'>' => {
|
||||||
|
return Token{ .tag = switch (state) {
|
||||||
|
.op_minus => .op_acc,
|
||||||
|
else => unreachable,
|
||||||
|
}, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.op_pipe => switch (c) {
|
||||||
|
'|' => {
|
||||||
|
return Token{ .tag = .op_or, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.op_amp => switch (c) {
|
||||||
|
'&' => {
|
||||||
|
return Token{ .tag = .op_and, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.op_deref => switch (c) {
|
||||||
|
'>' => {
|
||||||
|
return Token{ .tag = .op_derefacc, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
.list_l => {
|
||||||
|
return Token{ .tag = .list_l, .loc = loc };
|
||||||
|
},
|
||||||
|
.list_r => {
|
||||||
|
return Token{ .tag = .list_r, .loc = loc };
|
||||||
|
},
|
||||||
|
.list_lz => switch (c) {
|
||||||
|
'(' => {
|
||||||
|
return Token{ .tag = .op_derefacc, .loc = loc };
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
test "simple tokenization" {
|
||||||
|
const example =
|
||||||
|
\\t
|
||||||
|
\\nil
|
||||||
|
\\a = b
|
||||||
|
\\"some string w/ escaped\""
|
||||||
|
;
|
||||||
|
|
||||||
|
var tokz = Tokenizer.init(example);
|
||||||
|
try std.testing.expectEqual(Token{ .loc = .{ .start = 0, .end = 1 }, .tag = .t }, tokz.next());
|
||||||
|
try std.testing.expectEqual(Token{ .loc = .{ .start = 2, .end = 5 }, .tag = .nil }, tokz.next());
|
||||||
|
try std.testing.expectEqual(Token{ .loc = .{ .start = 6, .end = 7 }, .tag = .sym }, tokz.next());
|
||||||
|
try std.testing.expectEqual(Token{ .loc = .{ .start = 8, .end = 9 }, .tag = .assign }, tokz.next());
|
||||||
|
try std.testing.expectEqual(Token{ .loc = .{ .start = 10, .end = 11 }, .tag = .sym }, tokz.next());
|
||||||
|
try std.testing.expectEqual(Token{ .loc = .{ .start = 12, .end = 37 }, .tag = .str }, tokz.next());
|
||||||
|
}
|
||||||
40
todo.md
40
todo.md
|
|
@ -1,40 +0,0 @@
|
||||||
# TODOs
|
|
||||||
|
|
||||||
- [x] Paren pair parsing
|
|
||||||
- iterative parsing and matching of paren/bracket pairs
|
|
||||||
- [ ] tokenizer
|
|
||||||
- identify "tokens"
|
|
||||||
- everythin is a token with exception of:
|
|
||||||
- operators
|
|
||||||
- parens/brackets
|
|
||||||
- numbers
|
|
||||||
- t / nil
|
|
||||||
- comments (maybe already handled)
|
|
||||||
- [ ] namespaces / scopes
|
|
||||||
- namespaces are started with:
|
|
||||||
- let / letseq / let...
|
|
||||||
|
|
||||||
```skill
|
|
||||||
; let[T]( locals: list[tuple[symbol, Any] | symbol] | nil, *exprs: Any, last_expr: T) -> T
|
|
||||||
```
|
|
||||||
|
|
||||||
- prog
|
|
||||||
|
|
||||||
```skill
|
|
||||||
; prog( locals: list[symbol] | nil, *exprs: Any) -> Any
|
|
||||||
```
|
|
||||||
|
|
||||||
- procedure
|
|
||||||
|
|
||||||
```skill
|
|
||||||
; function_name(req_param: Any, key_param1: any = value_param2) => Any
|
|
||||||
procedure( function_name(req_param @keys (key_param1 value_param2))
|
|
||||||
...
|
|
||||||
)
|
|
||||||
|
|
||||||
function_name(<req_arg> ?key_param1 <value_param2>)
|
|
||||||
```
|
|
||||||
|
|
||||||
- [ ] token contextualization
|
|
||||||
- looks for declaration / definition of symbol
|
|
||||||
|
|
||||||
360
uv.lock
360
uv.lock
|
|
@ -1,360 +0,0 @@
|
||||||
version = 1
|
|
||||||
revision = 2
|
|
||||||
requires-python = ">=3.13"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "attrs"
|
|
||||||
version = "24.3.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/48/c8/6260f8ccc11f0917360fc0da435c5c9c7504e3db174d5a12a1494887b045/attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", size = 805984, upload-time = "2024-12-16T06:59:29.899Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397, upload-time = "2024-12-16T06:59:26.977Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "black"
|
|
||||||
version = "24.10.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "click" },
|
|
||||||
{ name = "mypy-extensions" },
|
|
||||||
{ name = "packaging" },
|
|
||||||
{ name = "pathspec" },
|
|
||||||
{ name = "platformdirs" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813, upload-time = "2024-10-07T19:20:50.361Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d0/a0/a993f58d4ecfba035e61fca4e9f64a2ecae838fc9f33ab798c62173ed75c/black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981", size = 1643986, upload-time = "2024-10-07T19:28:50.684Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/37/d5/602d0ef5dfcace3fb4f79c436762f130abd9ee8d950fa2abdbf8bbc555e0/black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b", size = 1448085, upload-time = "2024-10-07T19:28:12.093Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/6d/a3a239e938960df1a662b93d6230d4f3e9b4a22982d060fc38c42f45a56b/black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2", size = 1760928, upload-time = "2024-10-07T19:24:15.233Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dd/cf/af018e13b0eddfb434df4d9cd1b2b7892bab119f7a20123e93f6910982e8/black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b", size = 1436875, upload-time = "2024-10-07T19:24:42.762Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898, upload-time = "2024-10-07T19:20:48.317Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cattrs"
|
|
||||||
version = "24.1.2"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "attrs" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/64/65/af6d57da2cb32c076319b7489ae0958f746949d407109e3ccf4d115f147c/cattrs-24.1.2.tar.gz", hash = "sha256:8028cfe1ff5382df59dd36474a86e02d817b06eaf8af84555441bac915d2ef85", size = 426462, upload-time = "2024-09-22T14:58:36.377Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c8/d5/867e75361fc45f6de75fe277dd085627a9db5ebb511a87f27dc1396b5351/cattrs-24.1.2-py3-none-any.whl", hash = "sha256:67c7495b760168d931a10233f979b28dc04daf853b30752246f4f8471c6d68d0", size = 66446, upload-time = "2024-09-22T14:58:34.812Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "click"
|
|
||||||
version = "8.1.8"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "colorama"
|
|
||||||
version = "0.4.6"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "iniconfig"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lsprotocol"
|
|
||||||
version = "2025.0.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "attrs" },
|
|
||||||
{ name = "cattrs" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/e9/26/67b84e6ec1402f0e6764ef3d2a0aaf9a79522cc1d37738f4e5bb0b21521a/lsprotocol-2025.0.0.tar.gz", hash = "sha256:e879da2b9301e82cfc3e60d805630487ac2f7ab17492f4f5ba5aaba94fe56c29", size = 74896, upload-time = "2025-06-17T21:30:18.156Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/7b/f0/92f2d609d6642b5f30cb50a885d2bf1483301c69d5786286500d15651ef2/lsprotocol-2025.0.0-py3-none-any.whl", hash = "sha256:f9d78f25221f2a60eaa4a96d3b4ffae011b107537facee61d3da3313880995c7", size = 76250, upload-time = "2025-06-17T21:30:19.455Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "markdown-it-py"
|
|
||||||
version = "3.0.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "mdurl" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mdurl"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mypy"
|
|
||||||
version = "1.14.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "mypy-extensions" },
|
|
||||||
{ name = "typing-extensions" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051, upload-time = "2024-12-30T16:39:07.335Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097, upload-time = "2024-12-30T16:37:25.144Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728, upload-time = "2024-12-30T16:38:08.634Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965, upload-time = "2024-12-30T16:38:12.132Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660, upload-time = "2024-12-30T16:38:17.342Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198, upload-time = "2024-12-30T16:38:32.839Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276, upload-time = "2024-12-30T16:38:20.828Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905, upload-time = "2024-12-30T16:38:42.021Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mypy-extensions"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "packaging"
|
|
||||||
version = "24.2"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parsimonious"
|
|
||||||
version = "0.10.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "regex" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/7b/91/abdc50c4ef06fdf8d047f60ee777ca9b2a7885e1a9cea81343fbecda52d7/parsimonious-0.10.0.tar.gz", hash = "sha256:8281600da180ec8ae35427a4ab4f7b82bfec1e3d1e52f80cb60ea82b9512501c", size = 52172, upload-time = "2022-09-03T17:01:17.004Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/aa/0f/c8b64d9b54ea631fcad4e9e3c8dbe8c11bb32a623be94f22974c88e71eaf/parsimonious-0.10.0-py3-none-any.whl", hash = "sha256:982ab435fabe86519b57f6b35610aa4e4e977e9f02a14353edf4bbc75369fc0f", size = 48427, upload-time = "2022-09-03T17:01:13.814Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pathspec"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "platformdirs"
|
|
||||||
version = "4.3.6"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302, upload-time = "2024-09-17T19:06:50.688Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439, upload-time = "2024-09-17T19:06:49.212Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pluggy"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pygls"
|
|
||||||
version = "2.0.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "attrs" },
|
|
||||||
{ name = "cattrs" },
|
|
||||||
{ name = "lsprotocol" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/87/50/2bfc32f3acbc8941042919b59c9f592291127b55d7331b72e67ce7b62f08/pygls-2.0.0.tar.gz", hash = "sha256:99accd03de1ca76fe1e7e317f0968ebccf7b9955afed6e2e3e188606a20b4f07", size = 55796, upload-time = "2025-10-17T19:22:47.925Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/09/14feafc13bebb9c85b29b374889c1549d3700cb572f2d43a1bb940d70315/pygls-2.0.0-py3-none-any.whl", hash = "sha256:b4e54bba806f76781017ded8fd07463b98670f959042c44170cd362088b200cc", size = 69533, upload-time = "2025-10-17T19:22:46.63Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pygments"
|
|
||||||
version = "2.19.1"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pytest"
|
|
||||||
version = "8.3.4"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
||||||
{ name = "iniconfig" },
|
|
||||||
{ name = "packaging" },
|
|
||||||
{ name = "pluggy" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919, upload-time = "2024-12-01T12:54:25.98Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083, upload-time = "2024-12-01T12:54:19.735Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "regex"
|
|
||||||
version = "2024.11.6"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/8e/5f/bd69653fbfb76cf8604468d3b4ec4c403197144c7bfe0e6a5fc9e02a07cb/regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519", size = 399494, upload-time = "2024-11-06T20:12:31.635Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/90/73/bcb0e36614601016552fa9344544a3a2ae1809dc1401b100eab02e772e1f/regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84", size = 483525, upload-time = "2024-11-06T20:10:45.19Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0f/3f/f1a082a46b31e25291d830b369b6b0c5576a6f7fb89d3053a354c24b8a83/regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4", size = 288324, upload-time = "2024-11-06T20:10:47.177Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/09/c9/4e68181a4a652fb3ef5099e077faf4fd2a694ea6e0f806a7737aff9e758a/regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0", size = 284617, upload-time = "2024-11-06T20:10:49.312Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fc/fd/37868b75eaf63843165f1d2122ca6cb94bfc0271e4428cf58c0616786dce/regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0", size = 795023, upload-time = "2024-11-06T20:10:51.102Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c4/7c/d4cd9c528502a3dedb5c13c146e7a7a539a3853dc20209c8e75d9ba9d1b2/regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7", size = 833072, upload-time = "2024-11-06T20:10:52.926Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/4f/db/46f563a08f969159c5a0f0e722260568425363bea43bb7ae370becb66a67/regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7", size = 823130, upload-time = "2024-11-06T20:10:54.828Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/db/60/1eeca2074f5b87df394fccaa432ae3fc06c9c9bfa97c5051aed70e6e00c2/regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c", size = 796857, upload-time = "2024-11-06T20:10:56.634Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/10/db/ac718a08fcee981554d2f7bb8402f1faa7e868c1345c16ab1ebec54b0d7b/regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3", size = 784006, upload-time = "2024-11-06T20:10:59.369Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c2/41/7da3fe70216cea93144bf12da2b87367590bcf07db97604edeea55dac9ad/regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07", size = 781650, upload-time = "2024-11-06T20:11:02.042Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a7/d5/880921ee4eec393a4752e6ab9f0fe28009435417c3102fc413f3fe81c4e5/regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e", size = 789545, upload-time = "2024-11-06T20:11:03.933Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/96/53770115e507081122beca8899ab7f5ae28ae790bfcc82b5e38976df6a77/regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6", size = 853045, upload-time = "2024-11-06T20:11:06.497Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/31/d3/1372add5251cc2d44b451bd94f43b2ec78e15a6e82bff6a290ef9fd8f00a/regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4", size = 860182, upload-time = "2024-11-06T20:11:09.06Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ed/e3/c446a64984ea9f69982ba1a69d4658d5014bc7a0ea468a07e1a1265db6e2/regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d", size = 787733, upload-time = "2024-11-06T20:11:11.256Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2b/f1/e40c8373e3480e4f29f2692bd21b3e05f296d3afebc7e5dcf21b9756ca1c/regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff", size = 262122, upload-time = "2024-11-06T20:11:13.161Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/45/94/bc295babb3062a731f52621cdc992d123111282e291abaf23faa413443ea/regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a", size = 273545, upload-time = "2024-11-06T20:11:15Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rich"
|
|
||||||
version = "13.9.4"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "markdown-it-py" },
|
|
||||||
{ name = "pygments" },
|
|
||||||
]
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149, upload-time = "2024-11-01T16:43:57.873Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424, upload-time = "2024-11-01T16:43:55.817Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ruff"
|
|
||||||
version = "0.9.2"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/80/63/77ecca9d21177600f551d1c58ab0e5a0b260940ea7312195bd2a4798f8a8/ruff-0.9.2.tar.gz", hash = "sha256:b5eceb334d55fae5f316f783437392642ae18e16dcf4f1858d55d3c2a0f8f5d0", size = 3553799, upload-time = "2025-01-16T13:22:20.512Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/b9/0e168e4e7fb3af851f739e8f07889b91d1a33a30fca8c29fa3149d6b03ec/ruff-0.9.2-py3-none-linux_armv6l.whl", hash = "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347", size = 11652408, upload-time = "2025-01-16T13:21:12.732Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2c/22/08ede5db17cf701372a461d1cb8fdde037da1d4fa622b69ac21960e6237e/ruff-0.9.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00", size = 11587553, upload-time = "2025-01-16T13:21:17.716Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/42/05/dedfc70f0bf010230229e33dec6e7b2235b2a1b8cbb2a991c710743e343f/ruff-0.9.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fbd337bac1cfa96be615f6efcd4bc4d077edbc127ef30e2b8ba2a27e18c054d4", size = 11020755, upload-time = "2025-01-16T13:21:21.746Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/9b/65d87ad9b2e3def67342830bd1af98803af731243da1255537ddb8f22209/ruff-0.9.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b35259b0cbf8daa22a498018e300b9bb0174c2bbb7bcba593935158a78054d", size = 11826502, upload-time = "2025-01-16T13:21:26.135Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/93/02/f2239f56786479e1a89c3da9bc9391120057fc6f4a8266a5b091314e72ce/ruff-0.9.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b6a9701d1e371bf41dca22015c3f89769da7576884d2add7317ec1ec8cb9c3c", size = 11390562, upload-time = "2025-01-16T13:21:29.026Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c9/37/d3a854dba9931f8cb1b2a19509bfe59e00875f48ade632e95aefcb7a0aee/ruff-0.9.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9cc53e68b3c5ae41e8faf83a3b89f4a5d7b2cb666dff4b366bb86ed2a85b481f", size = 12548968, upload-time = "2025-01-16T13:21:34.147Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fa/c3/c7b812bb256c7a1d5553433e95980934ffa85396d332401f6b391d3c4569/ruff-0.9.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8efd9da7a1ee314b910da155ca7e8953094a7c10d0c0a39bfde3fcfd2a015684", size = 13187155, upload-time = "2025-01-16T13:21:40.494Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/bd/5a/3c7f9696a7875522b66aa9bba9e326e4e5894b4366bd1dc32aa6791cb1ff/ruff-0.9.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3292c5a22ea9a5f9a185e2d131dc7f98f8534a32fb6d2ee7b9944569239c648d", size = 12704674, upload-time = "2025-01-16T13:21:45.041Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/be/d6/d908762257a96ce5912187ae9ae86792e677ca4f3dc973b71e7508ff6282/ruff-0.9.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a605fdcf6e8b2d39f9436d343d1f0ff70c365a1e681546de0104bef81ce88df", size = 14529328, upload-time = "2025-01-16T13:21:49.45Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/2d/c2/049f1e6755d12d9cd8823242fa105968f34ee4c669d04cac8cea51a50407/ruff-0.9.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c547f7f256aa366834829a08375c297fa63386cbe5f1459efaf174086b564247", size = 12385955, upload-time = "2025-01-16T13:21:52.71Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/91/5a/a9bdb50e39810bd9627074e42743b00e6dc4009d42ae9f9351bc3dbc28e7/ruff-0.9.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d18bba3d3353ed916e882521bc3e0af403949dbada344c20c16ea78f47af965e", size = 11810149, upload-time = "2025-01-16T13:21:57.098Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/e5/fd/57df1a0543182f79a1236e82a79c68ce210efb00e97c30657d5bdb12b478/ruff-0.9.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b338edc4610142355ccf6b87bd356729b62bf1bc152a2fad5b0c7dc04af77bfe", size = 11479141, upload-time = "2025-01-16T13:22:00.585Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/16/bc3fd1d38974f6775fc152a0554f8c210ff80f2764b43777163c3c45d61b/ruff-0.9.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:492a5e44ad9b22a0ea98cf72e40305cbdaf27fac0d927f8bc9e1df316dcc96eb", size = 12014073, upload-time = "2025-01-16T13:22:03.956Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/47/6b/e4ca048a8f2047eb652e1e8c755f384d1b7944f69ed69066a37acd4118b0/ruff-0.9.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af1e9e9fe7b1f767264d26b1075ac4ad831c7db976911fa362d09b2d0356426a", size = 12435758, upload-time = "2025-01-16T13:22:07.73Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c2/40/4d3d6c979c67ba24cf183d29f706051a53c36d78358036a9cd21421582ab/ruff-0.9.2-py3-none-win32.whl", hash = "sha256:71cbe22e178c5da20e1514e1e01029c73dc09288a8028a5d3446e6bba87a5145", size = 9796916, upload-time = "2025-01-16T13:22:10.894Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/c3/ef/7f548752bdb6867e6939489c87fe4da489ab36191525fadc5cede2a6e8e2/ruff-0.9.2-py3-none-win_amd64.whl", hash = "sha256:c5e1d6abc798419cf46eed03f54f2e0c3adb1ad4b801119dedf23fcaf69b55b5", size = 10773080, upload-time = "2025-01-16T13:22:14.155Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/4e/33df635528292bd2d18404e4daabcd74ca8a9853b2e1df85ed3d32d24362/ruff-0.9.2-py3-none-win_arm64.whl", hash = "sha256:a1b63fa24149918f8b37cef2ee6fff81f24f0d74b6f0bdc37bc3e1f2143e41c6", size = 10001738, upload-time = "2025-01-16T13:22:18.121Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "skillls"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = { editable = "." }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "parsimonious" },
|
|
||||||
{ name = "pygls" },
|
|
||||||
{ name = "rich" },
|
|
||||||
{ name = "tree-sitter" },
|
|
||||||
{ name = "tree-sitter-skill" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.optional-dependencies]
|
|
||||||
dev = [
|
|
||||||
{ name = "black" },
|
|
||||||
{ name = "mypy" },
|
|
||||||
{ name = "pytest" },
|
|
||||||
{ name = "ruff" },
|
|
||||||
{ name = "types-parsimonious" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.metadata]
|
|
||||||
requires-dist = [
|
|
||||||
{ name = "black", marker = "extra == 'dev'" },
|
|
||||||
{ name = "mypy", marker = "extra == 'dev'" },
|
|
||||||
{ name = "parsimonious", specifier = "~=0.10.0" },
|
|
||||||
{ name = "pygls", specifier = "~=2.0" },
|
|
||||||
{ name = "pytest", marker = "extra == 'dev'" },
|
|
||||||
{ name = "rich" },
|
|
||||||
{ name = "ruff", marker = "extra == 'dev'" },
|
|
||||||
{ name = "tree-sitter", specifier = ">=0.24.0" },
|
|
||||||
{ name = "tree-sitter-skill", git = "ssh://git@git.acereca.net/acereca/tree-sitter-skill.git" },
|
|
||||||
{ name = "types-parsimonious", marker = "extra == 'dev'" },
|
|
||||||
]
|
|
||||||
provides-extras = ["dev"]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tree-sitter"
|
|
||||||
version = "0.24.0"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/a7/a2/698b9d31d08ad5558f8bfbfe3a0781bd4b1f284e89bde3ad18e05101a892/tree-sitter-0.24.0.tar.gz", hash = "sha256:abd95af65ca2f4f7eca356343391ed669e764f37748b5352946f00f7fc78e734", size = 168304, upload-time = "2025-01-17T05:06:38.115Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/61/cd/2348339c85803330ce38cee1c6cbbfa78a656b34ff58606ebaf5c9e83bd0/tree_sitter-0.24.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0d4a6416ed421c4210f0ca405a4834d5ccfbb8ad6692d4d74f7773ef68f92071", size = 140781, upload-time = "2025-01-17T05:06:22.82Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/a3/1ea9d8b64e8dcfcc0051028a9c84a630301290995cd6e947bf88267ef7b1/tree_sitter-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0992d483677e71d5c5d37f30dfb2e3afec2f932a9c53eec4fca13869b788c6c", size = 133928, upload-time = "2025-01-17T05:06:25.146Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/fe/ae/55c1055609c9428a4aedf4b164400ab9adb0b1bf1538b51f4b3748a6c983/tree_sitter-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57277a12fbcefb1c8b206186068d456c600dbfbc3fd6c76968ee22614c5cd5ad", size = 564497, upload-time = "2025-01-17T05:06:27.53Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/ce/d0/f2ffcd04882c5aa28d205a787353130cbf84b2b8a977fd211bdc3b399ae3/tree_sitter-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25fa22766d63f73716c6fec1a31ee5cf904aa429484256bd5fdf5259051ed74", size = 578917, upload-time = "2025-01-17T05:06:31.057Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/82/aebe78ea23a2b3a79324993d4915f3093ad1af43d7c2208ee90be9273273/tree_sitter-0.24.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7d5d9537507e1c8c5fa9935b34f320bfec4114d675e028f3ad94f11cf9db37b9", size = 581148, upload-time = "2025-01-17T05:06:32.409Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a1/b4/6b0291a590c2b0417cfdb64ccb8ea242f270a46ed429c641fbc2bfab77e0/tree_sitter-0.24.0-cp313-cp313-win_amd64.whl", hash = "sha256:f58bb4956917715ec4d5a28681829a8dad5c342cafd4aea269f9132a83ca9b34", size = 120207, upload-time = "2025-01-17T05:06:34.841Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a8/18/542fd844b75272630229c9939b03f7db232c71a9d82aadc59c596319ea6a/tree_sitter-0.24.0-cp313-cp313-win_arm64.whl", hash = "sha256:23641bd25dcd4bb0b6fa91b8fb3f46cc9f1c9f475efe4d536d3f1f688d1b84c8", size = 108232, upload-time = "2025-01-17T05:06:35.831Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "tree-sitter-skill"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = { git = "ssh://git@git.acereca.net/acereca/tree-sitter-skill.git#ce8634713b13f1787837fd9a7c515383ecedac07" }
|
|
||||||
dependencies = [
|
|
||||||
{ name = "tree-sitter" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "types-parsimonious"
|
|
||||||
version = "0.10.0.20240331"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/11/8a/3e0f5d72ea35bc5fba64899fca45124a4398c78e28c40a3e119f15882d35/types-parsimonious-0.10.0.20240331.tar.gz", hash = "sha256:c9ca50c968b83203a285ee8fbe4a50c5aa6d8ca903d92802ee5398cb95608ceb", size = 5482, upload-time = "2024-03-31T02:17:49.591Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/b5/fe/f6f9b4ec9c4cd0c567bcd581d65795bb07b0613fe3d15b249af348efa42a/types_parsimonious-0.10.0.20240331-py3-none-any.whl", hash = "sha256:6828faa2b74c03d229d2ea5b661a9de47589a837fec48424804c42b9113a28cd", size = 6308, upload-time = "2024-03-31T02:17:48.098Z" },
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typing-extensions"
|
|
||||||
version = "4.12.2"
|
|
||||||
source = { registry = "https://pypi.org/simple" }
|
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" }
|
|
||||||
wheels = [
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" },
|
|
||||||
]
|
|
||||||
Loading…
Reference in New Issue