def product(self, node): args = node.args if len(args) == 2: n = ast2str(args[0]) n = n.replace(",", ";") n = n.replace(" ", "") n = n.replace("_sage_const_", "") N = int(n) right = self.visit(args[1]) e_coeff = Coeff(right.batch, var('e')) b_coeff = Coeff(right.batch, var('b')) p_coeff = Coeff(right.batch, var('p')) total = N * right.total batch = (N * e_coeff) * formula('e') + \ (N * p_coeff) * formula('p') if N != 0: if b_coeff != 0: s = right.type_[5:] + '_mul' total += (N - 1) * formula(s) batch += formula('b') R = Reduced(right.type_, node, total=total, batch=batch) return R else: semantic_error(node,\ "invalid arguments for product:" + ast2str(node))
def operation_Pow(self, X, Y, node, **kwargs): # self.Print("operation_Pow:", X.type_,",", Y.type_) # self.Print("operation_Pow:", kwargs['X_value'],",", kwargs['Y_value']) X_value = kwargs['X_value'] Y_value = kwargs['Y_value'] if (type(Y_value) == int): if (Y_value == 1) or (Y_value == 0): if (X.type_ == 'TYPE_INTEGER') or \ (X.type_ == 'TYPE_GROUP') or \ (X.type_ == 'TYPE_GROUP0') or \ (X.type_ == 'TYPE_GROUP1') or \ (X.type_ == 'TYPE_GROUP2') or \ (X.type_ == 'TYPE_TARGET'): return X if (Y_value < 0): mY = Reduced('TYPE_INTEGER', node.right, total=0, batch=0) one = Reduced('TYPE_INTEGER', node.right, total=0, batch=0) Pow_kwargs = {} Pow_kwargs['X_value'] = X_value Pow_kwargs['Y_value'] = -Y_value Div_kwargs = {} Div_kwargs['X_value'] = 1 Div_kwargs['Y_value'] = 'unknown' return self.operation_Div(one,\ self.operation_Pow(X,mY,node,**Pow_kwargs),\ node, **Div_kwargs) if (X.type_ == 'TYPE_TARGET') or \ (X.type_ == 'TYPE_GROUP') or \ (X.type_ == 'TYPE_GROUP0') or \ (X.type_ == 'TYPE_GROUP1') or \ (X.type_ == 'TYPE_GROUP2'): X.batch = Batch(X) Y.batch = Batch(Y) X_b_coeff = Coeff(X.batch, var('b')) X_e_coeff = Coeff(X.batch, var('e')) X_p_coeff = Coeff(X.batch, var('p')) Y_b_coeff = Coeff(Y.batch, var('b')) Y_e_coeff = Coeff(Y.batch, var('e')) Y_p_coeff = Coeff(Y.batch, var('p')) s = X.type_[5:] + '_mul' total = X_e_coeff * formula(s) batch = (X_e_coeff + X_b_coeff) * formula('e') + \ (X_p_coeff ) * formula('p') return Reduced(X.type_, node, \ total=Total(X)+Total(Y)+total, batch=batch, **kwargs) elif X.type_ == 'TYPE_INTEGER': s = X.type_[5:] + '_pow' return Reduced(X.type_, node, \ total=Total(X)+Total(Y)+formula(s), batch=0, **kwargs) else: warning(node, 'cannot infer type of ' + ast2str(X.node)) return Reduced(X.type_, node, \ total=Total(X)+Total(Y), batch=0, **kwargs)
def transfer_batch(X): X.batch = Batch(X) e_coeff = Coeff(X.batch, var('e')) b_coeff = Coeff(X.batch, var('b')) p_coeff = Coeff(X.batch, var('p')) if e_coeff != 0: s = X.type_[5:] + '_batch(' + str(e_coeff) + ';' \ + str(b_coeff) + ')' X.total = formula(s) + X.total if p_coeff != 0: s = 'pairing_batch(' + str(p_coeff) + ')' X.total = formula(s) + X.total X.total -= (p_coeff - 1) * formula('TARGET_mul') X.batch = 0
def visit_For(self, node): body = self.visit(node.body) transfer_batch(body) total = body.total if node.orelse: orelse = self.visit(node.orelse) transfer_batch(orelse) orelse = orelse.total else: orelse = 0 t = ast2str(node.target) t = t.replace(",", ";") t = t.replace(" ", "") t = t.replace("_sage_const_", "") u = ast2str(node.iter) u = u.replace(",", ";") u = u.replace(" ", "") u = u.replace("_sage_const_", "") s = 'for_statement("' s += t s += '";"' s += u s += '";' s += str(total).replace(' ', '') s += ';' s += str(orelse).replace(' ', '') s += ")" total = formula(s) return Reduced('TYPE_FOR', node, total=total, batch=0)
def visit_If(self, node): body = self.visit(node.body) transfer_batch(body) total = body.total # elifs. if (node.orelse and len(node.orelse) == 1 and \ isinstance(node.orelse[0], ast.If)): orelse = self.visit(node.orelse[0]) transfer_batch(orelse) orelse = orelse.total # final else elif node.orelse: orelse = self.visit(node.orelse) transfer_batch(orelse) orelse = orelse.total else: orelse = 0 t = ast2str(node.test) t = t.replace(",", ";") t = t.replace(" ", "") s = 'if_statement("' s += t s += '";' s += str(total) s += ';' s += str(orelse) s += ")" total = formula(s) return Reduced('TYPE_IF', node, total=total, batch=0)
def transfer_bitexp(X, n): X.batch = Batch(X) e_coeff = Coeff(X.batch, var('e')) b_coeff = Coeff(X.batch, var('b')) p_coeff = Coeff(X.batch, var('p')) if e_coeff != 0: s = X.type_[5:] + \ '_bitexp(' + str(n) + ';' \ + str(e_coeff) + ';' \ + str(b_coeff) + ')' X.total = formula(s) + X.total if p_coeff != 0: s = "pairing_batch(" + str(p_coeff) + ")" X.total = formula(s) + X.total X.total -= (p_coeff - 1) * formula("TARGET_mul") X.batch = 0
def operation_Name(self, node): total = 0 batch = 0 if hasattr(node, 'InferredType'): type_ = node.InferredType else: type_ = 'TYPE_UNKNOWN16' if (type_ == 'TYPE_GROUP') or \ (type_ == 'TYPE_GROUP0') or \ (type_ == 'TYPE_GROUP1') or \ (type_ == 'TYPE_GROUP2') or \ (type_ == 'TYPE_TARGET'): batch = formula('b') if hasattr(node, 'InferredValue'): value = node.InferredValue return Reduced(type_, node, value=value, total=total, batch=batch, id=node.id) else: return Reduced(type_, node, total=total, batch=batch, id=node.id)
def visit_Call(self, node): func = node.func args = node.args ret = self.visit(func) total = 0 batch = 0 type_ = InferredType(node) if not hasattr(ret, 'id'): if type(args) in [list, tuple]: for i in range(len(args)): child = self.visit(args[i]) transfer_batch(child) total = child.total + total else: symbol = ret.node.id if (symbol == 'bitexp'): return self.bitexp(node) if (symbol == 'inline'): return self.inline(node) if (symbol == 'product'): return self.product(node) if type(args) in [list, tuple]: for i in range(len(args)): child = self.visit(args[i]) transfer_batch(child) total = child.total + total # <-- process_Assign if (symbol == 'e'): return Reduced('TYPE_TARGET', node, total=total, \ batch=formula('b') + formula('p')) else: if (symbol != 'Integer') and \ (symbol != 'Group') and \ (symbol != 'Group0') and \ (symbol != 'Group1') and \ (symbol != 'Group2') and \ (symbol != 'Target'): total = formula('call_' + symbol) + total if (type_ == 'TYPE_GROUP') or \ (type_ == 'TYPE_GROUP0') or \ (type_ == 'TYPE_GROUP1') or \ (type_ == 'TYPE_GROUP2') or \ (type_ == 'TYPE_TARGET'): batch = formula('b') return Reduced(type_, node, total=total, batch=batch)
def operation_Add(self, X, Y, node, **kwargs): # self.Print("operation_Add:", X.value,",", Y.value) if (X.type_ != 'TYPE_INTEGER') or \ (Y.type_ != 'TYPE_INTEGER'): return Reduced(X.type_, node, total=0) transfer_batch(X) transfer_batch(Y) s = X.type_[5:] + '_add' total = formula(s) + Total(X) + Total(Y) return Reduced(X.type_, node, total=total, batch=0, **kwargs)
def operation_Sub(self, X, Y, node, **kwargs): # self.Print("operation_Sub:", X.type_,",", Y.type_) if (X.type_ != 'TYPE_INTEGER') or \ (Y.type_ != 'TYPE_INTEGER'): return Reduced(X.type_, node, total=0) transfer_batch(X) transfer_batch(Y) s = X.type_[5:] + '_sub' total = formula(s) + Total(X) + Total(Y) # print("operation_Sub:", total) return Reduced(X.type_, node, total=total, batch=0, **kwargs)
def operation_Div(self, X, Y, node, **kwargs): # self.Print("operation_Div:", X.type_,",", Y.type_) X_value = kwargs['X_value'] Y_value = kwargs['Y_value'] # X/1 if (Y.type_ == 'TYPE_INTEGER') and (Y_value == 1): if (X.type_ == 'TYPE_INTEGER') or \ (X.type_ == 'TYPE_GROUP') or \ (X.type_ == 'TYPE_GROUP0') or \ (X.type_ == 'TYPE_GROUP1') or \ (X.type_ == 'TYPE_GROUP2') or \ (X.type_ == 'TYPE_TARGET'): return X # 1/Y if (X.type_ == 'TYPE_INTEGER') and (X_value == 1): if (Y.type_ == 'TYPE_GROUP') or \ (Y.type_ == 'TYPE_GROUP0') or \ (Y.type_ == 'TYPE_GROUP1') or \ (Y.type_ == 'TYPE_GROUP2'): return Y if (Y.type_ == 'TYPE_TARGET'): X.type_ = 'TYPE_TARGET' X.batch = formula('b') # if (X.type_ == 'TYPE_INTEGER'): # if not (((X.type_ == 'TYPE_INTEGER') or \ # (X.type_ == 'TYPE_GROUP') or \ # (X.type_ == 'TYPE_GROUP0') or \ # (X.type_ == 'TYPE_GROUP1') or \ # (X.type_ == 'TYPE_GROUP2') or \ # (X.type_ == 'TYPE_TARGET')) and \ # (X.type_ == Y.type_)): # OPERATION_ERROR2() if (X.type_ == 'TYPE_TARGET') or \ (X.type_ == 'TYPE_GROUP') or \ (X.type_ == 'TYPE_GROUP0') or \ (X.type_ == 'TYPE_GROUP1') or \ (X.type_ == 'TYPE_GROUP2'): X.batch = Batch(X) Y.batch = Batch(Y) X_b_coeff = Coeff(X.batch, var('b')) X_e_coeff = Coeff(X.batch, var('e')) X_p_coeff = Coeff(X.batch, var('p')) Y_b_coeff = Coeff(Y.batch, var('b')) Y_e_coeff = Coeff(Y.batch, var('e')) Y_p_coeff = Coeff(Y.batch, var('p')) total = 0 batch = (X_e_coeff + Y_e_coeff) * formula('e') + \ (X_p_coeff + Y_p_coeff) * formula('p') if (X_b_coeff != 0) and (Y_b_coeff != 0): s = X.type_[5:] + '_div' total = formula(s) if (X_b_coeff != 0) or (Y_b_coeff != 0): batch += formula('b') return Reduced(X.type_, node, \ total=Total(X)+Total(Y)+total, batch=batch, **kwargs) elif X.type_ == 'TYPE_INTEGER': s = X.type_[5:] + '_div' total = formula(s) return Reduced(X.type_, node, \ total=Total(X)+Total(Y)+formula(s), batch=0, **kwargs) else: warning(node, 'cannot infer type of ' + ast2str(X.node)) return Reduced(X.type_, node, \ total=Total(X)+Total(Y), batch=0, **kwargs)