Added simple form of concept composition

This commit is contained in:
2020-01-15 18:38:29 +01:00
parent 51fa9629d0
commit 8152f82c6b
22 changed files with 1105 additions and 544 deletions
+102
View File
@@ -0,0 +1,102 @@
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
from evaluators.BaseEvaluator import OneReturnValueEvaluator
from parsers.ConceptLexerParser import ConceptNode, UnrecognizedTokensNode, SourceCodeNode
from parsers.PythonParser import LexerNodeParserHelperForPython, PythonNode
class LexerNodeEvaluator(OneReturnValueEvaluator):
"""
After a BNF is recognized, generates the concept or the list concepts
"""
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(self.verbose_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)