Reimplemented explain feature

This commit is contained in:
2020-06-04 18:43:15 +02:00
parent c498b394e3
commit d7573f095f
27 changed files with 1673 additions and 1161 deletions
+56 -16
View File
@@ -1,4 +1,5 @@
import click
import types
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from printer.FormatInstructions import FormatInstructions, FormatDetailType
@@ -28,7 +29,6 @@ class SheerkaPrinter:
def __init__(self, sheerka):
self.sheerka = sheerka
self.formatter = Formatter()
self.formatter.register_format_l(EXECUTION_CONTEXT_CLASS, "[{id:3}] %tab%{desc} ({status})")
self.custom_concepts_printers = None
self.reset()
@@ -38,6 +38,10 @@ class SheerkaPrinter:
str(BuiltinConcepts.RETURN_VALUE): self.print_return_value,
}
self.formatter.reset_formats()
self.formatter.register_format_l(EXECUTION_CONTEXT_CLASS, "[{id:3}] %tab%{desc} ({status})")
self.formatter.register_format_l(SyntaxError,
'%red%{self.__class__.__name__}: {msg}\\n{text}\\n{"^": >{offset}}%reset%')
self.formatter.register_format_l(Exception, "%red%{self}%reset%")
def register_custom_printer(self, concept, custom_format):
key = concept.key if isinstance(concept, Concept) else concept
@@ -47,12 +51,22 @@ class SheerkaPrinter:
def register_format_l(self, obj, template):
self.formatter.register_format_l(obj, template)
def register_format_d(self, predicate, properties, format_type=FormatDetailType.Props_In_Line):
self.formatter.register_format_d(predicate, properties, format_type)
def register_format_d(self, obj, properties=None, format_type=FormatDetailType.Props_In_Line):
self.formatter.register_format_d(obj, properties, format_type)
def print(self, to_print, instructions=None):
"""
Print using SheerkaPrinter.out
:param to_print:
:param instructions: FormatInstructions
:return:
"""
instructions = instructions or FormatInstructions()
self.fp(instructions, to_print)
try:
self.fp(instructions, to_print)
except Exception as ex:
self.fp(instructions, ex)
return
def fp(self, instructions, item):
"""
@@ -61,11 +75,12 @@ class SheerkaPrinter:
:param item:
:return:
"""
if isinstance(item, (list, tuple)):
for i in item:
self.fp(instructions, i)
return
elif isinstance(item, str):
# first, get the merged instructions
instructions = self.merge_instructions(instructions, item)
# We can only print string
if isinstance(item, str):
for color in COLORS:
item = item.replace("%" + color + "%", "" if instructions.no_color else COLORS[color])
if "%tab%" in item:
@@ -74,23 +89,48 @@ class SheerkaPrinter:
self.out(instructions.tab + item)
return
# if list or generator, print one by one
elif hasattr(item, "__iter__"):
for i in item:
self.fp(instructions, i)
return
# Custom print required
elif isinstance(item, Concept) and item.key in self.custom_concepts_printers:
self.custom_concepts_printers[item.key](self, instructions, item)
# get the format per line and print
else:
self.fp(instructions, self.formatter.format_l(item, instructions.format_l))
# print details
format_d = self.formatter.compute_format_d(instructions.format_d)
for format_d_desc in reversed(format_d):
if format_d_desc.predicate.eval(item):
self.fp(instructions, self.formatter.format_d(item, format_d_desc))
break
format_d = self.formatter.format_d(item, instructions.format_d)
if format_d:
self.fp(instructions, format_d)
if instructions.recursive_props:
for k, v in instructions.recursive_props.items():
if hasattr(item, k) and v > 0 and (value := getattr(item, k)) != BuiltinConcepts.NOT_INITIALIZED:
self.fp(instructions.recurse(k), value)
@staticmethod
def merge_instructions(instructions, obj):
"""
Merge the format instruction coming from the context with the one from obj
Note that if obj is not a Concept, there is not instruction to merge
:param instructions:
:param obj:
:return:
"""
if not hasattr(obj, "get_format_instructions"):
return instructions
obj_instructions = obj.get_format_instructions()
if obj_instructions is None:
return instructions
return instructions.clone().merge(obj_instructions)
@staticmethod
def print_explanation(printer, instructions, item):
explanation_instructions = instructions.clone().merge(item.instructions)
@@ -102,7 +142,7 @@ class SheerkaPrinter:
if printer.sheerka.isinstance(item.body, BuiltinConcepts.EXPLANATION):
return printer.fp(instructions, item.body)
if isinstance(item.body, (list, tuple)):
if isinstance(item.body, (list, tuple, types.GeneratorType)):
return printer.fp(instructions, item.body)
status = item.status