Initial parse/read driver REPL
This commit is contained in:
parent
7b2291b151
commit
0b7b67b797
9 changed files with 178 additions and 0 deletions
35
projects/shogoth/BUILD
Normal file
35
projects/shogoth/BUILD
Normal file
|
@ -0,0 +1,35 @@
|
|||
py_library(
|
||||
name = "lib",
|
||||
srcs = glob(["src/python/**/*"]),
|
||||
imports = [
|
||||
"src/python"
|
||||
],
|
||||
deps = [
|
||||
py_requirement("lark"),
|
||||
],
|
||||
)
|
||||
|
||||
zapp_binary(
|
||||
name = "shogothd",
|
||||
main = "src/python/shogoth/server/__main__.py",
|
||||
deps = [
|
||||
":lib",
|
||||
],
|
||||
)
|
||||
|
||||
zapp_binary(
|
||||
name = "shogoth",
|
||||
main = "src/python/shogoth/client/__main__.py",
|
||||
deps = [
|
||||
":lib",
|
||||
],
|
||||
)
|
||||
|
||||
zapp_binary(
|
||||
name = "repl",
|
||||
main = "src/python/shogoth/repl/__main__.py",
|
||||
shebang = "/usr/bin/env python3.10",
|
||||
deps = [
|
||||
":lib",
|
||||
]
|
||||
)
|
9
projects/shogoth/README.md
Normal file
9
projects/shogoth/README.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Shogot'im
|
||||
|
||||
> "The shoggot'im, they're called: servitors. There are several kinds of advanced robotic systems made out of molecular components: they can change shape, restructure material at the atomic level -- act like corrosive acid, or secrete diamonds. Some of them are like a tenuous mist -- what Doctor Drexler at MIT calls a utility fog -- while others are more like an oily globule. Apparently they may be able to manufacture more of themselves, but they're not really alive in any meaning of the term we're familiar with. They're programmable, like robots, using a command language deduced from recovered records of the forerunners who left them here. The Molotov Raid of 1930 brought back a large consignment of them; all we have to go on are the scraps they missed, and reports by the Antarctic Survey. Professor Liebkunst's files in particular are most frustrating --''
|
||||
>
|
||||
> ~ Charlie Stross, "A Colder War"
|
||||
|
||||
## License
|
||||
|
||||
While the source for this project happens to be published no grant of rights is made.
|
0
projects/shogoth/src/python/shogoth/client/__main__.py
Normal file
0
projects/shogoth/src/python/shogoth/client/__main__.py
Normal file
6
projects/shogoth/src/python/shogoth/parser/__init__.py
Normal file
6
projects/shogoth/src/python/shogoth/parser/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
"""Published interface to the shogoth parser."""
|
||||
|
||||
from .impl import parse
|
||||
|
||||
|
||||
__all__ = ["parse"]
|
44
projects/shogoth/src/python/shogoth/parser/impl.py
Normal file
44
projects/shogoth/src/python/shogoth/parser/impl.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
"""A quick and dirty parser for Shogoth."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from lark import Lark
|
||||
|
||||
|
||||
PARSER = Lark('''\
|
||||
start: expr
|
||||
expr: plist | blist | mapping | quote | atom
|
||||
|
||||
plist: "(" expr* ")" // paren list
|
||||
blist: "[" expr* "]" // brackets list
|
||||
mapping: "{" kv* "}"
|
||||
kv: expr expr
|
||||
quote: "'" expr
|
||||
|
||||
atom: KEYWORD | PATTERN | INT | FLOAT | STRING | true | false | nil | SYMBOL
|
||||
KEYWORD: ":" SYMBOL
|
||||
SYMBOL: /[^(){}#'"\s]+/
|
||||
|
||||
STRING: /".*?"/
|
||||
PATTERN: /\/.*?\//
|
||||
|
||||
true: TRUE
|
||||
TRUE: /true/
|
||||
false: FALSE
|
||||
FALSE: /false/
|
||||
nil: NIL
|
||||
NIL: /nil/
|
||||
INT: /[+-]?[0-9]+/
|
||||
|
||||
%import common.WORD // imports from terminal library
|
||||
%import common.FLOAT // float
|
||||
%ignore " " // Disregard spaces in text
|
||||
%ignore "," // Treat commas as whitespace
|
||||
%ignore /;.*/ // Disregard comments
|
||||
''', start=["expr"])
|
||||
|
||||
|
||||
def parse(input: str) -> Any:
|
||||
"""Parse a string using the shogoth (lisp) gramar, returning an unmodified tree."""
|
||||
|
||||
return PARSER.parse(input)
|
5
projects/shogoth/src/python/shogoth/reader/__init__.py
Normal file
5
projects/shogoth/src/python/shogoth/reader/__init__.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from .impl import Reader
|
||||
|
||||
__all__ = ["Reader"]
|
66
projects/shogoth/src/python/shogoth/reader/impl.py
Normal file
66
projects/shogoth/src/python/shogoth/reader/impl.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
"""The shogoth reader."""
|
||||
|
||||
|
||||
from typing import Any
|
||||
from shogoth.parser import parse
|
||||
|
||||
from lark import Tree, Token
|
||||
from lark import Lark, Transformer, v_args
|
||||
|
||||
# Monkeypatching for py3.10 matching
|
||||
Tree.__match_args__ = ("data", "children")
|
||||
Token.__match_args__ = ("type", "value")
|
||||
|
||||
|
||||
class Reader(object):
|
||||
"""An extension of parsing that produces meaningful trees. Can be extended with userland hooks."""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _parse(self, buffer):
|
||||
return parse(buffer)
|
||||
|
||||
def symbol(self, x):
|
||||
return ["read-eval", ["symbol", x]]
|
||||
|
||||
def keyword(self, x):
|
||||
return ["read-eval", ["keyword", x]]
|
||||
|
||||
def _read(self, tree: Tree) -> Any:
|
||||
match tree:
|
||||
case Tree(Token('RULE', 'expr'), children):
|
||||
return self._read(children[0])
|
||||
|
||||
case Tree(Token('RULE', 'plist'), children):
|
||||
return [self._read(c) for c in children]
|
||||
|
||||
case Tree(Token('RULE', 'blist'), children):
|
||||
return [self._read(c) for c in children]
|
||||
|
||||
case Tree(Token('RULE', 'mapping'), children):
|
||||
return dict(self._read(c) for c in children)
|
||||
|
||||
case Tree(Token('RULE', 'kv'), [k, v]):
|
||||
return (self._read(k), self._read(v))
|
||||
|
||||
case Tree(Token('RULE', 'atom'), [a]):
|
||||
return self._read(a)
|
||||
|
||||
case Token('INT', x):
|
||||
return int(x)
|
||||
|
||||
case Token('FLOAT', x):
|
||||
return float(x)
|
||||
|
||||
case Token('KEYWORD', x):
|
||||
return self.keyword(x)
|
||||
|
||||
case Token('SYMBOL', x):
|
||||
return self.symbol(x)
|
||||
|
||||
case _:
|
||||
return tree
|
||||
|
||||
def read(self, buffer):
|
||||
return self._read(self._parse(buffer))
|
13
projects/shogoth/src/python/shogoth/repl/__main__.py
Normal file
13
projects/shogoth/src/python/shogoth/repl/__main__.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
"""A testing REPL."""
|
||||
|
||||
import sys
|
||||
|
||||
from shogoth.parser import parse
|
||||
from shogoth.reader import Reader
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
reader = Reader()
|
||||
while (line := input(">>> ")):
|
||||
read = reader.read(line)
|
||||
print(read, type(read))
|
0
projects/shogoth/src/python/shogoth/server/__main__.py
Normal file
0
projects/shogoth/src/python/shogoth/server/__main__.py
Normal file
Loading…
Reference in a new issue