Refactored to use a single implementation for concept evaluation
This commit is contained in:
@@ -3,6 +3,7 @@ from core.builtin_concepts import ParserResultConcept, ReturnValueConcept
|
||||
from core.builtin_helpers import get_names
|
||||
from core.concept import Concept
|
||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||
from parsers.BaseParser import NotInitializedNode
|
||||
from parsers.ConceptLexerParser import ParsingExpression, ParsingExpressionVisitor
|
||||
from parsers.DefaultParser import DefConceptNode
|
||||
|
||||
@@ -58,7 +59,7 @@ class AddConceptEvaluator(OneReturnValueEvaluator):
|
||||
# put back the sources
|
||||
part_ret_val = getattr(def_concept_node, prop)
|
||||
if not isinstance(part_ret_val, ReturnValueConcept) or not part_ret_val.status:
|
||||
continue # not quite sure that it's possible
|
||||
continue # Nothing to do is not initialized
|
||||
|
||||
# update the parts
|
||||
source = self.get_source(part_ret_val)
|
||||
@@ -82,7 +83,8 @@ class AddConceptEvaluator(OneReturnValueEvaluator):
|
||||
# finish initialisation
|
||||
concept.init_key(def_concept_node.name.tokens)
|
||||
concept.add_codes(def_concept_node.get_asts())
|
||||
if sheerka.is_success(def_concept_node.definition):
|
||||
if not isinstance(def_concept_node.definition, NotInitializedNode) and \
|
||||
sheerka.is_success(def_concept_node.definition):
|
||||
concept.bnf = def_concept_node.definition.value.value
|
||||
|
||||
ret = sheerka.create_new_concept(context, concept)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
|
||||
import core.builtin_helpers
|
||||
from core.concept import Concept, ConceptParts
|
||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||
|
||||
@@ -31,42 +30,25 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
||||
concept = return_value.value.value
|
||||
context.log(self.verbose_log, f"Evaluating concept {concept}.", self.name)
|
||||
|
||||
# pre condition should already be validated by the parser.
|
||||
# It's a mandatory condition for the concept before it can be recognized
|
||||
# If the concept that is requested is in the context(at least its name), drop the call.
|
||||
# Why ?
|
||||
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
||||
# The body should be 'property_a', and not a concept called a in our universe
|
||||
if context.obj and concept.name in context.obj.props:
|
||||
return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.NOT_FOR_ME), parents=[return_value])
|
||||
|
||||
if len(concept.cached_asts) == 0:
|
||||
sheerka.initialize_concept_asts(context, concept, self.verbose_log)
|
||||
evaluated = sheerka.evaluate_concept(context, concept, self.verbose_log)
|
||||
|
||||
# TODO; check pre
|
||||
# if pre is not true, return Concept with a false value
|
||||
if evaluated.key != concept.key:
|
||||
# evaluated.key != concept.key means that we have transformed the concept
|
||||
# When you successfully evaluate an error, the status should not be false
|
||||
return sheerka.ret(
|
||||
self.name,
|
||||
False,
|
||||
evaluated,
|
||||
parents=[return_value])
|
||||
|
||||
# Evaluate the properties
|
||||
for prop in concept.props:
|
||||
sub_context = context.push(self.name, desc=f"Evaluating property '{prop}'", obj=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, desc="Evaluating body", obj=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.execute(context, parsing_result, self.evaluation_steps, self.log)
|
||||
res = core.builtin_helpers.expect_one(context, res)
|
||||
return res
|
||||
if ConceptParts.BODY not in evaluated.cached_asts:
|
||||
return sheerka.ret(self.name, True, evaluated, parents=[return_value])
|
||||
else:
|
||||
return sheerka.ret(self.name, True, evaluated.body, parents=[return_value])
|
||||
|
||||
@@ -54,7 +54,8 @@ class ConceptNodeEvaluator(OneReturnValueEvaluator):
|
||||
|
||||
def update_concept(self, sheerka, concept, underlying, init_empty_body=True):
|
||||
"""
|
||||
Updates the property of the concept
|
||||
Updates the properties of the concept
|
||||
Goes in recursion if the property is a concept
|
||||
"""
|
||||
|
||||
def _add_prop(c, prop_name, value):
|
||||
|
||||
@@ -28,6 +28,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
node = return_value.value.value
|
||||
try:
|
||||
context.log(self.verbose_log, f"Evaluating python node {node}.", self.name)
|
||||
|
||||
my_locals = self.get_locals(context, node.ast_)
|
||||
context.log(self.verbose_log, f"locals={my_locals}", self.name)
|
||||
|
||||
@@ -51,6 +52,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
if context.obj:
|
||||
context.log(self.verbose_log,
|
||||
f"Concept '{context.obj}' is in context. Adding its properties to locals if any.", self.name)
|
||||
|
||||
for prop_name, prop_value in context.obj.props.items():
|
||||
my_locals[prop_name] = prop_value.value
|
||||
|
||||
@@ -60,18 +62,23 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
||||
|
||||
for name in unreferenced_names_visitor.names:
|
||||
context.log(self.verbose_log, f"Resolving '{name}'.", self.name)
|
||||
|
||||
if name in my_locals:
|
||||
context.log(self.verbose_log, f"Using value from property.", self.name)
|
||||
continue
|
||||
|
||||
concept = context.sheerka.new(name)
|
||||
if context.sheerka.isinstance(concept, BuiltinConcepts.UNKNOWN_CONCEPT):
|
||||
context.log(self.verbose_log, f"'{name}' is not a concept. Skipping.", self.name)
|
||||
continue
|
||||
|
||||
context.log(self.verbose_log, f"'{name}' is a concept. Evaluating body.", self.name)
|
||||
sub_context = context.push(self.name, desc=f"Evaluating {concept}'s body", obj=concept)
|
||||
context.log(self.verbose_log, f"'{name}' is a concept. Evaluating.", self.name)
|
||||
sub_context = context.push(self.name, desc=f"Evaluating '{concept}'", obj=concept)
|
||||
sub_context.log_new(self.verbose_log)
|
||||
context.sheerka.eval_concept(sub_context, concept, ["body"], self.verbose_log)
|
||||
evaluated = context.sheerka.evaluate_concept(sub_context, concept, self.verbose_log)
|
||||
|
||||
if not context.sheerka.isa(concept.body, BuiltinConcepts.ERROR):
|
||||
my_locals[name] = concept.body
|
||||
if evaluated.key == concept.key:
|
||||
my_locals[name] = evaluated.body or evaluated
|
||||
|
||||
return my_locals
|
||||
|
||||
|
||||
Reference in New Issue
Block a user