-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Moved compile logic in compile class * Removed unnecessary comment * Removed compile method from syntax tree * Moved compiler class to a separate file * Add docstrings to syntax tree file * Fix formatting of docstrings * Moved compile test to a new file * Removed unused imports * Added test for base snippet visitor * Few renames * Implemented more complete compile functionality * Added tests for compiler * Added cleanup after compile * Compiler documentation added
- Loading branch information
Showing
6 changed files
with
238 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,17 @@ | ||
import argparse | ||
import homotopy.parser | ||
|
||
from homotopy.compiler import Compiler | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description="Compile a snippet.") | ||
parser.add_argument('snippet', nargs=1, type=str, help='a snippet to be compiled') | ||
|
||
snippet = parser.parse_args().snippet[0] | ||
|
||
print(homotopy.parser.parser.parse(snippet).compile()) | ||
print(Compiler().compile(homotopy.parser.parser.parse(snippet))) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from homotopy.syntax_tree import SnippetVisitor | ||
from homotopy.snippet_provider import snippetProvider | ||
|
||
import re | ||
import logging | ||
|
||
|
||
class Compiler(SnippetVisitor): | ||
def __init__(self, expansion_level_count=2): | ||
self.expansion_level_count = expansion_level_count | ||
|
||
def visit_composite_snippet(self, composite_snippet): | ||
left_side = snippetProvider[self.visit(composite_snippet.left)] | ||
right_side = snippetProvider[self.visit(composite_snippet.right)] | ||
|
||
if composite_snippet.operation in left_side: | ||
return left_side.replace(composite_snippet.operation, right_side) | ||
else: | ||
expanded_left_side = left_side | ||
|
||
for _ in range(self.expansion_level_count): | ||
expanded_left_side = re.sub( | ||
r'{{(.*?)}}', | ||
lambda match_object: snippetProvider[match_object.group(1)], | ||
expanded_left_side, | ||
count=1) | ||
|
||
if composite_snippet.operation in expanded_left_side: | ||
return expanded_left_side.replace(composite_snippet.operation, right_side) | ||
|
||
logging.warning("No match found. Ignoring right side of the snippet.") | ||
return left_side | ||
|
||
def visit_simple_snippet(self, simple_snippet): | ||
return snippetProvider[simple_snippet.value] | ||
|
||
def compile(self, snippet): | ||
compiled_snippet = self.visit(snippet) | ||
|
||
return re.sub(r'({{.*?}})', "", compiled_snippet) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from unittest import TestCase | ||
from unittest.mock import patch, MagicMock | ||
|
||
import homotopy.syntax_tree as st | ||
from homotopy.compiler import Compiler | ||
|
||
|
||
class TestCompiler(TestCase): | ||
@patch('homotopy.snippet_provider.SnippetProvider.__getitem__') | ||
def test_compile(self, mock_provider): | ||
with self.assertRaises(NotImplementedError): | ||
Compiler().compile(st.Snippet()) | ||
|
||
data = { | ||
"for": "for # in !:\n\tpass", | ||
"def": "def !({{params}}):\n\tpass", | ||
"params": "#{{opt_params}}", | ||
"opt_params": ", #{{opt_params}}", | ||
"a1": "{{a2}}", | ||
"a2": "{{a3}}", | ||
"a3": "{{a4}}", | ||
"a4": "#" | ||
} | ||
|
||
mock_provider.side_effect = lambda x: x if x not in data else data[x] | ||
|
||
self.assertEqual( | ||
Compiler().compile(st.CompositeSnippet( | ||
st.CompositeSnippet(st.SimpleSnippet('for'), '#', st.SimpleSnippet('i')), | ||
'!', | ||
st.SimpleSnippet('data') | ||
)), | ||
'for i in data:\n\tpass' | ||
) | ||
|
||
with patch('logging.warning', MagicMock()) as m: | ||
self.assertEqual( | ||
Compiler().compile(st.CompositeSnippet( | ||
st.CompositeSnippet(st.SimpleSnippet('for'), '#', st.SimpleSnippet('i')), | ||
'%', | ||
st.SimpleSnippet('data') | ||
)), | ||
'for i in !:\n\tpass' | ||
) | ||
|
||
m.assert_called_once_with("No match found. Ignoring right side of the snippet.") | ||
|
||
with patch('logging.warning', MagicMock()) as m: | ||
self.assertEqual( | ||
Compiler().compile(st.CompositeSnippet(st.SimpleSnippet('a1'), '#', st.SimpleSnippet('i'))), | ||
'' | ||
) | ||
|
||
self.assertEqual( | ||
Compiler(expansion_level_count=3).compile(st.CompositeSnippet(st.SimpleSnippet('a1'), '#', st.SimpleSnippet('i'))), | ||
'i' | ||
) | ||
|
||
m.assert_called_once_with("No match found. Ignoring right side of the snippet.") | ||
|
||
self.assertEqual( | ||
Compiler().compile(st.CompositeSnippet( | ||
st.CompositeSnippet(st.SimpleSnippet('def'), '!', st.SimpleSnippet('foo')), | ||
'#', | ||
st.SimpleSnippet('a') | ||
)), | ||
'def foo(a):\n\tpass' | ||
) | ||
|
||
self.assertEqual( | ||
Compiler().compile(st.CompositeSnippet( | ||
st.CompositeSnippet( | ||
st.CompositeSnippet(st.SimpleSnippet('def'), '!', st.SimpleSnippet('foo')), | ||
'#', | ||
st.SimpleSnippet('a') | ||
), | ||
'#', | ||
st.SimpleSnippet('b'))), | ||
'def foo(a, b):\n\tpass' | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters