Пример #1
0
def bool_opr(lval, rval, op):
    if isAthValue(lval):
        lval = AthSymbol(bool(lval), left=lval)
    if isAthValue(rval):
        rval = AthSymbol(bool(rval), left=rval)
    if op == 'l&':
        return lval and rval
    elif op == 'l|':
        return lval or rval
    elif op == 'l^':
        return (lval if lval and not rval else
                rval if rval and not lval else AthSymbol(False))
    raise SyntaxError(f'Invalid comparison operator: {op}')
Пример #2
0
 def exec_stmts(self, fname, stmts):
     # AST Execution trampoline.
     athloops = 0
     while True:
         try:
             ath_builtins['THIS'] = ThisSymbol(fname, stmts)
             self.stack.append(AthStackFrame(iter_nodes=stmts.iter_nodes()))
             self.ast = self.stack[-1].iter_nodes
             while True:
                 try:
                     node = next(self.ast)
                 except StopIteration:
                     state = self.stack[-1].exec_state
                     if state == self.TOPLEVEL_STATE:
                         sys.exit(0)  # override
                         athloops += 1
                         if athloops >= 612:
                             sys.stderr.write(
                                 'UnboundedLoopError: THIS.DIE() never called'
                             )
                         else:
                             self.ast.reset()
                     elif state == self.FUNCEXEC_STATE:
                         self.stack.pop()
                         self.eval_return(AthSymbol(False))
                         self.ast = self.stack[-1].iter_nodes
                     else:
                         if (self.get_symbol(self.ast.pendant).alive ==
                                 bool(state - self.TILDEATH_STATE)):
                             self.stack.pop()
                             self.ast = self.stack[-1].iter_nodes
                         else:
                             self.ast.reset()
                     continue
                 # print(repr(node))
                 if isinstance(node, TildeAthLoop):
                     if self.get_symbol(
                             node.body.pendant).alive == node.state:
                         continue
                     self.stack.append(
                         AthStackFrame(
                             iter_nodes=node.body.iter_nodes(),
                             exec_state=self.TILDEATH_STATE +
                             int(node.state),
                         ))
                     self.ast = self.stack[-1].iter_nodes
                     continue
                 self.stack[-1].eval_state.append(node.prepare())
                 ret_value = self.eval_stmt()
                 if (self.stack[-1].get_current().name == 'DIVULGATE'
                         and ret_value is not None):
                     self.stack.pop()
                     self.eval_return(ret_value)
         except KeyboardInterrupt:
             raise  # override
             self.stack.clear()
             continue
         except Exception as exc:
             raise exc
Пример #3
0
 def math_proxy_func(env, *values):
     args = []
     for value in values:
         if isinstance(value, AthSymbol):
             value = value.left
         if isinstance(value, dtypes):
             args.append(value)
         else:
             raise TypeError('invalid numerical type')
     return AthSymbol(left=func(*args))
Пример #4
0
def symbol_opr(lval, rval, op):
    if not (isinstance(lval, AthSymbol) and isinstance(rval, AthSymbol)):
        raise TypeError('May only perform living assertions on symbols')
    try:
        if op == '!=!':
            value = lval is rval
        elif op == '?=!':
            value = lval.left.alive and rval.left.alive
        elif op == '!=?':
            value = lval.right.alive and rval.right.alive
        elif op == '~=!':
            value = not (lval.left.alive or rval.left.alive)
        elif op == '!=~':
            value = not (lval.right.alive or rval.right.alive)
        elif op == '~=~':
            value = lval is not rval
        else:
            raise SyntaxError('Invalid comparison operator: {}', op)
    except AttributeError:
        raise SymbolError('The relevant side(s) must be symbols')
    return AthSymbol(value)
Пример #5
0
 def eval_stmt(self, ret_value=None):
     # Statement evaluation trampoline.
     eval_state = self.stack[-1].eval_state
     node = eval_state[-1]
     if ret_value is not None:
         node.set_argv(ret_value)
     while True:
         try:
             # Try to get the next argument AST node from the expression.
             arg = node.get_arg()
         except IndexError:
             # If there are no more left, execute the associated function.
             try:
                 ret_value = node.execute(self)
             except SymbolDeath as exc:
                 # In a DIE statement, SymbolDeath will be raised.
                 if 'THIS' in exc.args[0]:
                     # End the program only when THIS is killed.
                     sys.exit(0)
                 elif self.stack[-1].iter_nodes.pendant in exc.args[0]:
                     # If the current frame's control variable is killed, evaluate:
                     state = self.stack[-1].exec_state
                     if state == self.TILALIVE_STATE:
                         # If in keep-dead loop, force the loop to repeat.
                         self.stack[-1].iter_nodes.reset()
                     else:
                         # Otherwise, pop the execution stack and move on.
                         self.stack.pop()
                         self.ast = self.stack[-1].iter_nodes
                         if state == self.FUNCEXEC_STATE:
                             # If popping from a function, evaluate from here instead.
                             eval_state = self.stack[-1].eval_state
                             ret_val = AthSymbol(False)
                             continue
                 eval_state.clear()
                 return AthSymbol(False)
             except Exception as exc:
                 # When other errors occur, pass the exception upward.
                 raise exc
             else:
                 # When the function has finished, move down the evaluation stack.
                 if node.stmt.name == 'EXECUTE':  # Function call
                     eval_state.pop()
                     func, scope_vars = ret_value
                     if isinstance(func, AthBuiltinFunction):
                         node = eval_state[-1]
                         node.set_argv(func(self, *scope_vars))
                         continue
                     if self.is_tail_call(len(eval_state) + 1):
                         frame = self.stack[-1]
                         frame.scope_vars = scope_vars
                         frame.iter_nodes = func.body.iter_nodes()
                         frame.exec_state = self.FUNCEXEC_STATE
                         eval_state.clear()
                     else:
                         self.stack.append(
                             AthStackFrame(
                                 scope_vars=scope_vars,
                                 iter_nodes=func.body.iter_nodes(),
                                 exec_state=self.FUNCEXEC_STATE,
                             ))
                     self.ast = self.stack[-1].iter_nodes
                     return None
                 if len(eval_state) > 1:
                     eval_state.pop()
                     node = eval_state[-1]
                     node.set_argv(ret_value)
                     continue
                 # If this is the last expression in the stack, return to the AST.
                 eval_state.clear()
                 return ret_value
         else:
             # If there is an argument left to evaluate, deal with it first.
             if arg is None or isinstance(arg,
                                          (int, str, AthCustomFunction)):
                 # Name, Number, Function, and Empty items are passed as is.
                 node.set_argv(arg)
             elif isinstance(arg, LiteralToken):
                 # Tokens pass their values.
                 node.set_argv(arg.value)
             elif isinstance(arg, IdentifierToken):
                 # Name tokens pass either their names or evaluate their values.
                 if node.is_name_arg():
                     node.set_argv(arg.name)
                 else:
                     node.set_argv(self.get_symbol(arg.name))
             elif isinstance(arg, AthStatement):
                 # Evaluate expressions for their values before passing the result.
                 node = arg.prepare()
                 eval_state.append(node)
Пример #6
0
def unopr_expression(env, opr, val):
    ans = unops[opr](val)
    if isAthValue(ans):
        return AthSymbol(left=ans)
    return ans
Пример #7
0
def bool_not(val):
    if isAthValue(val):
        val = AthSymbol(bool(val), left=val)
    return AthSymbol(not val, val.left, val.right)
Пример #8
0
def on_dead_jump(env, expr, jlen):
    if not expr:
        env.stack[-1].iter_nodes.index += jlen
    return AthSymbol(False)
Пример #9
0
def biopr_expression(env, opr, lft, rht):
    ans = biops[opr](lft, rht)
    if isAthValue(ans):
        return AthSymbol(left=ans)
    return ans
Пример #10
0
def cmp_opr(lval, rval, op):
    if isAthValue(lval):
        lval = AthSymbol(bool(lval), left=lval)
    return op(lval, rval)