Repository: genadijrazdorov/algograph

Issue:
Complex branches (more then one statement) not working

Discussion:

Patch:
diff --git a/algograph/lexer.py b/algograph/lexer.py
index 9d0e50f..39fa603 100644
--- a/algograph/lexer.py
+++ b/algograph/lexer.py
@@ -64,10 +64,10 @@ class Lexer:
         old, self.indent = self.indent, indent
 
         if indent > old:
-            yield INDENT(indent)
+            yield INDENT(indent - old)
 
         elif indent < old:
-            yield DEDENT(indent)
+            yield DEDENT(old - indent)
 
     def ignore(self, value):
         return []
diff --git a/algograph/parser.py b/algograph/parser.py
index c1b0840..cb4f890 100644
--- a/algograph/parser.py
+++ b/algograph/parser.py
@@ -85,9 +85,12 @@ def reduce_by_rule(rule):
 
 
 class Parser:
-    def __init__(self, algorithm):
+    def __init__(self, algorithm=None, tokens=None):
         self.algorithm = algorithm
-        self.tokens = Lexer(algorithm).tokenize()
+        if algorithm is None:
+            self.tokens = tokens
+        else:
+            self.tokens = Lexer(algorithm).tokenize()
 
     def reduce(self):
         '''
@@ -164,7 +167,12 @@ class Parser:
             raise SyntaxError
 
         token = SUITE(*stack[-i + 1: -1])
+        dedent = stack[-1].value
+        indent = stack[-i].value
         stack[-i:] = [token]
+        if dedent > indent:
+            stack.append(DEDENT(dedent - indent))
+            self._SUITE()
 
     @reduce_by_rule
     def _IFSWITCH(self):
@@ -213,7 +221,8 @@ class Parser:
             last = node
 
             not_ = stack[2].EXPR.NOT
-            yes = N(stack[2].SUITE.tokens[0].ID.value)
+            ## yes = N(stack[2].SUITE.tokens[0].ID.value)
+            yes = Parser(None, stack[2].SUITE.tokens).parse().root
             node[yes] = not not_
 
             elif_ = stack[2].ELIF
@@ -222,13 +231,15 @@ class Parser:
                     not_ = o.NOT
                     o = N(o.ID.value)
                     node[o] = not_
-                    s = N(s.tokens[0].ID.value)
+                    ## s = N(s.tokens[0].ID.value)
+                    s = Parser(None, s.tokens).parse().root
                     o[s] = not not_
                     node = o
 
             no = stack[2].ELSE
             if no:
-                no = N(no.tokens[0].ID.value)
+                ## no = N(no.tokens[0].ID.value)
+                no = Parser(None, no.tokens).parse().root
                 node[no] = not_
 
             del stack[2]


Test patch:
diff --git a/test/test_lexer.py b/test/test_lexer.py
index 99b4552..e04c4e9 100644
--- a/test/test_lexer.py
+++ b/test/test_lexer.py
@@ -47,7 +47,7 @@ class TestLexer:
                 INDENT(2),
                 ID('y'),
                 NEWLINE(),
-                DEDENT(0),
+                DEDENT(2),
                 ID('end'),
                 NEWLINE()
         ]
@@ -71,7 +71,7 @@ class TestLexer:
                 INDENT(2),
                 ID('one'),
                 NEWLINE(),
-                DEDENT(0),
+                DEDENT(2),
                 ELIF(),
                 ID('q'),
                 IS(),
@@ -82,14 +82,14 @@ class TestLexer:
                 INDENT(2),
                 ID('two'),
                 NEWLINE(),
-                DEDENT(0),
+                DEDENT(2),
                 ELSE(),
                 LITERAL(':'),
                 NEWLINE(),
                 INDENT(2),
                 ID('three'),
                 NEWLINE(),
-                DEDENT(0),
+                DEDENT(2),
                 ID('end'),
                 NEWLINE()
         ]
diff --git a/test/test_parser.py b/test/test_parser.py
index 8f62515..b9a72fa 100644
--- a/test/test_parser.py
+++ b/test/test_parser.py
@@ -29,6 +29,21 @@ class TestParser:
                      |   y
                      ''') == G(N('q', {N('y'): True}))
 
+    def test_multistatemnt_suite(self):
+        assert parse('''
+                     | if q:
+                     |   first
+                     |   second
+                     ''') == G(N('q', {N('first', {N('second'): None}): True}))
+
+    def test_multilevel_suite(self):
+        assert parse('''
+                     | if q:
+                     |   if q2:
+                     |     first
+                     |     second
+                     ''') == G(N('q', {N('q2', {N('first', {N('second'): None}): True}): True}))
+
     def test_if_not(self):
         assert parse('''
                      | if not q: