Enhanced ExecutionContext to keep track of the execution flow
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
import dataclasses
|
||||
from enum import Enum
|
||||
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE
|
||||
from core.sheerka import ExecutionContext
|
||||
from core.tokenizer import Token
|
||||
from evaluators.BaseEvaluator import BaseEvaluator
|
||||
from parsers.BaseParser import BaseParser, Node
|
||||
from parsers.BnfParser import BnfParser
|
||||
from parsers.ConceptLexerParser import UnrecognizedTokensNode, ParsingExpression
|
||||
from parsers.PythonParser import PythonNode
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
OBJ_TYPE_KEY = "__type__"
|
||||
OBJ_ID_KEY = "__id__"
|
||||
OBJ_NAME_KEY = "__name__"
|
||||
|
||||
default_concept = Concept()
|
||||
|
||||
|
||||
class SheerkaTransformType(Enum):
|
||||
Concept = 1
|
||||
Reference = 2
|
||||
ExecutionContext = 3
|
||||
Event = 4
|
||||
Node = 5
|
||||
Exception = 6
|
||||
|
||||
|
||||
class SheerkaTransform:
|
||||
|
||||
def __init__(self, sheerka):
|
||||
self.ids = {}
|
||||
self.sheerka = sheerka
|
||||
self.id_count = -1
|
||||
|
||||
def to_dict(self, obj):
|
||||
|
||||
if isinstance(obj, (Concept, ExecutionContext, Event)):
|
||||
exists, _id = self.exist(obj)
|
||||
if exists:
|
||||
return {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.Reference,
|
||||
OBJ_ID_KEY: _id
|
||||
}
|
||||
else:
|
||||
self.id_count = self.id_count + 1
|
||||
self.ids[obj] = self.id_count
|
||||
|
||||
if isinstance(obj, Concept):
|
||||
return self.context_to_dict(obj)
|
||||
|
||||
elif isinstance(obj, ExecutionContext):
|
||||
return self.execution_context_to_dict(obj)
|
||||
|
||||
elif isinstance(obj, Event):
|
||||
return {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.Event,
|
||||
OBJ_ID_KEY: self.id_count,
|
||||
'digest': obj.get_digest()}
|
||||
|
||||
elif isinstance(obj, (BaseParser, BaseEvaluator, BnfParser)):
|
||||
return obj.name
|
||||
|
||||
elif isinstance(obj, Token):
|
||||
return obj.__dict__
|
||||
|
||||
elif isinstance(obj, PythonNode):
|
||||
return {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.Node,
|
||||
OBJ_NAME_KEY: "PythonNode",
|
||||
'source': obj.source,
|
||||
'ast_': obj.get_dump(obj.ast_)
|
||||
}
|
||||
|
||||
elif isinstance(obj, Node):
|
||||
to_dict = {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.Node,
|
||||
OBJ_NAME_KEY: obj.__class__.__name__,
|
||||
}
|
||||
for k, v in obj.__dict__.items():
|
||||
to_dict[k] = self.to_dict(v)
|
||||
|
||||
return to_dict
|
||||
|
||||
elif isinstance(obj, Exception):
|
||||
to_dict = {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.Exception,
|
||||
OBJ_NAME_KEY: obj.__class__.__name__,
|
||||
}
|
||||
for k, v in obj.__dict__.items():
|
||||
to_dict[k] = self.to_dict(v)
|
||||
return to_dict
|
||||
|
||||
elif isinstance(obj, ParsingExpression):
|
||||
return obj.__repr__()
|
||||
|
||||
elif isinstance(obj, dict):
|
||||
return dict((str(k) if isinstance(k, Concept) else k, self.to_dict(v)) for k, v in obj.items())
|
||||
|
||||
elif hasattr(obj, "__iter__") and not isinstance(obj, str):
|
||||
return list(self.to_dict(o) for o in obj)
|
||||
|
||||
else:
|
||||
return obj
|
||||
|
||||
def context_to_dict(self, obj: Concept):
|
||||
to_dict = {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.Concept,
|
||||
OBJ_ID_KEY: self.id_count,
|
||||
}
|
||||
if obj.id:
|
||||
ref = self.sheerka.get(obj.key, obj.id)
|
||||
to_dict["id"] = obj.id
|
||||
else:
|
||||
ref = default_concept
|
||||
|
||||
# transform metadata
|
||||
for prop in PROPERTIES_TO_SERIALIZE:
|
||||
value = self.to_dict(getattr(obj.metadata, prop))
|
||||
ref_value = getattr(ref.metadata, prop)
|
||||
if value != ref_value:
|
||||
to_dict[prop] = value
|
||||
|
||||
# transform properties
|
||||
for prop in obj.props:
|
||||
value = self.to_dict(obj.props[prop].value)
|
||||
if prop not in ref.props or value != ref.props[prop].value:
|
||||
if "props" not in to_dict:
|
||||
to_dict["props"] = []
|
||||
to_dict["props"].append((prop, value))
|
||||
|
||||
return to_dict
|
||||
|
||||
def execution_context_to_dict(self, obj: ExecutionContext):
|
||||
to_dict = {
|
||||
OBJ_TYPE_KEY: SheerkaTransformType.ExecutionContext,
|
||||
OBJ_ID_KEY: self.id_count
|
||||
}
|
||||
for property_name in obj.__dict__:
|
||||
if property_name == "sheerka":
|
||||
continue
|
||||
to_dict[property_name] = self.to_dict(getattr(obj, property_name))
|
||||
|
||||
return to_dict
|
||||
|
||||
def exist(self, obj):
|
||||
for k, v in self.ids.items():
|
||||
if id(k) == id(obj) or k == obj:
|
||||
return True, v
|
||||
|
||||
return False, None
|
||||
Reference in New Issue
Block a user