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(0, types.IntegerType())) for _ in range(int(count) * (-1 if val.is_neg else 1)) ] ret = VectorObj(items, types.IntegerType()) 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 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 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 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(int(self.value[:-1]), types.IntegerType())
from R.Environment import Environment import R.RObj import R.BuiltIn as builtin from R.Function import FunctionObj, CallObj, Atomic, Arg import R.AtomicObjs as objs 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)
def create(*args): name = 'logical' args = [Arg('length', Atomic(0, types.IntegerType()))] return LogicalFun(name, args)
def create(*args): name = 'integer' args = [Arg('length', Atomic(0, types.IntegerType()))] return IntegerFun(name, args)
def create(*args): name = 'numeric' args = [Arg('length', Atomic(0, types.IntegerType()))] return NumericFun(name, args)
from R.Environment import Environment import R.RObj import R.BuiltIn as builtin from R.Function import FunctionObj, CallObj, Atomic, Arg import R.AtomicObjs as objs 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()), 'plain'), 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()), 'super'), Atomic.create(5, types.IntegerType()), language.AssignObj.create(objs.SymbolObj('h'), Atomic.create(1, types.IntegerType()), 'plain') ] symbol_c = objs.SymbolObj('c') c_call1 = CallObj(symbol_c, items1)