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
|
||||
quote: "'" expr
|
||||
|
||||
atom: KEYWORD | PATTERN | INT | FLOAT | STRING | true | false | nil | SYMBOL
|
||||
atom: KEYWORD | PATTERN | INT | FLOAT | STRING | TRUE | FALSE | NIL | SYMBOL
|
||||
KEYWORD: ":" SYMBOL
|
||||
SYMBOL: /[^(){}#'"\s]+/
|
||||
|
||||
// FIXME: These two don't deal with escapes correctly at all
|
||||
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
|
||||
|
@ -39,6 +36,6 @@ INT: /[+-]?[0-9]+/
|
|||
|
||||
|
||||
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)
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
from .impl import Reader
|
||||
|
||||
|
||||
__all__ = ["Reader"]
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
"""The shogoth reader."""
|
||||
|
||||
|
||||
import re
|
||||
from typing import Any
|
||||
from shogoth.parser import parse
|
||||
|
||||
from lark import Tree, Token
|
||||
from lark import Lark, Transformer, v_args
|
||||
from lark import (
|
||||
Lark,
|
||||
Token,
|
||||
Transformer,
|
||||
Tree,
|
||||
v_args,
|
||||
)
|
||||
from shogoth.parser import parse
|
||||
from shogoth.types import Keyword, Symbol
|
||||
|
||||
|
||||
# Monkeypatching for py3.10 matching
|
||||
Tree.__match_args__ = ("data", "children")
|
||||
|
@ -22,41 +30,57 @@ class Reader(object):
|
|||
return parse(buffer)
|
||||
|
||||
def symbol(self, x):
|
||||
return ["read-eval", ["symbol", x]]
|
||||
return Symbol(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:
|
||||
match tree:
|
||||
case Tree(Token('RULE', 'expr'), children):
|
||||
case Tree(Token("RULE", "expr"), children):
|
||||
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]
|
||||
|
||||
case Tree(Token('RULE', 'blist'), children):
|
||||
case Tree(Token("RULE", "blist"), 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)
|
||||
|
||||
case Tree(Token('RULE', 'kv'), [k, v]):
|
||||
case Tree(Token("RULE", "kv"), [k, v]):
|
||||
return (self._read(k), self._read(v))
|
||||
|
||||
case Tree(Token('RULE', 'atom'), [a]):
|
||||
case Tree(Token("RULE", "atom"), [a]):
|
||||
return self._read(a)
|
||||
|
||||
case Token('INT', x):
|
||||
case Token("INT", x):
|
||||
return int(x)
|
||||
|
||||
case Token('FLOAT', x):
|
||||
case Token("FLOAT", x):
|
||||
return float(x)
|
||||
|
||||
case Token('KEYWORD', x):
|
||||
case Token("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)
|
||||
|
||||
case _:
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
"""A testing REPL."""
|
||||
|
||||
import sys
|
||||
|
||||
from shogoth.parser import parse
|
||||
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