from thinglang import utils
from thinglang.execution.execution import ExecutionEngine
from thinglang.lexer.lexer import lexer
from thinglang.parser.analyzer import Analysis
from thinglang.parser.parser import parse
from thinglang.parser.simplifier import simplify


def run(source):
    if not source:
        raise ValueError('Source cannot be empty')

    source = source.strip().replace(' ' * 4, '\t')

    utils.print_header('Source', source)

    lexical_groups = list(lexer(source))
    tree = parse(lexical_groups)
    root_node = simplify(tree)

    Analysis(tree).run()

    utils.print_header('Parsed AST', root_node.tree())

    with ExecutionEngine(root_node) as engine:
        engine.execute()
        return engine.results()

@@ -248,24 +248,26 @@
  import 
-s
+S
 implif
-y
+ier
 %0A%0A%0Adef r
@@ -488,20 +488,19 @@
 e))%0A    
-tree
+ast
  = parse
@@ -520,39 +520,34 @@
 ps)%0A
+%0A
     
-root_node = simplify(tree)%0A
+Simplifier(ast).run()
 %0A   
@@ -556,20 +556,19 @@
 nalysis(
-tree
+ast
 ).run()%0A
@@ -605,25 +605,19 @@
 d AST', 
-root_node
+ast
 .tree())
@@ -647,17 +647,11 @@
 ine(
-root_node
+ast
 ) as

Update Simplifier interface