def compute(self, env: Environment): e1 = env.find_object('e1') e2 = env.find_object('e2') if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x ** y') if e2.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x ** y') as_integer = False if e1.get_type().name == 'integer' and e2.get_type().name == 'integer': as_integer = True elif e1.get_type().name == 'integer' and e2.get_type( ).name == 'logical': as_integer = True elif e1.get_type().name == 'logical' and e2.get_type( ).name == 'integer': as_integer = True res = perform_op_on_vector_or_atomic( e1, e2, lambda l, r: cast_atomic(atomic_mod(l, r), 'integer' if as_integer else 'double')) res = [VectorItem(None, el) for el in res] if len(res) == 0: t = get_more_important_vector_type(e1.get_type(), e2.get_type()) return VectorObj([], t) ret = VectorObj.create(res) return ret
def compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e1: Param = args['e1'] e2: Param = args['e2'] if e1.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x ** y') if e2.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x ** y') res = [] as_integer = False if e1.value.get_type().name == 'integer' and e2.value.get_type().name == 'integer': as_integer = True elif e1.value.get_type().name == 'integer' and e2.value.get_type().name == 'logical': as_integer = True elif e1.value.get_type().name == 'logical' and e2.value.get_type().name == 'integer': as_integer = True for l, r in concat_vectors(e1.value.items, e2.value.items): res.append(cast_atomic(atomic_mod(l.value, r.value), 'integer' if as_integer else 'double')) res = [VectorItem(None, el) for el in res] ret = VectorObj(res) return ret
def compute(self, env: Environment): ln: VectorObj = env.find_object('length') if ln.get_type().name not in ['double', 'integer']: raise errors.InvalidArg('length') if len(ln.items) != 1: raise errors.InvalidArg('length') val = ln.items[0][1] if val.is_inf: raise errors.R_RuntimeError('vector size cannot be infinite') elif val.is_na: raise errors.InvalidArg('length') elif val.is_nan: raise errors.R_RuntimeError('vector size cannot be NA/NaN') count = val.value items = [ VectorItem(None, Atomic(False, types.LogicalType())) for _ in range(int(count) * (-1 if val.is_neg else 1)) ] ret = VectorObj(items, types.LogicalType()) return ret
def compute(self, env: Environment): e1 = env.find_object('x') e2 = env.find_object('y') if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x | y') if e2.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x | y') res = VectorItem(None, atomic_or(e1.items[0].value, e2.items[0].value)) ret = VectorObj.create([res]) return ret
def compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e1: Param = args['x'] e2: Param = args['y'] if e1.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x | y') if e2.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x | y') res = VectorItem(None, atomic_or(e1.value.items[0].value, e2.value.items[0].value)) ret = VectorObj([res]) return ret
def compute(self, env: Environment): e1 = env.find_object('x') e2 = env.find_object('y') if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x || y') if e2.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x || y') res = perform_op_on_vector_or_atomic( e1, e2, lambda l, r: cast_atomic(atomic_power(l, r))) res = [VectorItem(None, el) for el in res] ret = VectorObj.create(res) return ret
def compute(self, env: Environment): e1 = env.find_object('e1') e2 = env.find_object('e2') if isinstance(e2, EmptyParamObj): if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', '- x') res = [] for item in e1.items: res.append( atomic_subtract(Atomic(False, types.LogicalType()), item.value)) res = [VectorItem(None, el) for el in res] ret = VectorObj(res) return ret if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x - y') if e2.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x - y') as_integer = False if e1.get_type().name == 'integer' and e2.get_type().name == 'integer': as_integer = True elif e1.get_type().name == 'integer' and e2.get_type( ).name == 'logical': as_integer = True elif e1.get_type().name == 'logical' and e2.get_type( ).name == 'integer': as_integer = True res = perform_op_on_vector_or_atomic( e1, e2, lambda l, r: cast_atomic(atomic_subtract(l, r), 'integer' if as_integer else 'double')) res = [VectorItem(None, el) for el in res] if len(res) == 0: t = get_more_important_vector_type(e1.get_type(), e2.get_type()) return VectorObj([], t) ret = VectorObj.create(res) return ret
def atomic_multiply(e1: Atomic, e2: Atomic): type = get_more_important_vector_type(e1.get_type(), e2.get_type()) if type.name == 'character': raise errors.NonNumericToBinary() is_nan = e1.is_nan or e2.is_nan is_na = e1.is_na or e2.is_na or ((e1.is_inf or e2.is_inf) and (e1.value == 0 or e2.value == 0)) is_inf = (e1.is_inf or e2.is_inf) is_neg = e1.is_neg != e2.is_neg if is_nan: return Atomic(None, type, is_nan=True) elif is_na: return Atomic(None, type, is_na=True) elif is_inf: return Atomic(None, type, is_inf=True, is_neg=is_neg) if type.name == 'double': val = float(e1.value) * float(e2.value) * (-1 if e1.is_neg != e2.is_neg else 1) elif type.name == 'integer': val = int(int(e1.value) * int(e2.value) * (-1 if e1.is_neg != e2.is_neg else 1)) elif type.name == 'logical': val = int(e1.value) * int(e2.value) * (-1 if e1.is_neg != e2.is_neg else 1) type = types.IntegerType() else: raise Exception('invalid vector type - {}'.format(type.name)) if val < 0: return Atomic(-val, type, is_neg=True) else: return Atomic(val, type)
def compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e1: Param = args['x'] e2: Param = args['y'] if e1.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x || y') if e2.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x || y') res = [] for l, r in concat_vectors(e1.value.items, e2.value.items): res.append(atomic_or(l.value, r.value)) res = [VectorItem(None, el) for el in res] ret = VectorObj(res) return ret
def atomic_divide(e1: Atomic, e2: Atomic): type = get_more_important_vector_type(e1.get_type(), e2.get_type()) if type.name == 'character': raise errors.NonNumericToBinary() if e2.is_inf: new_e2 = Atomic(False, types.LogicalType(), is_inf=False, is_neg=e2.is_neg) else: if e2.value == 0 and not e2.is_na and not e2.is_nan: new_e2 = Atomic(None, e2.type, is_na=False, is_nan=False, is_inf=True, is_neg=e2.is_neg) elif not e2.is_na and not e2.is_nan: new_e2 = Atomic(1 / e2.value, e2.type, is_na=e2.is_na, is_nan=e2.is_nan, is_inf=e2.is_inf, is_neg=e2.is_neg) else: new_e2 = e2 ret = atomic_multiply(e1, new_e2) return ret
def compute(self, env: Environment): try: x: RObj = env.find_object_locally('x') except: raise errors.InvalidLeftHandAssignment() try: value: RObj = env.find_object_locally('value') except: raise errors.InvalidLeftHandAssignment() if x.get_type().name == 'symbol': val_value = value.evaluate(env) if val_value.get_type().name == 'call': val_value = val_value.compute(env) env.parent_env.add(x.name, val_value) return val_value raise errors.InvalidLeftHandAssignment()
def compute(self, env: Environment): e1 = env.find_object('x') e2 = env.find_object('y') if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x && y') if e2.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x && y') try: res = perform_op_on_vector_or_atomic(e1, e2, atomic_and) except UnsupportedVectorType as e: raise errors.InvalidArgTypeInArgs( 'x' if e.operand_index == 0 else 'y', 'x && y') res = [VectorItem(None, el) for el in res] ret = VectorObj.create(res) return ret
def compute(self, env: Environment): if self.base_obj.get_type().name == 'symbol': fun: FunctionObj = env.find_function(self.base_obj.name) else: fun: FunctionObj = self.base_obj.evaluate(env) if not isinstance(fun, FunctionObj): raise errors.ApplyToNonFunction() args = [] assg_obj = RObj.get_r_obj('AssignObj') for item in self.items: # item_val = item.evaluate(env) if isinstance(item, DotsObj): args.extend(item.items) elif isinstance(item, Atomic): n = VectorObj.create([VectorItem(None, item)]) args.append(Param(None, n)) elif isinstance(item, assg_obj): if item.mode == 'plain': if item.item.get_type().name == 'symbol': name = item.item.name elif isinstance(item.item, Atomic): if item.item.get_type().name == 'character': name = item.item[0] else: raise errors.InvalidLeftHandAssignment() else: raise errors.InvalidLeftHandAssignment() arg = Param(name, item.value.evaluate(env)) args.append(arg) else: arg = Param(None, item.evaluate(env)) args.append(arg) else: arg = Param(None, item.evaluate(env)) args.append(arg) try: ret = fun.compute(args, env) except errors.R_RuntimeError as e: r = RError(self, e.message) if not self.exception_occurred(r): raise r return ret
def atomic_subtract(e1: Atomic, e2: Atomic): type = get_more_important_vector_type(e1.get_type(), e2.get_type()) if type.name == 'character': raise errors.NonNumericToBinary() new_e2 = Atomic(e2.value, e2.type, is_na=e2.is_na, is_nan=e2.is_nan, is_inf=e2.is_inf, is_neg=not e2.is_neg) ret = atomic_add(e1, new_e2) return ret
def atomic_not(e: Atomic): if e.type.name == 'character': raise errors.InvalidArgType() if e.is_inf: ret = Atomic(False, types.LogicalType()) return ret elif e.is_na or e.is_nan: return Atomic(None, e.type, is_na=True) ret = Atomic(not bool(e.value), types.LogicalType()) return ret
def compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e1: Param = args['x'] e2: Param = args['y'] if e1.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', 'x && y') if e2.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('y', 'x && y') res = [] try: for l, r in concat_vectors(e1.value.items, e2.value.items): res.append(atomic_and(l.value, r.value)) except UnsupportedVectorType as e: raise errors.InvalidArgTypeInArgs('x' if e.operand_index == 0 else 'y', 'x && y') res = [VectorItem(None, el) for el in res] ret = VectorObj(res) return ret
def compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e: DotsObj = args['...'] for index, param in enumerate(e.items): if param.value.get_type().name not in ['character', 'double', 'integer', 'logical']: raise errors.ArgumentCannotBeHandledByFun(index+1, param.value.get_type().name, 'cat') for atom in param.value.items: rep = atom.show_self() print(rep) return NULLObj()
def compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e1: Param = args['x'] if e1.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgType() res = [] for item in e1.value.items: res.append(atomic_not(item.value)) res = [VectorItem(None, el) for el in res] ret = VectorObj(res) return ret
def create(input_args: List, body: RObj): args = [] for arg in input_args: if isinstance(arg, RObj.get_r_obj('SymbolObj')): a = Arg(arg.name, None) elif isinstance(arg, RObj.get_r_obj('AssignObj')): if not isinstance(arg.item, RObj.get_r_obj('SymbolObj')): raise errors.R_RuntimeError( 'invalid assigment of function') else: a = Arg(arg.item.name, arg.value) args.append(a) return FunctionObj(args, body)
def compute(self, env: Environment): e: DotsObj = env.find_object('...') for index, param in enumerate(e.items): if param[1].get_type().name not in [ 'character', 'double', 'integer', 'logical' ]: raise errors.ArgumentCannotBeHandledByFun( index + 1, param[1].get_type().name, 'cat') for atom in param[1].items: rep = atom.show_self() print(rep) return NULLObj()
def atomic_mod(e1: Atomic, e2: Atomic): type = get_more_important_vector_type(e1.get_type(), e2.get_type()) if type.name == 'character': raise errors.NonNumericToBinary() is_na = e1.is_na and not (e2.value == 0) is_nan = (e1.is_nan and e2.is_na) or (e1.is_nan and (e2.value == 0)) or ((e1.value == 0) and e2.is_nan) is_inf = (e1.is_inf and not e2.is_inf and e2.is_neg) or (e1.is_inf and e2.value != 0) if is_na: return Atomic(None, type, is_na=True) elif is_nan: return Atomic(None, type, is_nan=True) elif is_inf: return Atomic(None, type, is_inf=True) elif e1.value == 1 and e1.is_neg and e2.value == 0: return Atomic(1, type) elif e1.is_neg and e2.value == int(e2.value): ret = Atomic(e1.value**e2.value, type) return ret if type.name == 'double': val = (float(e1.value) * (-1 if e1.is_neg else 1))**(float(e2.value) * (-1 if e1.is_neg else 1)) elif type.name == 'integer': val = int((int(e1.value) * (-1 if e1.is_neg else 1))**(int(e2.value) * (-1 if e1.is_neg else 1))) elif type.name == 'logical': val = (int(e1.value) * (-1 if e1.is_neg else 1))**(int(e2.value) * (-1 if e1.is_neg else 1)) type = types.IntegerType() else: raise Exception('invalid vector type - {}'.format(type.name)) if isinstance(val, complex): return Atomic(None, type, is_nan=True) if val < 0: return Atomic(-val, type, is_neg=True) else: return Atomic(val, type)
def compute(self, env: Environment): e1 = env.find_object('x') if e1.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgType() res = [] if isinstance(e1, VectorObj): if len(e1.items) == 0: return VectorObj([], type(e1.get_type())()) for item in e1.items: res.append(atomic_not(item[1])) else: res.append(atomic_not(e1)) res = [VectorItem(None, el) for el in res] ret = VectorObj.create(res) return ret
def evaluate(self, env: Environment): val_arg: RObj = self.argument.evaluate(env) if val_arg.get_type().name not in ['double', 'numeric', 'logical']: raise errors.ArgNotInterpretableAsLogical() else: if isinstance(val_arg, atomics.VectorObj): if len(val_arg.items) == 0: raise RError.create_simple(self, 'argument is of length zero') r = as_boolean(val_arg) if r: ret = execute_item(self.body, env) return ret else: if self.alterbody is not None: ret = execute_item(self.alterbody, env) return ret else: return atomics.NULLObj()
def evaluate(self, env: Environment): while True: val_arg: RObj = self.argument.evaluate() if val_arg.get_type().name not in ['double', 'numeric', 'logical']: raise errors.ArgNotInterpretableAsLogical() else: if isinstance(val_arg, atomics.VectorObj): if len(val_arg.items) == 0: raise RError(self, 'argument is of length zero') r = as_boolean(val_arg) if r: try: self.body.evaluate(env) except BreakLoopCommand: return atomics.NULLObj() except NextLoopCommand: continue else: return atomics.NULLObj()
def set_value(self, value, env: Environment): raise errors.InvalidLeftHandAssignment()
def compute(self, env: Environment): raise errors.ApplyToNonFunction()
def set_dlr(self, key, value): raise errors.ObjectNotSubSettable(self)
def get_dlr(self, key): raise errors.ObjectNotSubSettable(self)
def set_super_sub(self, key, options: List[Param]): raise errors.ObjectNotSubSettable(self)
def get_super_sub(self, key): raise errors.ObjectNotSubSettable(self)