def _find_variable(self, toward): name = toward.name # if not variable if name is None: raise RequiredError('None') value = self.io.get(name) # not found if value is None: raise RequiredError(name) # if graph if type(value) is str: # set 'self' self.graph.push_self(name) # load script values = list(self.code_to_data(value)) for value in values: self.push(value) # remove 'self' self.graph.pop_self() # just script if toward.toward is None: return attr.AttrConst(False) var = self._execute_recursive(toward) return var # if binary elif type(value) is data.Constant: toward.toward = value var = self._execute_recursive(toward) return var raise NotImplementedError
def point_method(self, name, toward, repeat=None): # no user-defined method pointer if toward.is_method_defined: # if just declaring if toward.toward is None: raise RequiredError(toward.name) self.rename(name, self.new_name()) sub = Method(name, toward, repeat=repeat) sub.name = name self.vars[name] = sub return sub
def operate(self, op, sub, obj=None, step=None): # remove delegate if sub.is_method_delegate: if sub.name in self.vars.keys(): del self.vars[sub.name] toward = sub.toward sub.toward = None self.gc(toward) self.gc(sub) sub = self.find(sub.name) # = if op in Exp.IS: return self.inplace(sub, obj) # := (disposable substitute) if op in Exp.DIS: sub.is_pointer = True sub.is_pointer_orient = True # can substitute if sub.toward is None: name = sub.name if obj.has_attr(name): raise RequiredError(sub.symbol) sub.toward = obj return sub # else # remove obj self.gc(obj) return sub # in-place operators if op in Exp.Tokens_Inplace: if sub.toward is None: raise RequiredError(sub.name) tmp = Operator(op, sub.toward, obj, step) return self.inplace(sub, tmp) # out-place operators tmp = Operator(op, sub, obj, step) return tmp
def _execute_method_delegate(self, toward): name = toward.name toward_origin = toward repeat = toward.repeat while toward.toward is not None and not toward.is_method_defined: toward = toward.toward if name.startswith(Exp.CODE_CONST): name = toward.name repeat = self._execute_method_update_repeat(repeat, toward.repeat) # if builtins if toward.is_builtins: method, fixed = self.find_method(toward.name, find_hidden=False) args = attr.AttrTuple(toward_origin.args, self._execute_recursive) kwargs = attr.AttrDict(toward_origin.kwargs, self._execute_recursive) repeat = self._execute_recursive(repeat) return attr.AttrMethod(self, name, method, toward_origin, args, kwargs, fixed, repeat) # if user-defined methods if toward.is_method_defined: return self._execute_method_defined(toward, name, toward_origin.args, repeat) # undefined error raise RequiredError(toward.name)
def _execute_recursive(self, toward: data.Variable): # echo if toward is None: return None # if required if toward.is_required: var = self._find_variable(toward) return var # is variable if toward.is_variable: return self._execute_variable(toward) # is constant if toward.is_constant: return self._execute_constant(toward) # is slicing if toward.is_indices: return self._execute_indexed(toward) # is transpose if toward.is_transpose: return self._execute_transpose(toward) # is view if toward.is_view: return self._execute_view(toward) # is tuple if toward.is_tuple: return self._execute_tuple(toward) # is operator if toward.is_operator: return self._execute_operator(toward) # is user-defined method if toward.is_method_defined: raise RequiredError(toward.name) # is method if toward.is_method: return self._execute_method(toward) raise NotImplementedError
def inplace(self, sub, obj): # only variable, method, tuple in sub name = sub.name if not (sub.is_variable or sub.is_method or sub.is_operator): raise SyntaxError(name) # point method if obj.is_method_delegate: # no tuple-delegate if sub.is_tuple: raise SyntaxError(Exp.IS[0]) # else self.point_method(name, obj) return self.vars[name] # var-tuple if not sub.is_tuple and obj.is_tuple: # only var-tuple if not sub.is_variable: raise SyntaxError(Exp.IS[0]) # substitute old = sub.toward sub.toward = obj self.gc(old) return sub # tuple-var if sub.is_tuple and not obj.is_tuple: # only tuple-var(tuple) if obj.is_variable: if obj.toward.is_tuple: return self.inplace(sub, obj.toward) else: raise SyntaxError(Exp.IS[0]) else: raise SyntaxError(Exp.IS[0]) # tuple-tuple if sub.is_tuple and obj.is_tuple: # only same dims if len(sub.args) != len(obj.args): raise SyntaxError(Exp.IS[0]) # in-place in order for arg_sub, arg_obj in zip(sub.args, obj.args): self.inplace(arg_sub, arg_obj) return sub # else (tuple-var, var-var) # rename if recursion if sub.is_variable: if obj.has_attr(name): # check target is pointer old = self.vars[name] if old.is_required: raise RequiredError(name) # else # replace sub with sub.toward obj = obj.replace(name) sub.toward = obj return sub # substitute # remove previous old = sub.toward sub.toward = obj self.gc(old) return sub
def _calculate(self): if not self.is_data: raise NotDataError(self.symbol) if self.toward is None: raise RequiredError(self.symbol) return self.to_value(self.toward)