Reader's 'done'
This commit is contained in:
parent
0b7b67b797
commit
df9aae1253
7 changed files with 60 additions and 23 deletions
|
@ -15,22 +15,19 @@ mapping: "{" kv* "}"
|
||||||
kv: expr expr
|
kv: expr expr
|
||||||
quote: "'" expr
|
quote: "'" expr
|
||||||
|
|
||||||
atom: KEYWORD | PATTERN | INT | FLOAT | STRING | true | false | nil | SYMBOL
|
atom: KEYWORD | PATTERN | INT | FLOAT | STRING | TRUE | FALSE | NIL | SYMBOL
|
||||||
KEYWORD: ":" SYMBOL
|
KEYWORD: ":" SYMBOL
|
||||||
SYMBOL: /[^(){}#'"\s]+/
|
SYMBOL: /[^(){}#'"\s]+/
|
||||||
|
|
||||||
|
// FIXME: These two don't deal with escapes correctly at all
|
||||||
STRING: /".*?"/
|
STRING: /".*?"/
|
||||||
PATTERN: /\/.*?\//
|
PATTERN: /\/.*?\//
|
||||||
|
|
||||||
true: TRUE
|
|
||||||
TRUE: /true/
|
TRUE: /true/
|
||||||
false: FALSE
|
|
||||||
FALSE: /false/
|
FALSE: /false/
|
||||||
nil: NIL
|
|
||||||
NIL: /nil/
|
NIL: /nil/
|
||||||
INT: /[+-]?[0-9]+/
|
INT: /[+-]?[0-9]+/
|
||||||
|
|
||||||
%import common.WORD // imports from terminal library
|
|
||||||
%import common.FLOAT // float
|
%import common.FLOAT // float
|
||||||
%ignore " " // Disregard spaces in text
|
%ignore " " // Disregard spaces in text
|
||||||
%ignore "," // Treat commas as whitespace
|
%ignore "," // Treat commas as whitespace
|
||||||
|
@ -39,6 +36,6 @@ INT: /[+-]?[0-9]+/
|
||||||
|
|
||||||
|
|
||||||
def parse(input: str) -> Any:
|
def parse(input: str) -> Any:
|
||||||
"""Parse a string using the shogoth (lisp) gramar, returning an unmodified tree."""
|
'''Parse a string using the shogoth (lisp) gramar, returning an unmodified tree.'''
|
||||||
|
|
||||||
return PARSER.parse(input)
|
return PARSER.parse(input)
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
from .impl import Reader
|
from .impl import Reader
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["Reader"]
|
__all__ = ["Reader"]
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
"""The shogoth reader."""
|
"""The shogoth reader."""
|
||||||
|
|
||||||
|
|
||||||
|
import re
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from shogoth.parser import parse
|
|
||||||
|
|
||||||
from lark import Tree, Token
|
from lark import (
|
||||||
from lark import Lark, Transformer, v_args
|
Lark,
|
||||||
|
Token,
|
||||||
|
Transformer,
|
||||||
|
Tree,
|
||||||
|
v_args,
|
||||||
|
)
|
||||||
|
from shogoth.parser import parse
|
||||||
|
from shogoth.types import Keyword, Symbol
|
||||||
|
|
||||||
|
|
||||||
# Monkeypatching for py3.10 matching
|
# Monkeypatching for py3.10 matching
|
||||||
Tree.__match_args__ = ("data", "children")
|
Tree.__match_args__ = ("data", "children")
|
||||||
|
@ -22,41 +30,57 @@ class Reader(object):
|
||||||
return parse(buffer)
|
return parse(buffer)
|
||||||
|
|
||||||
def symbol(self, x):
|
def symbol(self, x):
|
||||||
return ["read-eval", ["symbol", x]]
|
return Symbol(x)
|
||||||
|
|
||||||
def keyword(self, x):
|
def keyword(self, x):
|
||||||
return ["read-eval", ["keyword", x]]
|
return Keyword(x)
|
||||||
|
|
||||||
|
def pattern(self, x):
|
||||||
|
return re.compile(x[1:-1].replace("\\/", "/"))
|
||||||
|
|
||||||
def _read(self, tree: Tree) -> Any:
|
def _read(self, tree: Tree) -> Any:
|
||||||
match tree:
|
match tree:
|
||||||
case Tree(Token('RULE', 'expr'), children):
|
case Tree(Token("RULE", "expr"), children):
|
||||||
return self._read(children[0])
|
return self._read(children[0])
|
||||||
|
|
||||||
case Tree(Token('RULE', 'plist'), children):
|
case Tree(Token("RULE", "plist"), children):
|
||||||
return [self._read(c) for c in children]
|
return [self._read(c) for c in children]
|
||||||
|
|
||||||
case Tree(Token('RULE', 'blist'), children):
|
case Tree(Token("RULE", "blist"), children):
|
||||||
return [self._read(c) for c in children]
|
return [self._read(c) for c in children]
|
||||||
|
|
||||||
case Tree(Token('RULE', 'mapping'), children):
|
case Tree(Token("RULE", "mapping"), children):
|
||||||
return dict(self._read(c) for c in children)
|
return dict(self._read(c) for c in children)
|
||||||
|
|
||||||
case Tree(Token('RULE', 'kv'), [k, v]):
|
case Tree(Token("RULE", "kv"), [k, v]):
|
||||||
return (self._read(k), self._read(v))
|
return (self._read(k), self._read(v))
|
||||||
|
|
||||||
case Tree(Token('RULE', 'atom'), [a]):
|
case Tree(Token("RULE", "atom"), [a]):
|
||||||
return self._read(a)
|
return self._read(a)
|
||||||
|
|
||||||
case Token('INT', x):
|
case Token("INT", x):
|
||||||
return int(x)
|
return int(x)
|
||||||
|
|
||||||
case Token('FLOAT', x):
|
case Token("FLOAT", x):
|
||||||
return float(x)
|
return float(x)
|
||||||
|
|
||||||
case Token('KEYWORD', x):
|
case Token("KEYWORD", x):
|
||||||
return self.keyword(x)
|
return self.keyword(x)
|
||||||
|
|
||||||
case Token('SYMBOL', x):
|
case Token("PATTERN", x):
|
||||||
|
return self.pattern(x)
|
||||||
|
|
||||||
|
case Token("TRUE", _):
|
||||||
|
return True
|
||||||
|
|
||||||
|
case Token("FALSE", _):
|
||||||
|
return False
|
||||||
|
|
||||||
|
case Token("NIL", _):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Symbol is very much the catch-all of the grammar
|
||||||
|
case Token("SYMBOL", x):
|
||||||
return self.symbol(x)
|
return self.symbol(x)
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
"""A testing REPL."""
|
"""A testing REPL."""
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from shogoth.parser import parse
|
|
||||||
from shogoth.reader import Reader
|
from shogoth.reader import Reader
|
||||||
|
|
||||||
|
|
||||||
|
|
7
projects/shogoth/src/python/shogoth/types/__init__.py
Normal file
7
projects/shogoth/src/python/shogoth/types/__init__.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
"""The public interface for shogoth's baked-in types."""
|
||||||
|
|
||||||
|
from .keyword import Keyword
|
||||||
|
from .symbol import Symbol
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["Keyword", "Symbol"]
|
5
projects/shogoth/src/python/shogoth/types/keyword.py
Normal file
5
projects/shogoth/src/python/shogoth/types/keyword.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from .symbol import Symbol
|
||||||
|
|
||||||
|
|
||||||
|
class Keyword(Symbol):
|
||||||
|
pass
|
5
projects/shogoth/src/python/shogoth/types/symbol.py
Normal file
5
projects/shogoth/src/python/shogoth/types/symbol.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
|
||||||
|
class Symbol(NamedTuple):
|
||||||
|
name: str
|
Loading…
Reference in a new issue