from core.builtin_concepts import BuiltinConcepts, ParserResultConcept from core.concept import Concept from core.tokenizer import TokenKind from evaluators.BaseEvaluator import AllReturnValuesEvaluator, BaseEvaluator from parsers.BaseParser import BaseParser from parsers.ConceptLexerParser import ConceptNode, UnrecognizedTokensNode, ConceptLexerParser import core.utils class ConceptComposerEvaluator(AllReturnValuesEvaluator): """ Try to reassemble parts of concepts from different evaluators """ NAME = "ConceptComposer" def __init__(self): super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 40) def matches(self, context, return_values): concept_lexer_parser_name = ConceptLexerParser().name for return_value in return_values: if return_value.who.startswith(BaseParser.PREFIX) and return_value.status: return False if return_value.who.startswith(BaseEvaluator.PREFIX): return False if return_value.who != concept_lexer_parser_name: continue if not isinstance(return_value.value, ParserResultConcept): return False if not ( isinstance(return_value.value.value, ConceptNode) or isinstance(return_value.value.value, UnrecognizedTokensNode) or ( hasattr(return_value.value.value, "__iter__") and len(return_value.value.value) > 0 and ( isinstance(return_value.value.value[0], ConceptNode) or isinstance(return_value.value.value[0], UnrecognizedTokensNode) ))): return False self.eaten = return_value return True return False def eval(self, context, return_value): sheerka = context.sheerka nodes = self.eaten.value.value temp_res = [] has_error = False concepts_only = True for node in nodes: if isinstance(node, UnrecognizedTokensNode): tokens = core.utils.strip_tokens(node.tokens, True) for token in tokens: if token.type == TokenKind.IDENTIFIER: concept = context.new_concept(token.value) if sheerka.isinstance(concept, BuiltinConcepts.UNKNOWN_CONCEPT): has_error = True else: with context.push(self.name, desc=f"Evaluating '{concept}'") as sub_context: sub_context.log_new(self.verbose_log) concept = sheerka.evaluate_concept(sub_context, concept, self.verbose_log) sub_context.add_values(return_values=concept) temp_res.append(concept) else: temp_res.append(core.utils.strip_quotes(token.value)) concepts_only &= token.type == TokenKind.WHITESPACE or token.type == TokenKind.NEWLINE else: with context.push(self.name, desc=f"Evaluating '{node.concept}'") as sub_context: sub_context.log_new(self.verbose_log) concept = sheerka.evaluate_concept(sub_context, node.concept, self.verbose_log) sub_context.add_values(return_values=concept) temp_res.append(concept) if has_error: return sheerka.ret( self.name, False, temp_res, parents=[self.eaten]) if concepts_only: res = [] for r in temp_res: if isinstance(r, Concept): res.append(r) else: res = "" for r in temp_res: if isinstance(r, Concept): res += sheerka.value(r) else: res += r return sheerka.ret( self.name, True, res, parents=[self.eaten])