Fixed EvalEvaluator when there is nothing to evaluate

This commit is contained in:
2019-12-27 14:43:36 +01:00
parent 21da87393f
commit 81b2355633
5 changed files with 97 additions and 15 deletions
+19 -1
View File
@@ -749,4 +749,22 @@ The ParsingExpression
The [Non]TerminalNode The [Non]TerminalNode
represents what was found. So similarly to the ConceptNode, you will find the start, end and token attributes represents what was found. So similarly to the ConceptNode, you will find the start, end and token attributes
That's all for today ! That's all for today !
2019-27-12
**********
How to manage variables resolutions
"""""""""""""""""""""""""""""""""""
I have to admit that I am a little bit stuck with how to manage variable resolution with PythonEvaluator.
What is expected by the expression depends on the expression itself.
Let's see an example
::
def concept one as 1
def concept two as 2
eval one + two
+16 -11
View File
@@ -12,8 +12,6 @@ class EvalEvaluator(AllReturnValuesEvaluator):
def __init__(self): def __init__(self):
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80) super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80)
self.successful_return_value = None
self.to_eval = []
self.eval_requested = None self.eval_requested = None
def matches(self, context, return_values): def matches(self, context, return_values):
@@ -21,18 +19,25 @@ class EvalEvaluator(AllReturnValuesEvaluator):
for ret in return_values: for ret in return_values:
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED): if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED):
self.eval_requested = ret self.eval_requested = ret
elif ret.status and isinstance(ret.body, Concept) and ret.body.body: return True
self.to_eval.append(ret)
return self.eval_requested is not None and len(self.to_eval) > 0 return False
def eval(self, context, return_value): def eval(self, context, return_values):
sheerka = context.sheerka sheerka = context.sheerka
result = [] result = []
context.log(self.verbose_log, f"{len(self.to_eval)} return value(s) to eval", who=self)
for ret_val in self.to_eval: for ret_val in return_values:
context.log(self.verbose_log, f"{ret_val}", who=self) if ret_val.status and isinstance(ret_val.body, Concept) and ret_val.body.body:
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested])) context.log(self.verbose_log, f"Evaluating {ret_val}", who=self)
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested]))
return result if len(result) > 0:
return result
else:
# suppress the successful BuiltinConcepts.CONCEPT_EVAL_REQUESTED
return sheerka.ret(
self.name,
False,
sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED),
parents=[self.eval_requested])
+24 -3
View File
@@ -49,11 +49,32 @@ def test_i_can_match_and_eval():
@pytest.mark.parametrize("return_values, expected", [ @pytest.mark.parametrize("return_values, expected", [
([r(Concept("foo", body="bar")), eval_requested], True), ([r(Concept("foo", body="bar")), eval_requested], True),
([r(Concept("status is false", body="bar"), False), eval_requested], False), ([r(Concept("status is false", body="bar"), False), eval_requested], True),
([r("string_value"), eval_requested], False), ([r("string_value"), eval_requested], True),
([r(Concept("no body")), eval_requested], False), ([r(Concept("no body")), eval_requested], True),
([r(Concept("eval requested missing", body="bar"))], False), ([r(Concept("eval requested missing", body="bar"))], False),
]) ])
def test_i_cannot_match_if_eval_request_is_not_present(return_values, expected): def test_i_cannot_match_if_eval_request_is_not_present(return_values, expected):
context = get_context() context = get_context()
assert EvalEvaluator().matches(context, return_values) == expected assert EvalEvaluator().matches(context, return_values) == expected
def test_concept_eval_requested_is_reduced_when_nothing_to_reduce():
context = get_context()
return_values = [
ReturnValueConcept("some_name", True, "not to eval"),
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
eval_requested
]
evaluator = EvalEvaluator()
assert evaluator.matches(context, return_values)
evaluated = evaluator.eval(context, return_values)
assert evaluated == ReturnValueConcept(
"evaluators.Eval",
False,
context.sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
assert evaluated.parents == [eval_requested]
+22
View File
@@ -162,6 +162,28 @@ class EvaluatorAllReduceFooBar(EvaluatorAllWithPriority):
return ret return ret
class EvaluatorAllSuppressFooEntry(EvaluatorAllWithPriority):
def __init__(self):
super().__init__("suppress", 100)
def matches(self, context, return_values):
super().matches(context, return_values)
return True
def eval(self, context, return_values):
super().eval(context, return_values)
foo = None
for ret in return_values:
if ret.body.name == "foo":
foo = ret
if foo:
return context.sheerka.ret(self.name, False, Concept("does not matter"), parents=[foo])
else:
return None
def test_that_return_values_is_unchanged_when_no_evaluator(): def test_that_return_values_is_unchanged_when_no_evaluator():
sheerka = get_sheerka() sheerka = get_sheerka()
sheerka.evaluators = [] sheerka.evaluators = []
+16
View File
@@ -400,3 +400,19 @@ def test_i_can_say_that_a_concept_isa_another_concept():
res = sheerka.evaluate_user_input("foo isa bar") res = sheerka.evaluate_user_input("foo isa bar")
assert res[0].status assert res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS) assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
def test_eval_does_not_break_valid_result():
sheerka = get_sheerka()
sheerka.evaluate_user_input("def concept one as 1")
sheerka.evaluate_user_input("def concept two as 2")
res = sheerka.evaluate_user_input("one + two")
assert len(res) == 1
assert res[0].status
assert res[0].body == 3
res = sheerka.evaluate_user_input("eval one + two")
assert len(res) == 1
assert res[0].status
assert res[0].body == 3