from core.builtin_concepts import ParserResultConcept, BuiltinConcepts import core.builtin_helpers from core.concept import Concept, ConceptParts from evaluators.BaseEvaluator import OneReturnValueEvaluator import logging from parsers.BaseParser import BaseParser log = logging.getLogger(__name__) class ConceptEvaluator(OneReturnValueEvaluator): NAME = "Concept" evaluation_steps = [BuiltinConcepts.EVALUATION, BuiltinConcepts.AFTER_EVALUATION] def __init__(self): super().__init__(self.NAME, 50) def matches(self, context, return_value): return return_value.status and \ return_value.who.startswith(BaseParser.PREFIX) and \ isinstance(return_value.value, Concept) and \ not isinstance(return_value.value, ParserResultConcept) # because there are specific evaluators def eval(self, context, return_value): sheerka = context.sheerka concept = return_value.value # pre condition should already be validated by the parser. # It's a mandatory condition for the concept before it can be recognized if len(concept.cached_asts) == 0: sheerka.initialize_concept_asts(context, concept) # TODO; check pre # if pre is not true, return Concept with a false value # Evaluate the properties for prop in concept.props: sub_context = context.push(self.name, f"Evaluating property '{prop}'", concept) res = self.evaluate_parsing(sheerka, sub_context, concept.cached_asts[prop]) if res.status: concept.set_prop(prop, res.value) else: return sheerka.ret( self.name, False, sheerka.new(BuiltinConcepts.PROPERTY_EVAL_ERROR, body=prop, concept=concept, error=res.value), parents=[return_value]) # Returns the concept when no body if ConceptParts.BODY not in concept.cached_asts: return sheerka.ret(self.name, True, concept, parents=[return_value]) # Evaluate the body otherwise body = concept.cached_asts[ConceptParts.BODY] if body is None: raise NotImplementedError("Seems weird !") sub_context = context.push(self.name, "Evaluating body", concept) res = self.evaluate_parsing(sheerka, sub_context, body) return sheerka.ret(self.name, res.status, res.value, parents=[return_value]) def evaluate_parsing(self, sheerka, context, parsing_result): res = sheerka.chain_process(context, parsing_result, self.evaluation_steps) res = core.builtin_helpers.expect_one(context, res) return res