From 7e1e8b2ad40cb3f7159ce7b8ac5d039e3a9380ee Mon Sep 17 00:00:00 2001
From: Reid 'arrdem' McKenzie <me@arrdem.com>
Date: Sat, 21 Aug 2021 16:44:49 -0600
Subject: [PATCH] Adding Symbols

---
 projects/lilith/src/python/lilith/parser.py | 12 +++++---
 projects/lilith/test/python/test_parser.py  | 34 ++++++++++++---------
 2 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/projects/lilith/src/python/lilith/parser.py b/projects/lilith/src/python/lilith/parser.py
index a351cf8..844564d 100644
--- a/projects/lilith/src/python/lilith/parser.py
+++ b/projects/lilith/src/python/lilith/parser.py
@@ -16,13 +16,17 @@ GRAMMAR = read_text('lilith', 'grammar.lark')
 # !frag[lang: yaml]
 # !end
 # all this following tex
+class Symbol(t.NamedTuple):
+    name: str
+
+
 class Args(t.NamedTuple):
     positionals: object = []
     kwargs: object = {}
 
 
 class Apply(t.NamedTuple):
-    name: str
+    name: Symbol
     args: Args
 
 
@@ -43,8 +47,8 @@ class Block(t.NamedTuple):
         return "\n".join(self.body_lines)
 
 
-class TreeToTuples(lark.Transformer):
-    @lark.v_args(inline=True)
+class TreeToTuples(Transformer):
+    @v_args(inline=True)
     def string(self, s):
         return s[1:-1].replace('\\"', '"')
 
@@ -59,7 +63,7 @@ class TreeToTuples(lark.Transformer):
 
     def word(self, args):
         """args: ['a'] ['a' ['b', 'c', 'd']]"""
-        return ".".join(a.value for a in args)
+        return Symbol(".".join(a.value for a in args))
 
     def atom(self, args):
         return args[0]
diff --git a/projects/lilith/test/python/test_parser.py b/projects/lilith/test/python/test_parser.py
index f6d28ee..cc4514d 100644
--- a/projects/lilith/test/python/test_parser.py
+++ b/projects/lilith/test/python/test_parser.py
@@ -1,6 +1,7 @@
 """tests covering the Lilith parser."""
 
-from lilith.parser import Apply, Args, Block, GRAMMAR, parse_buffer, parser_with_transformer
+from lilith.parser import Apply, Args, Block, GRAMMAR, parse_buffer, parser_with_transformer, Symbol
+
 import pytest
 
 
@@ -14,8 +15,8 @@ def test_parse_args(args_grammar, example, expected):
 
 
 @pytest.mark.parametrize('example, expected', [
-    ("foo: bar", {"foo": "bar"}),
-    ("foo: bar, baz: qux", {"foo": "bar", "baz": "qux"}),
+    ("foo: bar", {Symbol("foo"): Symbol("bar")}),
+    ("foo: bar, baz: qux", {Symbol("foo"): Symbol("bar"), Symbol("baz"): Symbol("qux")}),
 ])
 def test_parse_kwargs(kwargs_grammar, example, expected):
     assert kwargs_grammar.parse(example) == expected
@@ -25,9 +26,14 @@ def test_parse_kwargs(kwargs_grammar, example, expected):
     ("1", ([1], {})),
     ("1, 2", ([1, 2], {})),
     ("1, 2, 3", ([1, 2, 3], {})),
-    ("foo: bar", ([], {"foo": "bar"})),
-    ("foo: bar, baz: qux", ([], {"foo": "bar", "baz": "qux"})),
-    ("1; foo: bar, baz: qux", ([1], {"foo": "bar", "baz": "qux"})),
+    ("foo: bar",
+     ([], {Symbol("foo"): Symbol("bar")})),
+    ("foo: bar, baz: qux",
+     ([], {Symbol("foo"): Symbol("bar"),
+           Symbol("baz"): Symbol("qux")})),
+    ("1; foo: bar, baz: qux",
+     ([1], {Symbol("foo"): Symbol("bar"),
+            Symbol("baz"): Symbol("qux")})),
 ])
 def test_parse_arguments(arguments_grammar, example, expected):
     assert arguments_grammar.parse(example) == expected
@@ -35,13 +41,13 @@ def test_parse_arguments(arguments_grammar, example, expected):
 
 @pytest.mark.parametrize('example, expected', [
     ('!def[syntax]',
-     Block(Apply('def', Args(['syntax'], {})), [])),
+     Block(Apply(Symbol('def'), Args(['syntax'], {})), [])),
     ('!frag[lang: md]',
-     Block(Apply('frag', Args([], {'lang': 'md'})), [])),
+     Block(Apply(Symbol('frag'), Args([], {'lang': 'md'})), [])),
     ('!frag[foo; lang: md]',
-     Block(Apply('frag', Args(['foo'], {'lang': 'md'})), [])),
+     Block(Apply(Symbol('frag'), Args(['foo'], {'lang': 'md'})), [])),
     ("!int.add[1, 2]",
-     Block(Apply('int.add', Args([1, 2], {})), [])),
+     Block(Apply(Symbol('int.add'), Args([1, 2], {})), [])),
 ])
 def test_parse_header(header_grammar, example, expected):
     assert header_grammar.parse(example) == expected
@@ -49,12 +55,12 @@ def test_parse_header(header_grammar, example, expected):
 
 @pytest.mark.parametrize('example, expected', [
     ("!frag[lang: md]",
-     [Block(Apply('frag', Args([], {"lang": "md"})), [])]),
+     [Block(Apply(Symbol('frag'), Args([], {Symbol("lang"): Symbol("md")})), [])]),
     ("""!frag[lang: md]\nHello, world!\n\n""",
-     [Block(Apply('frag', Args([], {"lang": "md"})), ["Hello, world!", ""])]),
+     [Block(Apply(Symbol('frag'), Args([], {Symbol("lang"): Symbol("md")})), ["Hello, world!", ""])]),
     ("""!frag[lang: md]\nHello, world!\n\n!def[bar]""",
-     [Block(Apply('frag', Args([], {"lang": "md"})), ["Hello, world!", ""]),
-      Block(Apply('def', Args(["bar"], {})), [])]),
+     [Block(Apply(Symbol('frag'), Args([], {Symbol("lang"): Symbol("md")})), ["Hello, world!", ""]),
+      Block(Apply(Symbol('def'), Args([Symbol("bar")], {})), [])]),
 ])
 def test_block_parser(example, expected):
     assert parse_buffer(example) == expected