from core.builtin_concepts import ParserResultConcept, BuiltinConcepts from evaluators.BaseEvaluator import OneReturnValueEvaluator from parsers.BaseNodeParser import SourceCodeNode from parsers.BnfNodeParser import ConceptNode from parsers.PythonParser import LexerNodeParserHelperForPython, PythonNode class LexerNodeEvaluator(OneReturnValueEvaluator): """ Evaluate a list of LexerNode (ConceptNode | SourceCodeNode | UnrecognizedTokenNode...) """ NAME = "LexerNode" def __init__(self): super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 60) self.identifiers = {} # cache for already created identifier (the key is id(concept)) self.identifiers_key = {} # number of identifiers with the same root (prefix) def matches(self, context, return_value): if not return_value.status: return False if not isinstance(return_value.value, ParserResultConcept): return False value = return_value.value.value if isinstance(value, (ConceptNode, SourceCodeNode)): return True if hasattr(value, "__iter__"): for node in value: if not isinstance(node, (ConceptNode, SourceCodeNode)): return False return True return False def eval(self, context, return_value): """ From a concept node, creates a new concept and makes sure that the properties are correctly set """ nodes = return_value.value.value if not hasattr(nodes, "__iter__"): nodes = [nodes] context.log(f"{nodes=}", self.name) for node in nodes: if isinstance(node, SourceCodeNode): ret = self.evaluate_python_code(context, nodes) break else: ret = self.evaluate_concepts_only(context, nodes) ret.parents = [return_value] return ret def evaluate_concepts_only(self, context, nodes): concepts = [] source = "" sheerka = context.sheerka for node in nodes: if isinstance(node, ConceptNode): source += node.source if source == "" else (" " + node.source) concepts.append(node.concept) if len(concepts) == 1: return sheerka.ret( self.name, True, context.sheerka.new( BuiltinConcepts.PARSER_RESULT, parser=self, source=source, body=concepts[0], try_parsed=None)) return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=nodes)) def evaluate_python_code(self, context, nodes): sheerka = context.sheerka helper = LexerNodeParserHelperForPython() result = helper.parse(context, nodes) if isinstance(result, PythonNode): return sheerka.ret( self.name, True, sheerka.new( BuiltinConcepts.PARSER_RESULT, parser=self, source=result.source, body=result, try_parsed=None)) else: return sheerka.ret( self.name, False, result.body)