Refactored to use cached_asts in Concepts, rather than setting up a value directly
This commit is contained in:
@@ -293,3 +293,16 @@ class Property:
|
|||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash((self.name, self.value))
|
return hash((self.name, self.value))
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass()
|
||||||
|
class DoNotResolve:
|
||||||
|
"""
|
||||||
|
This class is used to that the metadata (or the prop) of the concept must not be evaluated
|
||||||
|
thru sheerka.execute
|
||||||
|
|
||||||
|
For example, if you want to set a value to the BODY that will not change when
|
||||||
|
when the concept will be evaluated,
|
||||||
|
set concept.cached_asts[BODY] to DoNotResolve(value)
|
||||||
|
"""
|
||||||
|
value: object
|
||||||
|
|||||||
+74
-30
@@ -1,5 +1,5 @@
|
|||||||
from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConcept, BuiltinErrors, BuiltinUnique
|
from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConcept, BuiltinErrors, BuiltinUnique
|
||||||
from core.concept import Concept, ConceptParts, PROPERTIES_FOR_NEW
|
from core.concept import Concept, ConceptParts, PROPERTIES_FOR_NEW, DoNotResolve
|
||||||
from parsers.BaseParser import BaseParser
|
from parsers.BaseParser import BaseParser
|
||||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event, SheerkaDataProviderDuplicateKeyError
|
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event, SheerkaDataProviderDuplicateKeyError
|
||||||
import core.utils
|
import core.utils
|
||||||
@@ -551,6 +551,9 @@ class Sheerka(Concept):
|
|||||||
"""
|
"""
|
||||||
steps = [BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.PARSING, BuiltinConcepts.AFTER_PARSING]
|
steps = [BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.PARSING, BuiltinConcepts.AFTER_PARSING]
|
||||||
for part_key in ConceptParts:
|
for part_key in ConceptParts:
|
||||||
|
if part_key in concept.cached_asts:
|
||||||
|
continue
|
||||||
|
|
||||||
source = getattr(concept.metadata, part_key.value)
|
source = getattr(concept.metadata, part_key.value)
|
||||||
if source is None or not isinstance(source, str) or source == "":
|
if source is None or not isinstance(source, str) or source == "":
|
||||||
# the only sources that I am sure to parse are strings
|
# the only sources that I am sure to parse are strings
|
||||||
@@ -565,6 +568,9 @@ class Sheerka(Concept):
|
|||||||
sub_context.add_values(return_values=res)
|
sub_context.add_values(return_values=res)
|
||||||
|
|
||||||
for prop in concept.props:
|
for prop in concept.props:
|
||||||
|
if prop in concept.cached_asts:
|
||||||
|
continue
|
||||||
|
|
||||||
value = concept.props[prop].value
|
value = concept.props[prop].value
|
||||||
if value:
|
if value:
|
||||||
if isinstance(value, Concept):
|
if isinstance(value, Concept):
|
||||||
@@ -604,14 +610,65 @@ class Sheerka(Concept):
|
|||||||
if concept.metadata.is_evaluated:
|
if concept.metadata.is_evaluated:
|
||||||
return concept
|
return concept
|
||||||
|
|
||||||
def _resolve(return_value, desc, obj):
|
def _resolve(to_resolve, current_prop, current_concept):
|
||||||
|
if isinstance(to_resolve, DoNotResolve):
|
||||||
|
return to_resolve.value
|
||||||
|
|
||||||
|
desc = f"Evaluating {current_prop} (concept={current_concept})"
|
||||||
context.log(logger, desc, self.evaluate_concept.__name__)
|
context.log(logger, desc, self.evaluate_concept.__name__)
|
||||||
with context.push(desc=desc, obj=obj) as sub_context:
|
with context.push(desc=desc, obj=current_concept) as sub_context:
|
||||||
sub_context.log_new(logger)
|
sub_context.log_new(logger)
|
||||||
r = self.execute(sub_context, return_value, CONCEPT_EVALUATION_STEPS, logger)
|
|
||||||
|
# when it's a concept, evaluate it
|
||||||
|
if isinstance(to_resolve, Concept):
|
||||||
|
evaluated = self.evaluate_concept(sub_context, to_resolve)
|
||||||
|
sub_context.add_values(return_values=evaluated)
|
||||||
|
if evaluated.key == to_resolve.key:
|
||||||
|
return evaluated
|
||||||
|
else:
|
||||||
|
error = evaluated
|
||||||
|
|
||||||
|
# otherwise, execute all return values to find out what is the value
|
||||||
|
else:
|
||||||
|
r = self.execute(sub_context, to_resolve, CONCEPT_EVALUATION_STEPS, logger)
|
||||||
one_r = core.builtin_helpers.expect_one(context, r)
|
one_r = core.builtin_helpers.expect_one(context, r)
|
||||||
sub_context.add_values(return_values=one_r)
|
sub_context.add_values(return_values=one_r)
|
||||||
return one_r
|
if one_r.status:
|
||||||
|
return one_r.value
|
||||||
|
else:
|
||||||
|
error = one_r.value
|
||||||
|
|
||||||
|
return self.new(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||||
|
body=error,
|
||||||
|
concept=concept,
|
||||||
|
property_name=prop_name)
|
||||||
|
|
||||||
|
def _resolve_list(sheerka, list_to_resolve, current_prop, current_concept):
|
||||||
|
"""When dealing with a list, there are two possibilities"""
|
||||||
|
# It may be a list of ReturnValueConcept to execute (always the case for metadata)
|
||||||
|
# or a list of single values (may be the case for properties)
|
||||||
|
# in this latter case, all values are to be processed one by one and a list should be returned
|
||||||
|
if len(list_to_resolve) == 0:
|
||||||
|
return []
|
||||||
|
|
||||||
|
if sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE):
|
||||||
|
return _resolve(list_to_resolve, current_prop, current_concept)
|
||||||
|
|
||||||
|
res = []
|
||||||
|
for to_resolve in list_to_resolve:
|
||||||
|
# sanity check
|
||||||
|
if sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE):
|
||||||
|
return self.new(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||||
|
body="Mix between real values and return values",
|
||||||
|
concept=concept,
|
||||||
|
property_name=prop_name)
|
||||||
|
|
||||||
|
r = _resolve(to_resolve, current_prop, current_concept)
|
||||||
|
if sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR):
|
||||||
|
return r
|
||||||
|
res.append(r)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
# WHERE condition should already be validated by the parser.
|
# WHERE condition should already be validated by the parser.
|
||||||
# It's a mandatory condition for the concept before it can be recognized
|
# It's a mandatory condition for the concept before it can be recognized
|
||||||
@@ -620,8 +677,6 @@ class Sheerka(Concept):
|
|||||||
# TODO : Validate the PRE condition
|
# TODO : Validate the PRE condition
|
||||||
#
|
#
|
||||||
|
|
||||||
if len(concept.cached_asts) == 0:
|
|
||||||
context.log(logger, "concept asts are not initialized. Initializing.", self.evaluate_concept.__name__)
|
|
||||||
self.initialize_concept_asts(context, concept, logger)
|
self.initialize_concept_asts(context, concept, logger)
|
||||||
|
|
||||||
# to make sure of the order, it don't use ConceptParts.get_parts()
|
# to make sure of the order, it don't use ConceptParts.get_parts()
|
||||||
@@ -632,35 +687,24 @@ class Sheerka(Concept):
|
|||||||
if metadata_to_eval == "props":
|
if metadata_to_eval == "props":
|
||||||
for prop_name in (p for p in concept.props if p in concept.cached_asts):
|
for prop_name in (p for p in concept.props if p in concept.cached_asts):
|
||||||
prop_ast = concept.cached_asts[prop_name]
|
prop_ast = concept.cached_asts[prop_name]
|
||||||
if isinstance(concept.cached_asts[prop_name], Concept):
|
|
||||||
context.log(
|
if isinstance(prop_ast, list):
|
||||||
logger, f"Evaluation prop={prop_name}, value={prop_ast}", self.evaluate_concept.__name__)
|
resolved = _resolve_list(context.sheerka, prop_ast, prop_name, None)
|
||||||
with context.push(f"Evaluation property '{prop_name}', value='{prop_ast}'") as sub_context:
|
|
||||||
sub_context.log_new(logger)
|
|
||||||
evaluated = self.evaluate_concept(sub_context, prop_ast)
|
|
||||||
sub_context.add_values(return_values=evaluated)
|
|
||||||
concept.set_prop(prop_name, evaluated)
|
|
||||||
else:
|
else:
|
||||||
res = _resolve(prop_ast, f"Evaluating property '{prop_name}'", None)
|
resolved = _resolve(prop_ast, prop_name, None)
|
||||||
if res.status:
|
if context.sheerka.isinstance(resolved, BuiltinConcepts.CONCEPT_EVAL_ERROR):
|
||||||
concept.set_prop(prop_name, res.value)
|
return resolved
|
||||||
else:
|
else:
|
||||||
return self.new(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
concept.set_prop(prop_name, resolved)
|
||||||
body=res.value,
|
|
||||||
concept=concept,
|
|
||||||
property_name=prop_name)
|
|
||||||
else:
|
else:
|
||||||
part_key = ConceptParts(metadata_to_eval)
|
part_key = ConceptParts(metadata_to_eval)
|
||||||
|
|
||||||
if part_key in concept.cached_asts and concept.cached_asts[part_key] is not None:
|
if part_key in concept.cached_asts and concept.cached_asts[part_key] is not None:
|
||||||
res = _resolve(concept.cached_asts[part_key], f"Evaluating '{part_key}'", concept)
|
metadata_ast = concept.cached_asts[part_key]
|
||||||
if res.status:
|
resolved = _resolve(metadata_ast, part_key, concept)
|
||||||
setattr(concept.metadata, metadata_to_eval, res.value)
|
if context.sheerka.isinstance(resolved, BuiltinConcepts.CONCEPT_EVAL_ERROR):
|
||||||
|
return resolved
|
||||||
else:
|
else:
|
||||||
return self.new(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
setattr(concept.metadata, metadata_to_eval, resolved)
|
||||||
body=res.value,
|
|
||||||
concept=concept,
|
|
||||||
property_name=part_key)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# TODO : Validate the POST condition
|
# TODO : Validate the POST condition
|
||||||
|
|||||||
@@ -107,9 +107,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
|||||||
sub_context.add_values(return_values=evaluated)
|
sub_context.add_values(return_values=evaluated)
|
||||||
|
|
||||||
if evaluated.key == concept.key:
|
if evaluated.key == concept.key:
|
||||||
my_locals[name] = evaluated if return_concept else \
|
my_locals[name] = evaluated if return_concept else context.sheerka.value(evaluated)
|
||||||
evaluated.body if ConceptParts.BODY in evaluated.cached_asts else \
|
|
||||||
evaluated
|
|
||||||
|
|
||||||
if self.locals:
|
if self.locals:
|
||||||
my_locals.update(self.locals)
|
my_locals.update(self.locals)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
from dataclasses import field, dataclass
|
from dataclasses import field, dataclass
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from core.concept import Concept
|
from core.concept import Concept, ConceptParts, DoNotResolve
|
||||||
from core.tokenizer import TokenKind, Tokenizer, Token
|
from core.tokenizer import TokenKind, Tokenizer, Token
|
||||||
from parsers.BaseParser import BaseParser, Node, ErrorNode
|
from parsers.BaseParser import BaseParser, Node, ErrorNode
|
||||||
import core.utils
|
import core.utils
|
||||||
@@ -702,6 +702,9 @@ class ConceptLexerParser(BaseParser):
|
|||||||
else:
|
else:
|
||||||
to_match = node.concept
|
to_match = node.concept
|
||||||
|
|
||||||
|
if to_match not in self.concepts_grammars:
|
||||||
|
return False
|
||||||
|
|
||||||
return _is_infinite_recursion(ref_concept, self.concepts_grammars[to_match])
|
return _is_infinite_recursion(ref_concept, self.concepts_grammars[to_match])
|
||||||
|
|
||||||
if isinstance(node, OrderedChoice):
|
if isinstance(node, OrderedChoice):
|
||||||
@@ -847,17 +850,17 @@ class ConceptLexerParser(BaseParser):
|
|||||||
Adds a new entry,
|
Adds a new entry,
|
||||||
makes a list if the property already exists
|
makes a list if the property already exists
|
||||||
"""
|
"""
|
||||||
if prop_name not in _concept.props or _concept.props[prop_name].value is None:
|
if prop_name not in _concept.cached_asts or _concept.cached_asts[prop_name] is None:
|
||||||
# new entry
|
# new entry
|
||||||
_concept.set_prop(prop_name, value)
|
_concept.cached_asts[prop_name] = value
|
||||||
else:
|
else:
|
||||||
# make a list if there was a value
|
# make a list if there was a value
|
||||||
previous_value = _concept.props[prop_name].value
|
previous_value = _concept.cached_asts[prop_name]
|
||||||
if isinstance(previous_value, list):
|
if isinstance(previous_value, list):
|
||||||
previous_value.append(value)
|
previous_value.append(value)
|
||||||
else:
|
else:
|
||||||
new_value = [previous_value, value]
|
new_value = [previous_value, value]
|
||||||
_concept.set_prop(prop_name, new_value)
|
_concept.cached_asts[prop_name] = new_value
|
||||||
|
|
||||||
def _look_for_concept_match(_underlying):
|
def _look_for_concept_match(_underlying):
|
||||||
if isinstance(_underlying.parsing_expression, ConceptMatch):
|
if isinstance(_underlying.parsing_expression, ConceptMatch):
|
||||||
@@ -881,7 +884,7 @@ class ConceptLexerParser(BaseParser):
|
|||||||
result = self.finalize_concept(sheerka, ref_tpl, concept_match_node.children[0], init_empty_body)
|
result = self.finalize_concept(sheerka, ref_tpl, concept_match_node.children[0], init_empty_body)
|
||||||
_underlying_value_cache[id(concept_match_node)] = result
|
_underlying_value_cache[id(concept_match_node)] = result
|
||||||
else:
|
else:
|
||||||
result = _underlying.source
|
result = DoNotResolve(_underlying.source)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -898,8 +901,7 @@ class ConceptLexerParser(BaseParser):
|
|||||||
concept = sheerka.new(key)
|
concept = sheerka.new(key)
|
||||||
if init_empty_body and concept.body is None:
|
if init_empty_body and concept.body is None:
|
||||||
value = _get_underlying_value(underlying)
|
value = _get_underlying_value(underlying)
|
||||||
concept.metadata.body = value
|
concept.cached_asts[ConceptParts.BODY] = value
|
||||||
concept.metadata.is_evaluated = True
|
|
||||||
if underlying.parsing_expression.rule_name:
|
if underlying.parsing_expression.rule_name:
|
||||||
_add_prop(concept, underlying.parsing_expression.rule_name, value)
|
_add_prop(concept, underlying.parsing_expression.rule_name, value)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import core.utils
|
import core.utils
|
||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from core.concept import Concept
|
from core.concept import Concept, ConceptParts, DoNotResolve
|
||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from core.tokenizer import Tokenizer, TokenKind, Token
|
from core.tokenizer import Tokenizer, TokenKind, Token
|
||||||
from parsers.ConceptLexerParser import ConceptLexerParser, ConceptNode, Sequence, StrMatch, OrderedChoice, Optional, \
|
from parsers.ConceptLexerParser import ConceptLexerParser, ConceptNode, Sequence, StrMatch, OrderedChoice, Optional, \
|
||||||
@@ -58,7 +58,20 @@ def get_context():
|
|||||||
|
|
||||||
|
|
||||||
def get_expected(concept, text=None):
|
def get_expected(concept, text=None):
|
||||||
return Concept(name=concept.name, body=text or concept.name).init_key()
|
c = Concept(name=concept.name)
|
||||||
|
c.cached_asts[ConceptParts.BODY] = DoNotResolve(text or concept.name)
|
||||||
|
c.init_key()
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
def cbody(concept):
|
||||||
|
"""cbody stands for compiled body"""
|
||||||
|
return concept.cached_asts[ConceptParts.BODY]
|
||||||
|
|
||||||
|
|
||||||
|
def cprop(concept, prop_name):
|
||||||
|
"""cbody stands for compiled property"""
|
||||||
|
return concept.cached_asts[prop_name]
|
||||||
|
|
||||||
|
|
||||||
def init(concepts, grammar):
|
def init(concepts, grammar):
|
||||||
@@ -359,20 +372,15 @@ def test_i_can_use_reference():
|
|||||||
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[0].value.body == [("foo", 0, 2, "one two")]
|
assert res[0].value.body == [("foo", 0, 2, "one two")]
|
||||||
concept_found_1 = res[0].value.body[0].concept
|
concept_found_1 = res[0].value.body[0].concept
|
||||||
assert concept_found_1.metadata.is_evaluated
|
assert cbody(concept_found_1) == DoNotResolve("one two")
|
||||||
assert concept_found_1.body == "one two"
|
|
||||||
|
|
||||||
assert res[1].status
|
assert res[1].status
|
||||||
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[1].value.body == [("bar", 0, 2, "one two")]
|
assert res[1].value.body == [("bar", 0, 2, "one two")]
|
||||||
concept_found_2 = res[1].value.body[0].concept
|
concept_found_2 = res[1].value.body[0].concept
|
||||||
assert concept_found_2.metadata.is_evaluated
|
|
||||||
# the body and the prop['foo'] are the same concept 'foo'
|
# the body and the prop['foo'] are the same concept 'foo'
|
||||||
assert isinstance(concept_found_2.body, Concept)
|
assert cbody(concept_found_2) == get_expected(foo, "one two")
|
||||||
assert concept_found_2.body.key == "foo"
|
assert id(cprop(concept_found_2, "foo")) == id(cbody(concept_found_2))
|
||||||
assert concept_found_2.body.metadata.is_evaluated
|
|
||||||
assert concept_found_2.body.body == "one two"
|
|
||||||
assert id(concept_found_2.props["foo"].value) == id(concept_found_2.body)
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_use_a_reference_with_a_body():
|
def test_i_can_use_a_reference_with_a_body():
|
||||||
@@ -394,20 +402,15 @@ def test_i_can_use_a_reference_with_a_body():
|
|||||||
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[0].value.body == [("foo", 0, 2, "one two")]
|
assert res[0].value.body == [("foo", 0, 2, "one two")]
|
||||||
concept_found_1 = res[0].value.body[0].concept
|
concept_found_1 = res[0].value.body[0].concept
|
||||||
assert not concept_found_1.metadata.is_evaluated
|
|
||||||
assert concept_found_1.body == "'foo'"
|
assert concept_found_1.body == "'foo'"
|
||||||
|
|
||||||
assert res[1].status
|
assert res[1].status
|
||||||
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[1].value.body == [("bar", 0, 2, "one two")]
|
assert res[1].value.body == [("bar", 0, 2, "one two")]
|
||||||
concept_found_2 = res[1].value.body[0].concept
|
concept_found_2 = res[1].value.body[0].concept
|
||||||
assert concept_found_2.metadata.is_evaluated
|
|
||||||
# the body and the prop['foo'] are the same concept 'foo'
|
# the body and the prop['foo'] are the same concept 'foo'
|
||||||
assert isinstance(concept_found_2.body, Concept)
|
assert cbody(concept_found_2) == foo
|
||||||
assert concept_found_2.body.key == "foo"
|
assert id(cprop(concept_found_2, "foo")) == id(cbody(concept_found_2))
|
||||||
assert not concept_found_2.body.metadata.is_evaluated
|
|
||||||
assert concept_found_2.body.body == "'foo'"
|
|
||||||
assert id(concept_found_2.props["foo"].value) == id(concept_found_2.body)
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_use_context_reference_with_multiple_levels():
|
def test_i_can_use_context_reference_with_multiple_levels():
|
||||||
@@ -429,23 +432,23 @@ def test_i_can_use_context_reference_with_multiple_levels():
|
|||||||
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[0].value.body == [("foo", 0, 2, "one two")]
|
assert res[0].value.body == [("foo", 0, 2, "one two")]
|
||||||
concept_found_1 = res[0].value.body[0].concept
|
concept_found_1 = res[0].value.body[0].concept
|
||||||
assert concept_found_1.body == "one two"
|
assert cbody(concept_found_1) == DoNotResolve("one two")
|
||||||
assert concept_found_1.metadata.is_evaluated
|
|
||||||
|
|
||||||
assert res[1].status
|
assert res[1].status
|
||||||
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[1].value.body == [("bar", 0, 2, "one two")]
|
assert res[1].value.body == [("bar", 0, 2, "one two")]
|
||||||
concept_found_2 = res[1].value.body[0].concept
|
concept_found_2 = res[1].value.body[0].concept
|
||||||
assert concept_found_2.body == get_expected(foo, "one two")
|
assert cbody(concept_found_2) == get_expected(foo, "one two")
|
||||||
assert id(concept_found_2.props["foo"].value) == id(concept_found_2.body)
|
assert id(cprop(concept_found_2, "foo")) == id(cbody(concept_found_2))
|
||||||
|
|
||||||
assert res[2].status
|
assert res[2].status
|
||||||
assert context.sheerka.isinstance(res[2].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[2].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[2].value.body == [("baz", 0, 2, "one two")]
|
assert res[2].value.body == [("baz", 0, 2, "one two")]
|
||||||
concept_found_3 = res[2].value.body[0].concept
|
concept_found_3 = res[2].value.body[0].concept
|
||||||
expected_foo = get_expected(foo, "one two")
|
expected_foo = get_expected(foo, "one two")
|
||||||
assert concept_found_3.body == get_expected(bar, expected_foo).set_prop("foo", expected_foo)
|
assert cbody(concept_found_3) == get_expected(bar, expected_foo)
|
||||||
assert id(concept_found_3.props["bar"].value) == id(concept_found_3.body)
|
assert cprop(concept_found_3, "foo") == expected_foo
|
||||||
|
assert id(cprop(concept_found_3, "bar")) == id(cbody(concept_found_3))
|
||||||
|
|
||||||
|
|
||||||
def test_order_is_not_important_when_using_references():
|
def test_order_is_not_important_when_using_references():
|
||||||
@@ -476,26 +479,21 @@ def test_i_can_parse_when_reference():
|
|||||||
assert res.status
|
assert res.status
|
||||||
assert res.value.body == [("bar", 0, 2, "twenty two")]
|
assert res.value.body == [("bar", 0, 2, "twenty two")]
|
||||||
concept_found = res.value.body[0].concept
|
concept_found = res.value.body[0].concept
|
||||||
assert concept_found.body == "twenty two"
|
assert cbody(concept_found) == DoNotResolve("twenty two")
|
||||||
assert concept_found.metadata.is_evaluated
|
assert cprop(concept_found, "foo") == get_expected(foo, "twenty")
|
||||||
assert concept_found.get_prop("foo") == get_expected(foo, "twenty")
|
|
||||||
assert concept_found.get_prop("foo").metadata.is_evaluated
|
|
||||||
|
|
||||||
res = parser.parse(context, "thirty one")
|
res = parser.parse(context, "thirty one")
|
||||||
assert res.status
|
assert res.status
|
||||||
assert res.value.body == [("bar", 0, 2, "thirty one")]
|
assert res.value.body == [("bar", 0, 2, "thirty one")]
|
||||||
concept_found = res.value.body[0].concept
|
concept_found = res.value.body[0].concept
|
||||||
assert concept_found.body == "thirty one"
|
assert cbody(concept_found) == DoNotResolve("thirty one")
|
||||||
assert concept_found.metadata.is_evaluated
|
assert cprop(concept_found, "foo") == get_expected(foo, "thirty")
|
||||||
assert concept_found.get_prop("foo") == get_expected(foo, "thirty")
|
|
||||||
assert concept_found.get_prop("foo").metadata.is_evaluated
|
|
||||||
|
|
||||||
res = parser.parse(context, "twenty")
|
res = parser.parse(context, "twenty")
|
||||||
assert res.status
|
assert res.status
|
||||||
assert res.value.body == [("foo", 0, 0, "twenty")]
|
assert res.value.body == [("foo", 0, 0, "twenty")]
|
||||||
concept_found = res.value.body[0].concept
|
concept_found = res.value.body[0].concept
|
||||||
assert concept_found.body == "twenty"
|
assert cbody(concept_found) == DoNotResolve("twenty")
|
||||||
assert concept_found.metadata.is_evaluated
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_parse_when_reference_has_a_body():
|
def test_i_can_parse_when_reference_has_a_body():
|
||||||
@@ -508,17 +506,14 @@ def test_i_can_parse_when_reference_has_a_body():
|
|||||||
assert res.status
|
assert res.status
|
||||||
assert res.value.body == [("bar", 0, 2, "twenty two")]
|
assert res.value.body == [("bar", 0, 2, "twenty two")]
|
||||||
concept_found = res.value.body[0].concept
|
concept_found = res.value.body[0].concept
|
||||||
assert concept_found.body == "twenty two"
|
assert cbody(concept_found) == DoNotResolve("twenty two")
|
||||||
assert concept_found.metadata.is_evaluated
|
assert cprop(concept_found, "foo") == foo
|
||||||
assert concept_found.get_prop("foo") == get_expected(foo, "'one'")
|
|
||||||
assert not concept_found.get_prop("foo").metadata.is_evaluated
|
|
||||||
|
|
||||||
res = parser.parse(context, "twenty")
|
res = parser.parse(context, "twenty")
|
||||||
assert res.status
|
assert res.status
|
||||||
assert res.value.body == [("foo", 0, 0, "twenty")]
|
assert res.value.body == [("foo", 0, 0, "twenty")]
|
||||||
concept_found = res.value.body[0].concept
|
concept_found = res.value.body[0].concept
|
||||||
assert concept_found.body == "'one'"
|
assert concept_found.body == "'one'"
|
||||||
assert not concept_found.metadata.is_evaluated
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_parse_multiple_results():
|
def test_i_can_parse_multiple_results():
|
||||||
@@ -536,16 +531,14 @@ def test_i_can_parse_multiple_results():
|
|||||||
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[0].value.body == [("bar", 0, 2, "one two")]
|
assert res[0].value.body == [("bar", 0, 2, "one two")]
|
||||||
concept_found_0 = res[0].value.body[0].concept
|
concept_found_0 = res[0].value.body[0].concept
|
||||||
assert concept_found_0.body == "one two"
|
assert cbody(concept_found_0) == DoNotResolve("one two")
|
||||||
assert concept_found_0.metadata.is_evaluated
|
|
||||||
assert len(concept_found_0.props) == 0
|
assert len(concept_found_0.props) == 0
|
||||||
|
|
||||||
assert res[1].status
|
assert res[1].status
|
||||||
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(res[1].value, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert res[1].value.body == [("foo", 0, 2, "one two")]
|
assert res[1].value.body == [("foo", 0, 2, "one two")]
|
||||||
concept_found_1 = res[1].value.body[0].concept
|
concept_found_1 = res[1].value.body[0].concept
|
||||||
assert concept_found_1.body == "one two"
|
assert cbody(concept_found_1) == DoNotResolve("one two")
|
||||||
assert concept_found_1.metadata.is_evaluated
|
|
||||||
assert len(concept_found_1.props) == 0
|
assert len(concept_found_1.props) == 0
|
||||||
|
|
||||||
|
|
||||||
@@ -617,10 +610,8 @@ def test_i_can_parse_concept_reference_that_is_not_in_grammar():
|
|||||||
assert res.status
|
assert res.status
|
||||||
assert res.value.body == [("foo", 0, 2, "twenty two")]
|
assert res.value.body == [("foo", 0, 2, "twenty two")]
|
||||||
concept_found = res.value.body[0].concept
|
concept_found = res.value.body[0].concept
|
||||||
assert concept_found.body == "twenty two"
|
assert cbody(concept_found) == DoNotResolve("twenty two")
|
||||||
assert concept_found.metadata.is_evaluated
|
assert cprop(concept_found, "two") == get_expected(two, "two")
|
||||||
assert concept_found.get_prop("two") == get_expected(two, "two")
|
|
||||||
assert concept_found.get_prop("two").metadata.is_evaluated
|
|
||||||
|
|
||||||
res = parser.parse(context, "twenty one")
|
res = parser.parse(context, "twenty one")
|
||||||
assert res.status
|
assert res.status
|
||||||
@@ -638,8 +629,7 @@ def test_i_can_parse_zero_or_more():
|
|||||||
assert return_value[0].underlying == u(grammar[foo], 0, 2, [u("one", 0, 0), u("one", 2, 2)])
|
assert return_value[0].underlying == u(grammar[foo], 0, 2, [u("one", 0, 0), u("one", 2, 2)])
|
||||||
|
|
||||||
concept_found = return_value[0].concept
|
concept_found = return_value[0].concept
|
||||||
assert concept_found.body == "one one"
|
assert cbody(concept_found) == DoNotResolve("one one")
|
||||||
assert concept_found.metadata.is_evaluated
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_parse_sequence_and_zero_or_more():
|
def test_i_can_parse_sequence_and_zero_or_more():
|
||||||
@@ -1064,8 +1054,8 @@ def test_i_can_get_the_inner_concept_when_possible():
|
|||||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert return_value == [("foo", 0, 0, "one")]
|
assert return_value == [("foo", 0, 0, "one")]
|
||||||
concept_found = return_value[0].concept
|
concept_found = return_value[0].concept
|
||||||
assert concept_found.body == get_expected(one, "one")
|
assert cbody(concept_found) == get_expected(one, "one")
|
||||||
assert concept_found.get_prop("one") == concept_found.body
|
assert id(cprop(concept_found, "one")) == id(cbody(concept_found))
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_get_the_inner_concept_when_possible_with_rule_name():
|
def test_i_can_get_the_inner_concept_when_possible_with_rule_name():
|
||||||
@@ -1081,11 +1071,11 @@ def test_i_can_get_the_inner_concept_when_possible_with_rule_name():
|
|||||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert return_value == [("foo", 0, 0, "one")]
|
assert return_value == [("foo", 0, 0, "one")]
|
||||||
concept_found = return_value[0].concept
|
concept_found = return_value[0].concept
|
||||||
assert concept_found.body == get_expected(one, "one")
|
assert cbody(concept_found) == get_expected(one, "one")
|
||||||
assert id(concept_found.get_prop("one")) == id(concept_found.body)
|
assert id(cprop(concept_found, "one")) == id(cbody(concept_found))
|
||||||
assert id(concept_found.get_prop("zero")) == id(concept_found.body)
|
assert id(cprop(concept_found, "zero")) == id(cbody(concept_found))
|
||||||
assert id(concept_found.get_prop("opt")) == id(concept_found.body)
|
assert id(cprop(concept_found, "opt")) == id(cbody(concept_found))
|
||||||
assert id(concept_found.get_prop("seq")) == id(concept_found.body)
|
assert id(cprop(concept_found, "seq")) == id(cbody(concept_found))
|
||||||
|
|
||||||
|
|
||||||
def test_i_get_multiple_props_when_zero_or_more():
|
def test_i_get_multiple_props_when_zero_or_more():
|
||||||
@@ -1098,15 +1088,14 @@ def test_i_get_multiple_props_when_zero_or_more():
|
|||||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert return_value == [("foo", 0, 4, "one one one")]
|
assert return_value == [("foo", 0, 4, "one one one")]
|
||||||
concept_found = return_value[0].concept
|
concept_found = return_value[0].concept
|
||||||
assert concept_found.body == "one one one"
|
assert cbody(concept_found) == DoNotResolve("one one one")
|
||||||
assert len(concept_found.props) == 1
|
assert len(concept_found.cached_asts["one"]) == 3
|
||||||
assert len(concept_found.get_prop("one")) == 3
|
assert cprop(concept_found, "one")[0] == get_expected(one)
|
||||||
assert concept_found.get_prop("one")[0] == get_expected(one)
|
assert cprop(concept_found, "one")[1] == get_expected(one)
|
||||||
assert concept_found.get_prop("one")[1] == get_expected(one)
|
assert cprop(concept_found, "one")[2] == get_expected(one)
|
||||||
assert concept_found.get_prop("one")[2] == get_expected(one)
|
assert id(cprop(concept_found, "one")[0]) != id(cprop(concept_found, "one")[1])
|
||||||
assert id(concept_found.get_prop("one")[0]) != id(concept_found.get_prop("one")[1])
|
assert id(cprop(concept_found, "one")[1]) != id(cprop(concept_found, "one")[2])
|
||||||
assert id(concept_found.get_prop("one")[1]) != id(concept_found.get_prop("one")[2])
|
assert id(cprop(concept_found, "one")[2]) != id(cprop(concept_found, "one")[0])
|
||||||
assert id(concept_found.get_prop("one")[2]) != id(concept_found.get_prop("one")[0])
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_get_multiple_props_when_zero_or_more_and_different_values():
|
def test_i_get_multiple_props_when_zero_or_more_and_different_values():
|
||||||
@@ -1119,13 +1108,12 @@ def test_i_get_multiple_props_when_zero_or_more_and_different_values():
|
|||||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert return_value == [("foo", "one ok un ok uno ok")]
|
assert return_value == [("foo", "one ok un ok uno ok")]
|
||||||
concept_found = return_value[0].concept
|
concept_found = return_value[0].concept
|
||||||
assert concept_found.get_prop("one")[0] == get_expected(one, "one")
|
assert cprop(concept_found, "one")[0] == get_expected(one, "one")
|
||||||
assert concept_found.get_prop("one")[1] == get_expected(one, "un")
|
assert cprop(concept_found, "one")[1] == get_expected(one, "un")
|
||||||
assert concept_found.get_prop("one")[2] == get_expected(one, "uno")
|
assert cprop(concept_found, "one")[2] == get_expected(one, "uno")
|
||||||
assert concept_found.get_prop("seq")[0] == "one ok"
|
assert cprop(concept_found, "seq")[0] == DoNotResolve("one ok")
|
||||||
assert concept_found.get_prop("seq")[1] == "un ok"
|
assert cprop(concept_found, "seq")[1] == DoNotResolve("un ok")
|
||||||
assert concept_found.get_prop("seq")[2] == "uno ok"
|
assert cprop(concept_found, "seq")[2] == DoNotResolve("uno ok")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||||
from core.concept import Concept
|
from core.concept import Concept, ConceptParts, DoNotResolve
|
||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from evaluators.ConceptNodeEvaluator import ConceptNodeEvaluator
|
from evaluators.ConceptNodeEvaluator import ConceptNodeEvaluator
|
||||||
from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, Sequence, TerminalNode, \
|
from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, Sequence, TerminalNode, \
|
||||||
@@ -73,7 +73,7 @@ def test_concept_is_returned_when_only_one_in_the_list():
|
|||||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||||
assert wrapper.parser == evaluator
|
assert wrapper.parser == evaluator
|
||||||
assert wrapper.source == "foo"
|
assert wrapper.source == "foo"
|
||||||
assert return_value == Concept("foo", body="foo").init_key()
|
assert return_value == Concept("foo").init_key()
|
||||||
assert return_value.metadata.is_evaluated
|
assert return_value.cached_asts[ConceptParts.BODY] == DoNotResolve("foo")
|
||||||
assert result.parents == [ret_val]
|
assert result.parents == [ret_val]
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ def test_i_can_eval_module_with_that_references_concepts():
|
|||||||
context = get_context()
|
context = get_context()
|
||||||
context.sheerka.add_in_cache(Concept("foo"))
|
context.sheerka.add_in_cache(Concept("foo"))
|
||||||
|
|
||||||
parsed = PythonParser().parse(context, "def a(b):\n return b\na(foo)")
|
parsed = PythonParser().parse(context, "def a(b):\n return b\na(c:foo:)")
|
||||||
evaluated = PythonEvaluator().eval(context, parsed)
|
evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
|
||||||
assert evaluated.status
|
assert evaluated.status
|
||||||
|
|||||||
+63
-1
@@ -4,7 +4,7 @@ from os import path
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept, ConceptAlreadyInSet
|
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept, ConceptAlreadyInSet
|
||||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, Property
|
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, Property, ConceptParts, DoNotResolve
|
||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||||
|
|
||||||
@@ -528,6 +528,41 @@ def test_i_can_evaluate_a_concept_with_prop(expr, expected):
|
|||||||
assert evaluated.metadata.is_evaluated
|
assert evaluated.metadata.is_evaluated
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_evaluate_metadata_using_do_not_resolve():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
concept = Concept("foo")
|
||||||
|
concept.cached_asts[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||||
|
|
||||||
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
|
assert evaluated.body == "do not resolve"
|
||||||
|
assert evaluated.metadata.is_evaluated
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_evaluate_property_using_do_not_resolve():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
concept = Concept("foo").set_prop("a")
|
||||||
|
concept.cached_asts["a"] = DoNotResolve("do not resolve")
|
||||||
|
|
||||||
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
|
assert evaluated.get_prop("a") == "do not resolve"
|
||||||
|
assert evaluated.metadata.is_evaluated
|
||||||
|
|
||||||
|
|
||||||
|
def test_original_value_is_overridden_when_using_do_no_resolve():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
concept = Concept("foo", body="original value").set_prop("a", "original value")
|
||||||
|
concept.cached_asts["a"] = DoNotResolve("do not resolve")
|
||||||
|
concept.cached_asts[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||||
|
|
||||||
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
|
assert evaluated.body == "do not resolve"
|
||||||
|
assert evaluated.get_prop("a") == "do not resolve"
|
||||||
|
assert evaluated.metadata.is_evaluated
|
||||||
|
|
||||||
|
|
||||||
def test_props_are_evaluated_before_body():
|
def test_props_are_evaluated_before_body():
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
|
|
||||||
@@ -615,6 +650,8 @@ def test_i_can_evaluate_concept_when_properties_reference_others_concepts():
|
|||||||
concept = Concept("foo", body="a").set_prop("a", "a").init_key()
|
concept = Concept("foo", body="a").set_prop("a", "a").init_key()
|
||||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
|
# first prop a is evaluated to concept_a
|
||||||
|
# then body is evaluated to prop a -> concept_a
|
||||||
assert evaluated.key == concept.key
|
assert evaluated.key == concept.key
|
||||||
assert evaluated.body == concept_a
|
assert evaluated.body == concept_a
|
||||||
|
|
||||||
@@ -647,6 +684,31 @@ def test_i_can_evaluate_concept_when_properties_reference_others_concepts_with_b
|
|||||||
assert evaluated.body == 3
|
assert evaluated.body == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_evaluate_concept_when_properties_is_a_concept():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
concept_a = sheerka.add_in_cache(Concept(name="a", body="'a'").init_key())
|
||||||
|
|
||||||
|
concept = Concept("foo").set_prop("a", concept_a)
|
||||||
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
|
assert evaluated.key == concept.key
|
||||||
|
assert evaluated.get_prop("a") == Concept(name="a", body="a").init_key()
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_evaluate_when_property_asts_is_a_list():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
foo = Concept("foo", body="1")
|
||||||
|
|
||||||
|
concept = Concept("to_eval").set_prop("prop")
|
||||||
|
concept.cached_asts["prop"] = [foo, DoNotResolve("1")]
|
||||||
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
|
props = evaluated.get_prop("prop")
|
||||||
|
assert len(props) == 2
|
||||||
|
assert props[0] == Concept("foo", body=1).init_key()
|
||||||
|
assert props[1] == "1"
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_reference_sheerka():
|
def test_i_can_reference_sheerka():
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
|
|
||||||
|
|||||||
@@ -413,14 +413,37 @@ def test_i_can_eval_a_mix_with_bnf_and_python():
|
|||||||
assert res[0].body == 22
|
assert res[0].body == 22
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_a_mix_with_bnf_and_python_when_rule_name():
|
@pytest.mark.parametrize("desc, definitions", [
|
||||||
|
("Simple form", [
|
||||||
|
"def concept one as 1",
|
||||||
|
"def concept two as 2",
|
||||||
|
"def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit"
|
||||||
|
]),
|
||||||
|
("When twenty is a concept", [
|
||||||
|
"def concept one as 1",
|
||||||
|
"def concept two as 2",
|
||||||
|
"def concept twenty as 20",
|
||||||
|
"def concept twenties from bnf twenty (one|two)=unit as twenty + unit"
|
||||||
|
]),
|
||||||
|
("When digit is a concept", [
|
||||||
|
"def concept one as 1",
|
||||||
|
"def concept two as 2",
|
||||||
|
"def concept twenty as 20",
|
||||||
|
"def concept digit from bnf one|two",
|
||||||
|
"def concept twenties from bnf twenty digit as twenty + digit"
|
||||||
|
]),
|
||||||
|
])
|
||||||
|
def test_i_can_mix_concept_with_python_to_define_numbers(desc, definitions):
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
|
|
||||||
sheerka.evaluate_user_input("def concept one as 1")
|
for definition in definitions:
|
||||||
sheerka.evaluate_user_input("def concept two as 2")
|
sheerka.evaluate_user_input(definition)
|
||||||
sheerka.evaluate_user_input("def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit")
|
|
||||||
|
|
||||||
assert sheerka.evaluate_user_input("eval twenty one")[0].body == 21
|
res = sheerka.evaluate_user_input("twenty one")
|
||||||
|
assert len(res) == 1
|
||||||
|
assert res[0].status
|
||||||
|
assert sheerka.isinstance(res[0].body, "twenties")
|
||||||
|
assert res[0].body.body == 21
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
@@ -438,47 +461,6 @@ def test_i_can_eval_a_mix_with_bnf_and_python_when_rule_name():
|
|||||||
assert res[0].body == 22
|
assert res[0].body == 22
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_a_mix_with_bnf_and_python_when_rule_name_2():
|
|
||||||
sheerka = get_sheerka()
|
|
||||||
|
|
||||||
sheerka.evaluate_user_input("def concept one as 1")
|
|
||||||
sheerka.evaluate_user_input("def concept two as 2")
|
|
||||||
sheerka.evaluate_user_input("def concept twenty as 20")
|
|
||||||
sheerka.evaluate_user_input("def concept twenties from bnf twenty (one | two)=unit as twenty + unit")
|
|
||||||
|
|
||||||
assert sheerka.evaluate_user_input("eval twenty one")[0].body == 21
|
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
|
||||||
assert len(res) == 1
|
|
||||||
assert res[0].status
|
|
||||||
assert res[0].body == 22
|
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + twenty two")
|
|
||||||
assert len(res) == 1
|
|
||||||
assert res[0].status
|
|
||||||
assert res[0].body == 43
|
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + one")
|
|
||||||
assert len(res) == 1
|
|
||||||
assert res[0].status
|
|
||||||
assert res[0].body == 22
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_a_more_complicated_mix_with_bnf_and_python():
|
|
||||||
sheerka = get_sheerka()
|
|
||||||
|
|
||||||
sheerka.evaluate_user_input("def concept one as 1")
|
|
||||||
sheerka.evaluate_user_input("def concept two as 2")
|
|
||||||
sheerka.evaluate_user_input("def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit")
|
|
||||||
|
|
||||||
assert sheerka.evaluate_user_input("eval twenty one")[0].body == 21
|
|
||||||
|
|
||||||
res = sheerka.evaluate_user_input("twenty one + twenty two")
|
|
||||||
assert len(res) == 1
|
|
||||||
assert res[0].status
|
|
||||||
assert res[0].body == 43
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_say_that_a_concept_isa_another_concept():
|
def test_i_can_say_that_a_concept_isa_another_concept():
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
sheerka.evaluate_user_input("def concept foo")
|
sheerka.evaluate_user_input("def concept foo")
|
||||||
|
|||||||
Reference in New Issue
Block a user