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 atomic_or(e1: Atomic, e2: Atomic): type = get_more_important_vector_type(e1.get_type(), e2.get_type()) if e1.is_na or e2.is_na: return Atomic(None, types.LogicalType(), is_na=True) if e1.is_nan or e2.is_nan: return Atomic(None, types.LogicalType(), is_na=True) if e1.is_inf or e2.is_inf: return Atomic(True, types.LogicalType()) if (e1.is_inf and e2.value == 0) or (e1.value == 0 and e2.is_inf): return Atomic(False, types.LogicalType()) if type.name == 'character': val = str(e1.value) or str(e2.value) elif type.name == 'double': val = float(e1.value) * (-1 if e1.is_neg else 1) or float( e2.value) * (-1 if e2.is_neg else 1) elif type.name == 'integer': val = int(e1.value) * (-1 if e1.is_neg else 1) or int( e2.value) * (-1 if e2.is_neg else 1) elif type.name == 'logical': val = bool(e1.value) or bool(e2.value) else: raise Exception('invalid vector type - {}'.format(type.name)) return Atomic(bool(val), types.LogicalType())
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 atomic_is_equal_or_greater(e1: Atomic, e2: Atomic): type = get_more_important_vector_type(e1.get_type(), e2.get_type()) if e1.is_na or e2.is_na: return Atomic(None, types.LogicalType(), is_na=True) if e1.is_nan or e2.is_nan: return Atomic(None, types.LogicalType(), is_na=True) if e1.is_inf and e2.is_inf: return Atomic(e1.is_neg < e2.is_neg, types.LogicalType()) if e1.is_inf != e2.is_inf: return Atomic(e1.is_inf and not e1.is_neg or e2.is_inf and e2.is_neg, types.LogicalType()) if type.name == 'character': return Atomic(str(e1.value) >= str(e2.value), types.LogicalType()) elif type.name == 'double': return Atomic( float(e1.value) * (-1 if e1.is_neg else 1) >= float(e2.value) * (-1 if e2.is_neg else 1), types.LogicalType()) elif type.name == 'integer': return Atomic( int(e1.value) * (-1 if e1.is_neg else 1) >= int(e2.value) * (-1 if e2.is_neg else 1), types.LogicalType()) elif type.name == 'logical': return Atomic(bool(e1.value) >= bool(e2.value), types.LogicalType()) else: raise Exception('invalid vector type - {}'.format(type.name))
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 get_more_important_vector_type(type1, type2): tps = [type1.name, type2.name] # if 'list' in tps: # return types.ListType() if 'character' in tps: return types.CharacterType() elif 'double' in tps: return types.DoubleType() elif 'integer' in tps: return types.IntegerType() elif 'logical' in tps: return types.LogicalType() first = tps[0] not in ['character', 'double', 'integer', 'logical'] raise UnsupportedVectorType(tps, operand_index=0 if first else 1)
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 compute(self, params: List[Param], env: Environment): args = self.arrange_args(params) e1: Param = args['e1'] e2: Param = args['e2'] if isinstance(e2, EmptyParamObj): if e1.value.get_type().name not in ['double', 'logical', 'integer']: raise errors.InvalidArgTypeInArgs('x', '- x') res = [] for item in e1.value.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.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_subtract(l.value, r.value), 'integer' if as_integer else 'double')) res = [VectorItem(None, el) for el in res] ret = VectorObj(res) return ret
def cast_atomic(e: Atomic, type_name): if e.get_type().name == type_name: return e elif type_name == 'character': ret = Atomic(bool(e.value), types.CharacterType(), is_na=e.is_na, is_nan=e.is_nan, is_inf=e.is_inf, is_neg=e.is_neg) return ret elif type_name == 'double': ret = Atomic(float(e.value), types.DoubleType(), is_na=e.is_na, is_nan=e.is_nan, is_inf=e.is_inf, is_neg=e.is_neg) return ret elif type_name == 'integer': ret = Atomic(int(e.value), types.IntegerType(), is_na=e.is_na, is_nan=e.is_nan, is_inf=e.is_inf, is_neg=e.is_neg) return ret elif type_name == 'logical': ret = Atomic(bool(e.value), types.LogicalType(), is_na=e.is_na, is_nan=e.is_nan, is_inf=e.is_inf, is_neg=e.is_neg) return ret else: raise Exception('unsupported vector cast type - {}'.format(type_name))
def evaluate(self): return language.Atomic.create(True if self.value == 'TRUE' else False, types.LogicalType())
def evaluate(self): return language.Atomic.create(None, types.LogicalType(), is_na=True)
import R.Types as types import R.LanguageObjs as language this_env: Environment = Environment(builtin.built_in_env) this_env.set_global(this_env) print('123') items1 = [ language.AssignObj.create(objs.SymbolObj('h'), Atomic.create(1, types.IntegerType())), Atomic.create(2, types.IntegerType()), Atomic.create(5, types.IntegerType()) ] items2 = [ Atomic.create(False, types.LogicalType()), language.AssignObj.create(objs.SymbolObj('f'), Atomic.create(1, types.IntegerType())), Atomic.create(5, types.IntegerType()), language.AssignObj.create(objs.SymbolObj('h'), Atomic.create(1, types.IntegerType())) ] symbol_c = objs.SymbolObj('c') c_call1 = CallObj(symbol_c, items1) vect1 = c_call1.evaluate(this_env) print(vect1.show_self()) c_call2 = CallObj(symbol_c, items2)