From b1ddfbca35fc17958d2c68c4f68427343c85c4fd Mon Sep 17 00:00:00 2001 From: Gail Weiss Date: Fri, 2 Jun 2023 16:57:16 +0200 Subject: [PATCH] remove 'draw' requirement that input sequence be strings. also, in case of draw and of unfinished eval (i.e., cases where want to know s-op/selector behaviour for some specific input), allow evaluating even when the s-op or selector is not aligned with main running example (by taking the given input as a backup example to do the test evaluation on). this changes error order slightly: in these cases, it now evaluates the input to a selector/s-op/function before it evaluates the expression receiving that input. this means that now the command '1(hi)' when hi is not defined complains about hi instead of complaining that it has not implemented the application of 1 to something else. as i do not want to force the order between complaints about these problems (for now?), simply update the test which had 1(hi) to instead have 1("hi"). --- RASP_support/Evaluator.py | 41 ++++++++++++++++++++++--- tests/broken_libs/lib/other_errors.rasp | 3 +- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/RASP_support/Evaluator.py b/RASP_support/Evaluator.py index c46c6c9..8b502be 100644 --- a/RASP_support/Evaluator.py +++ b/RASP_support/Evaluator.py @@ -111,6 +111,10 @@ class Evaluator: def __init__(self,env,repl): self.env = env self.sequence_running_example = repl.sequence_running_example + self.backup_example = None + # allows evaluating something that maybe doesn't necessarily work with the main running example, + # but we just want to see what happens on it - e.g. so we can do draw(tokens_int+1,[1,2]) + # without error even while the main example is still "hello" self.repl = repl def evaluate(self,ast): @@ -134,15 +138,16 @@ def draw(self,ast): # TODO: make at least some rudimentary comparisons of selectors somehow to merge heads idk?????? # maybe keep trace of operations used to create them and those with exact same parent s-ops and operations # can get in? would still find eg select(0,0,==) and select(1,1,==) different, but its better than nothing at all + example = self.evaluateExpr(ast.inputseq) if ast.inputseq else self.sequence_running_example + prev_backup = self.backup_example + self.backup_example = example unf = self.evaluateExpr(ast.unf) if not isinstance(unf,UnfinishedSequence): raise RASPTypeError("draw expects unfinished sequence, got:",unf) - example = self.evaluateExpr(ast.inputseq) if ast.inputseq else self.sequence_running_example - if not isinstance(example,str): - raise RASPTypeError("draw expects to evaluate sequence on string, got:",example) unf.draw_comp_flow(example) res = unf(example) res.created_from_input = example + self.backup_example = prev_backup return JustVal(res) def assign(self,ast): @@ -542,7 +547,22 @@ def evaluateExprsList(self,ast): def _test_res(self,res): if isinstance(res,Unfinished): - res(self.sequence_running_example,just_pass_exception_up=True) + def succeeds_with(exampe): + try: + res(example,just_pass_exception_up=True) + except: + return False + else: + return True + succeeds_with_backup = (self.backup_example is not None) and \ + succeeds_with(self.backup_example) + if succeeds_with_backup: + return + succeeds_with_main = succeeds_with(self.sequence_running_example) + if succeeds_with_main: + return + example = self.sequence_running_example if None is self.backup_example else self.backup_example + res(example,just_pass_exception_up=True) def evaluateExpr(self,ast,from_top=False): def format_return(res,resname="out",is_application_of_unfinished=False): @@ -576,7 +596,20 @@ def format_return(res,resname="out",is_application_of_unfinished=False): if ast.aggregate: return format_return(self._evaluateAggregateExpr(ast.aggregate)) if ast.unfORfun: + + # before evaluating the unfORfun expression, + # consider that it may be an unf that would not work + # with the current running example, and allow that it may have + # been sent in with an example for which it will work + prev_backup = self.backup_example + input_vals = self._get_first_cont_list(ast.inputexprs) + if len(input_vals) == 1: + self.backup_example = self.evaluateExpr(input_vals[0]) + unfORfun = self.evaluateExpr(ast.unfORfun) + + self.backup_example = prev_backup + if isinstance(unfORfun,Unfinished): return format_return(self._evaluateApplication(ast,unfORfun), is_application_of_unfinished=True) diff --git a/tests/broken_libs/lib/other_errors.rasp b/tests/broken_libs/lib/other_errors.rasp index 763f9cd..a30e429 100644 --- a/tests/broken_libs/lib/other_errors.rasp +++ b/tests/broken_libs/lib/other_errors.rasp @@ -5,8 +5,7 @@ def blbl() { # deliberately enforce a mistake. fix correct order of prints, and then do add appropriate tests, later } - -1(hi); +1("hi"); # note: if set tokens in the library then it will complain later # that tokens is a reserved word (as it should for things set in the library),