Get arrays and mappings working
This commit is contained in:
parent
8db42aa17d
commit
d6a811118d
5 changed files with 46 additions and 9 deletions
|
@ -10,9 +10,18 @@ STRING: /""".*?"""/ | /".*?"/
|
||||||
int: INT
|
int: INT
|
||||||
float: FLOAT
|
float: FLOAT
|
||||||
number: int | float
|
number: int | float
|
||||||
word: WORD ("." WORD)*
|
word: "nil" -> nil
|
||||||
|
| "true" -> true
|
||||||
|
| "false" -> false
|
||||||
|
| WORD ("." WORD)* -> word
|
||||||
string: STRING
|
string: STRING
|
||||||
atom: number | word | string
|
|
||||||
|
list: "[" (expr ("," expr)*)? "]"
|
||||||
|
|
||||||
|
pair: expr ":" expr
|
||||||
|
dict: "{" (pair ("," pair)*)? "}"
|
||||||
|
|
||||||
|
atom: number | word | string | list | dict
|
||||||
|
|
||||||
application: word "[" arguments? "]"
|
application: word "[" arguments? "]"
|
||||||
|
|
||||||
|
@ -20,7 +29,7 @@ expr: application | atom
|
||||||
|
|
||||||
args: expr ("," args)?
|
args: expr ("," args)?
|
||||||
|
|
||||||
kwargs: expr ":" expr ("," kwargs)?
|
kwargs: pair ("," kwargs)*
|
||||||
|
|
||||||
a_args_kwargs: args ";" kwargs
|
a_args_kwargs: args ";" kwargs
|
||||||
a_args: args
|
a_args: args
|
||||||
|
|
|
@ -54,13 +54,16 @@ class TreeToTuples(Transformer):
|
||||||
def string(self, s):
|
def string(self, s):
|
||||||
return s[1:-1].replace('\\"', '"')
|
return s[1:-1].replace('\\"', '"')
|
||||||
|
|
||||||
null = lambda self, _: None
|
nil = lambda self, _: None
|
||||||
true = lambda self, _: True
|
true = lambda self, _: True
|
||||||
false = lambda self, _: False
|
false = lambda self, _: False
|
||||||
int = v_args(inline=True)(lambda self, x: int(x))
|
int = v_args(inline=True)(lambda self, x: int(x))
|
||||||
float = v_args(inline=True)(lambda self, x: float(x))
|
float = v_args(inline=True)(lambda self, x: float(x))
|
||||||
number = v_args(inline=True)(lambda self, x: x)
|
number = v_args(inline=True)(lambda self, x: x)
|
||||||
|
|
||||||
|
list = list
|
||||||
|
dict = dict
|
||||||
|
|
||||||
def word(self, args):
|
def word(self, args):
|
||||||
"""args: ['a'] ['a' ['b', 'c', 'd']]"""
|
"""args: ['a'] ['a' ['b', 'c', 'd']]"""
|
||||||
return Symbol(".".join(a.value for a in args))
|
return Symbol(".".join(a.value for a in args))
|
||||||
|
@ -82,11 +85,14 @@ class TreeToTuples(Transformer):
|
||||||
_args = _args + args[1]
|
_args = _args + args[1]
|
||||||
return _args
|
return _args
|
||||||
|
|
||||||
|
def pair(self, args):
|
||||||
|
return (args[0], args[1])
|
||||||
|
|
||||||
def kwargs(self, args):
|
def kwargs(self, args):
|
||||||
d = {}
|
d = {}
|
||||||
key, val = args[0:2]
|
key, val = args[0]
|
||||||
if len(args) == 3:
|
if len(args) == 2:
|
||||||
d.update(args[2])
|
d.update(args[1])
|
||||||
d[key] = val
|
d[key] = val
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
"""A simple Lilith shell."""
|
"""A simple Lilith shell."""
|
||||||
|
|
||||||
|
import traceback
|
||||||
|
|
||||||
from lilith.interpreter import Bindings, eval, Runtime
|
from lilith.interpreter import Bindings, eval, Runtime
|
||||||
from lilith.parser import Apply, Args, parse_expr
|
from lilith.parser import Apply, Args, parse_expr
|
||||||
from lilith.reader import Module
|
from lilith.reader import Module
|
||||||
|
@ -49,12 +51,12 @@ if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
expr = parse_expr(line)
|
expr = parse_expr(line)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
traceback.print_exc()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = eval(runtime, module, Bindings("__root__", None), expr)
|
result = eval(runtime, module, Bindings("__root__", None), expr)
|
||||||
print_([("class:result", f"⇒ {result!r}")], style=STYLE)
|
print_([("class:result", f"⇒ {result!r}")], style=STYLE)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
traceback.print_exc()
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -22,6 +22,11 @@ def arguments_grammar():
|
||||||
return parser_with_transformer(GRAMMAR, "arguments")
|
return parser_with_transformer(GRAMMAR, "arguments")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def expr_grammar():
|
||||||
|
return parser_with_transformer(GRAMMAR, "expr")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def header_grammar():
|
def header_grammar():
|
||||||
return parser_with_transformer(GRAMMAR, "header")
|
return parser_with_transformer(GRAMMAR, "header")
|
||||||
|
|
|
@ -60,6 +60,21 @@ def test_parse_arguments(arguments_grammar, example, expected):
|
||||||
assert arguments_grammar.parse(example) == expected
|
assert arguments_grammar.parse(example) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"example, expected",
|
||||||
|
[
|
||||||
|
("1", 1),
|
||||||
|
("[1, 2, 3]", [1, 2, 3]),
|
||||||
|
('{"a": 1}', {"a": 1}),
|
||||||
|
("true", True),
|
||||||
|
("false", False),
|
||||||
|
("nil", None),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_parse_expr(expr_grammar, example, expected):
|
||||||
|
assert expr_grammar.parse(example) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"example, expected",
|
"example, expected",
|
||||||
[
|
[
|
||||||
|
|
Loading…
Reference in a new issue