Skip to content

Commit

Permalink
fixes_and_small_changes (#21)
Browse files Browse the repository at this point in the history
* Fix indent and delete unnecessary methods

* Fix long lines

* Disable simple snippet expansion in parameters

* Enable adding operators to nothing

* Rename wide_block to wblock

* Add snippets for easier method/constructor implementation

* Reformat cpp.json file

* Add delete method and constructor snippets

* Add private, public and protected blocks

* Refactor compile class

* Move ContextManager and IndentManager classes to util file

* Cleanup blank lines, imports and stuff like that
  • Loading branch information
Ahhhhmed committed Apr 20, 2018
1 parent e8060b3 commit 9e55488
Show file tree
Hide file tree
Showing 16 changed files with 424 additions and 337 deletions.
128 changes: 43 additions & 85 deletions homotopy/compiler.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import re

from homotopy.syntax_tree import SnippetVisitor
from homotopy.parser import Parser

import re
import logging
from homotopy.util import ContextManager


class Compiler(SnippetVisitor):
Expand All @@ -14,6 +14,7 @@ def __init__(self, snippet_provider, indent_manager):
self.context_manager.new_scope()
self.snippet_provider = snippet_provider
self.indent_manager = indent_manager
self.inside_parameter = False

def visit_composite_snippet(self, composite_snippet):
"""
Expand All @@ -28,29 +29,9 @@ def visit_composite_snippet(self, composite_snippet):

if operation_text in left_side:
return self.substitute(left_side, composite_snippet.operation, composite_snippet.right, operation_text)
else:
expanded_left_side = left_side
match_found = False

def expansion_function(match_object):
nonlocal match_found

if not match_found and operation_text in self.snippet_provider[match_object.group(1)]:
match_found = True
return self.snippet_provider[match_object.group(1)]

return match_object.group(0)

expanded_left_side = re.sub(
r'{{(.*?)}}',
expansion_function,
expanded_left_side)

if operation_text in expanded_left_side:
return self.substitute(expanded_left_side, composite_snippet.operation, composite_snippet.right, operation_text)

logging.warning("No match found. Ignoring right side of the snippet.")
return left_side
expanded_left_side = self.expand_snippet(left_side, operation_text)
return self.substitute(expanded_left_side, composite_snippet.operation, composite_snippet.right, operation_text)

def visit_simple_snippet(self, simple_snippet):
"""
Expand All @@ -59,7 +40,33 @@ def visit_simple_snippet(self, simple_snippet):
:param simple_snippet: Simple snippet
:return: Text of compile snippet
"""
return self.expand_variable_operators(self.snippet_provider[simple_snippet.value])
snippet_text = simple_snippet.value if self.inside_parameter else self.snippet_provider[simple_snippet.value]

return self.expand_variable_operators(snippet_text)

def expand_snippet(self, snippet_text, operation_text):
"""
Expend snippet to uncover possible operator definition.
:param snippet_text: Snippet text
:param operation_text: Operation text
:return: Expanded snippet
"""
match_found = False

def expansion_function(match_object):
nonlocal match_found

if not match_found and operation_text in self.snippet_provider[match_object.group(1)]:
match_found = True
return self.snippet_provider[match_object.group(1)]

return match_object.group(0)

return re.sub(
r'{{(.*?)}}',
expansion_function,
snippet_text)

def expand_variable_operators(self, text):
"""
Expand All @@ -80,17 +87,20 @@ def substitute(self, left, operation, right_tree, operation_text):
before_operation_text = left[0:left.find(operation_text)]
m = re.search(r"\n([\t ]*)$", before_operation_text)
indent = m.group(1) if m else ""
self.indent_manager.push_indent(indent)
else:
old_inside_parameter = self.inside_parameter
self.inside_parameter = True

right = self.snippet_provider[self.compile(right_tree)]
right = self.compile(right_tree)

if operation != Parser.in_operator:
self.context_manager.add_variable(operation_text, right)
else:
if operation == Parser.in_operator:
self.context_manager.remove_scope()

right = self.indent_manager.indent_new_lines(right)
self.indent_manager.pop_indent()
right = self.indent_manager.indent_new_lines(right, indent)
else:
self.context_manager.add_variable(operation_text, right)

self.inside_parameter = old_inside_parameter

return left.replace(operation_text, right)

Expand All @@ -104,55 +114,3 @@ def compile(self, snippet):
compiled_snippet = self.visit(snippet)

return re.sub(r'({{.*?}})', "", compiled_snippet)


class ContextManager:
"""
Class for managing substituted parameters to be used again.
"""
def __init__(self):
"""
Initialize stack.
"""
self.stack = []

def new_scope(self):
"""
Add new scope.
"""
self.stack.append({})

def remove_scope(self):
"""
Remove last scope.
"""
if self.stack:
self.stack.pop()

def add_variable(self, name, value):
"""
Add variable to current scope.
:param name: Variable name
:param value: Variable value
"""
if self.stack:
self.stack[-1][name] = value
else:
raise Exception("No scope to add variable to")

def __getitem__(self, item):
"""
Get variable from last scope.
:param item: Variable name
:return: Variable value if it exists. Empty string otherwise
"""
i = 2
while i <= len(self.stack):
if item in self.stack[-i]:
return self.stack[-i][item]

i += 1

return ""
5 changes: 2 additions & 3 deletions homotopy/homotopy.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from homotopy import preprocessor, parser, compiler, snippet_provider, indent_manager
from homotopy import preprocessor, parser, compiler, snippet_provider, util


class Homotopy:
Expand Down Expand Up @@ -72,7 +72,7 @@ def compile(self, snippet_text):
snippet_provider_instance = snippet_provider.SnippetProvider(
self.language, self.user_path + [Homotopy.stdlib_path]
)
indent_manager_instance = indent_manager.IndentManager()
indent_manager_instance = util.IndentManager()

snippet_text = indent_manager_instance.take_base_indent(snippet_text)

Expand All @@ -88,4 +88,3 @@ def compile(self, snippet_text):
compiled_snippet = compiler_instance.compile(syntax_tree)

return indent_manager_instance.indent_base(compiled_snippet)

72 changes: 0 additions & 72 deletions homotopy/indent_manager.py

This file was deleted.

3 changes: 1 addition & 2 deletions homotopy/snippet_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class SnippetProvider:
name_key = "name"
snippet_key = "snippet"

def __init__(self, language="", path=[]):
def __init__(self, language, path):
"""
Initialize snippet provider instance.
Expand Down Expand Up @@ -57,4 +57,3 @@ def __getitem__(self, item):
if item in self.data:
return self.data[item]
return item

8 changes: 4 additions & 4 deletions homotopy/stdlib/core.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[
{"name": "block","language": "all","snippet": ">>>{{opt_block}}"},
{"name": "opt_block","language": "all","snippet": "\n>>>{{opt_block}}"},
{"name": "wide_block","language": "all","snippet": ">>>{{opt_wide_block}}"},
{"name": "opt_wide_block","language": "all","snippet": "\n\n>>>{{opt_wide_block}}"},
{"name": "wblock","language": "all","snippet": ">>>{{opt_wblock}}"},
{"name": "opt_wblock","language": "all","snippet": "\n\n>>>{{opt_wblock}}"},
{"name": "inside_block","language": "C++","snippet": "\t>>>{{opt_inside_block}}"},
{"name": "opt_inside_block","language": "C++","snippet": "\n\t>>>{{opt_inside_block}}"},
{"name": "wide_inside_block","language": "C++","snippet": "\t>>>{{opt_wide_inside_block}}"},
{"name": "opt_wide_inside_block","language": "C++","snippet": "\n\n\t>>>{{opt_wide_inside_block}}"}
{"name": "winside_block","language": "C++","snippet": "\t>>>{{opt_winside_block}}"},
{"name": "opt_winside_block","language": "C++","snippet": "\n\n\t>>>{{opt_winside_block}}"}
]
57 changes: 33 additions & 24 deletions homotopy/stdlib/cpp.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,56 @@
{"name": "forr","language": "C++","snippet": "for(### $$$=%%%; $$$>={{for_end}}; $$$--){\n{{inside_block}}\n}"},
{"name": "for_end","language": "C++","snippet": "%%%"},
{"name": "forin","language": "C++","snippet": "for(auto&& $$$: %%%){\n{{inside_block}}\n}"},

{"name": "if","language": "C++","snippet": "if($$$){\n{{inside_block}}\n}"},
{"name": "while","language": "C++","snippet": "while($$$){\n{{inside_block}}\n}"},
{"name": "switch","language": "C++","snippet": "switch($$$){\n{{wide_inside_block}}\n}"},

{"name": "switch","language": "C++","snippet": "switch($$$){\n{{winside_block}}\n}"},
{"name": "case","language": "C++","snippet": "case $$$:\n{{inside_block}}\n\tbreak;{{opt_case}}"},
{"name": "opt_case","language": "C++","snippet": "\ncase $$$:\n{{inside_block}}\n\tbreak;{{opt_case}}"},
{"name": "struct","language": "C++","snippet": "struct !!!{{extend}} {\n{{wide_inside_block}}\n};"},
{"name": "class","language": "C++","snippet": "class !!!{{extend}} {\n{{wide_inside_block}}\n};"},
{"name": "extend","language": "C++","snippet": ": %%% :::{{opt_extend}}"},
{"name": "opt_extend","language": "C++","snippet": ", %%% :::{{opt_extend}}"},
{"name": "method","language": "C++","snippet": "public: ### @@@({{params}}){\n{{wide_inside_block}}\n}"},
{"name": "pmethod","language": "C++","snippet": "private: ### @@@({{params}}){\n{{wide_inside_block}}\n}"},
{"name": "nimethod","language": "C++","snippet": "public: ### @@@({{params}});"},
{"name": "nipmethod","language": "C++","snippet": "private: ### @@@({{params}});"},
{"name": "amethod","language": "C++","snippet": "public: ### @@@({{params}}) = 0;"},
{"name": "apmethod","language": "C++","snippet": "private: ### @@@({{params}}) = 0;"},
{"name": "constr","language": "C++","snippet": "public: {{?!!!}}({{params}}){\n{{wide_inside_block}}\n}"},
{"name": "pconstr","language": "C++","snippet": "private: {{?!!!}}({{params}}){\n{{wide_inside_block}}\n}"},
{"name": "niconstr","language": "C++","snippet": "public: {{?!!!}}({{params}});"},
{"name": "nipconstr","language": "C++","snippet": "private: {{?!!!}}({{params}});"},
{"name": "econstr","language": "C++","snippet": "public: {{?!!!}}({{params}}){}"},
{"name": "epconstr","language": "C++","snippet": "private: {{?!!!}}({{params}}){}"},
{"name": "func","language": "C++","snippet": "### @@@({{params}}){\n{{wide_inside_block}}\n}"},

{"name": "func","language": "C++","snippet": "### @@@({{params}}){\n{{winside_block}}\n}"},
{"name": "params","language": "C++","snippet": "### $$${{opt_params}}"},
{"name": "opt_params","language": "C++","snippet": ", ### $$${{opt_params}}"},

{"name": "struct","language": "C++","snippet": "struct !!!{{extend}} {\n{{winside_block}}\n};"},
{"name": "extend","language": "C++","snippet": ": %%% :::{{opt_extend}}"},
{"name": "opt_extend","language": "C++","snippet": ", %%% :::{{opt_extend}}"},

{"name": "class","language": "C++","snippet": "class !!!{{extend}} {\n{{block}}\n};"},
{"name": "public","language": "C++","snippet": "public:\n{{winside_block}}"},
{"name": "private","language": "C++","snippet": "private:\n{{winside_block}}"},
{"name": "protected","language": "C++","snippet": "protected:\n{{winside_block}}"},

{"name": "method","language": "C++","snippet": "### @@@({{params}}){\n{{winside_block}}\n}"},
{"name": "nimethod","language": "C++","snippet": "### @@@({{params}});"},
{"name": "amethod","language": "C++","snippet": "### @@@({{params}}) = 0;"},
{"name": "dmethod","language": "C++","snippet": "### @@@({{params}}) = delete;"},
{"name": "methodi1","language": "C++","snippet": "### !!!::@@@({{params}}){\n{{winside_block}}\n}"},
{"name": "methodi","language": "C++","snippet": "### {{?!!!}}::@@@({{params}}){\n{{winside_block}}\n}"},

{"name": "constr","language": "C++","snippet": "{{?!!!}}({{params}}){\n{{winside_block}}\n}"},
{"name": "niconstr","language": "C++","snippet": "{{?!!!}}({{params}});"},
{"name": "econstr","language": "C++","snippet": "{{?!!!}}({{params}}){}"},
{"name": "dconstr","language": "C++","snippet": "{{?!!!}}({{params}}) = delete;"},
{"name": "constri1","language": "C++","snippet": "!!!::!!!({{params}}){\n{{winside_block}}\n}"},
{"name": "constri","language": "C++","snippet": "{{?!!!}}::{{?!!!}}({{params}}){\n{{winside_block}}\n}"},

{"name": "enum","language": "C++","snippet": "enum !!!{{enum_type}} {\n{{enum_body}}\n};"},
{"name": "enum_body","language": "C++","snippet": "\t>>>{{opt_enum_body}}"},
{"name": "opt_enum_body","language": "C++","snippet": ",\n\t>>>{{opt_enum_body}}"},
{"name": "enum1","language": "C++","snippet": "enum !!!{{enum1_type}} { {{enum1_body}} };"},
{"name": "enum1_body","language": "C++","snippet": ">>>{{opt_enum1_body}}"},
{"name": "opt_enum1_body","language": "C++","snippet": ", >>>{{opt_enum1_body}}"},
{"name": "template","language": "C++","snippet": "template <{{template_params}}>\n{{wide_block}}"},

{"name": "template","language": "C++","snippet": "template <{{template_params}}>\n{{wblock}}"},
{"name": "template_params","language": "C++","snippet": "class ^^^{{opt_template_params}}"},
{"name": "opt_template_params","language": "C++","snippet": ", class ^^^{{opt_template_params}}"},
{"name": "methodi","language": "C++","snippet": "### !!!::@@@({{params}}){\n{{wide_inside_block}}\n}"},
{"name": "constri","language": "C++","snippet": "!!!::!!!({{params}}){\n{{wide_inside_block}}\n}"},


{"name": "inc","language": "C++","snippet": "#include \"$$$\""},
{"name": "stdinc","language": "C++","snippet": "#include <$$$>"},

{"name": "singleton","language": "C++","snippet": "method#{{?\\!\\!\\!}}\\&@getInstance>static {{?\\!\\!\\!}} instance;&return instance<block>epconstr&nipconstr#{{?\\!\\!\\!}} const\\&$origin&nipmethod#void@operator=#{{?\\!\\!\\!}} const\\&$origin<"},
{"name": "compositeclass","language": "C++","snippet": "private\\: std\\:\\:vector\\<{{?\\:\\:\\:}}*\\> children;&method#void@add#{{?\\:\\:\\:}}$*item>children.puch_back(item);<"},
{"name": "singleton","language": "C++","snippet": "public>method#{{?\\!\\!\\!}}\\&@getInstance>static {{?\\!\\!\\!}} instance;&return instance<<private>block>econstr&niconstr#{{?\\!\\!\\!}} const\\&$origin&nimethod#void@operator=#{{?\\!\\!\\!}} const\\&$origin<"},
{"name": "compositeclass","language": "C++","snippet": "public>method#void@add#{{?\\:\\:\\:}}$*item>children.puch_back(item);<<private>std\\:\\:vector\\<{{?\\:\\:\\:}}*\\> children;<"},
{"name": "compositemethod","language": "C++","snippet": ">for#int$i%0%children.size()>children[i]-\\>{{?\\@\\@\\@}}();<<"}
]
4 changes: 3 additions & 1 deletion homotopy/syntax_tree.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@


class Snippet:
"""
Base class for snippet syntax tree.
Expand Down Expand Up @@ -48,7 +50,7 @@ class SimpleSnippet(Snippet):
"""
def __init__(self, value):
"""
Initialize SnipleSnippet instance.
Initialize SimpleSnippet instance.
:param value: Value of the snippet
"""
Expand Down

0 comments on commit 9e55488

Please sign in to comment.