def p_logical_expression_not(self, p): '''logical_expression : BOOL_NOT logical_expression''' t = Token('NOT', '!') p[0] = UnaryOp(p[2], t) if p[2].dtype != ('bool', 0): print('invalid usage of operator logical NOT.') sys.exit(0) p[0].dtype = ('bool', 0)
def p_exression_deref(self, p): '''expression : STAR expression''' t = Token('DEREF', p[1]) p[0] = UnaryOp(p[2], t) dtype = p[2].dtype if dtype[1] <= 0: print('invalid usage of pointer.') sys.exit(0) p[0].dtype = (dtype[0], dtype[1] - 1)
def p_lhs(self, p): '''lhs : STAR lhs''' t = Token('DEREF', p[1]) p[0] = UnaryOp(p[2], t) dtype = p[2].dtype if dtype[1] <= 0: print('invalid usage of pointer.') sys.exit(0) p[0].dtype = (dtype[0], dtype[1] - 1)
def p_addr(self, p): '''addr : AND id''' if p[2].entry['type'] == 'function': print('invalid usage of function %s.' % (p[2].value)) sys.exit(0) t = Token('ADDR', p[1]) p[0] = UnaryOp(p[2], t) dtype = p[2].entry['type'] p[0].dtype = (dtype[0], dtype[1] + 1)
def p_expression_uminus(self, p): '''expression : MINUS expression %prec UMINUS''' t = Token('UMINUS', '-') p[0] = UnaryOp(p[2], t) check_direct_access(p[2]) dtype = p[2].dtype if dtype[0] == 'void' or dtype[1] != 0: print( 'invalid use of operator unary minus on expression of type: ', dtype) sys.exit(0) p[0].dtype = dtype
def visit_unary(self, node: ast.UnaryOp): # print("visiting unary") op = None expr = None for name, child in node.children(): if name == "op": op = child elif name == "expr": expr = child try: e = self.visit(expr) if op is not None: if isinstance(e, ast.ID): e = self.lookupSymTables(e.getName()) if e == 'F': e = False elif e == 'T': e = True if op == '!': return (not e) elif op == '+': return e elif op == '-': return -e return e except Exception as e: raise Exception(e)
def handle_q(self, q): if not q.children: expr = Name(id="True", **self.file) elif len(q.children) == 1: expr = self._attr_lookup(*q.children[0]) elif q.connector == "AND": expr = Call( func=Name(id="all", **self.file), args=[ List(elts=[self._attr_lookup(k, v) for k, v in q.children], **self.file) ], keywords=[], kwonlyargs=[], **self.file, ) else: # q.connector == 'OR' expr = Call( func=Name(id="any", **self.file), args=[ List(elts=[self._attr_lookup(k, v) for k, v in q.children], **self.file) ], keywords=[], kwonlyargs=[], **self.file, ) if q.negated: return UnaryOp(op=Not(), operand=expr, **self.file) return expr
def _if_gt(value): if value >= 0: comparators = [Constant(value=value, kind=None)] else: comparators = [ UnaryOp( op=USub(), operand=Constant(value=abs(value), kind=None), ), ] return [ If( test=Compare( left=Call( func=Name(id='int', ctx=Load()), args=[Name(id='value', ctx=Load())], keywords=[], ), ops=[Gt()], comparators=comparators, ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ) ]
def _if_pattern(self, pattern): self.imported.add('re') # fix known ietf regex use pattern = pattern.replace('\\p{N}\\p{L}', '\\w') return [ If( test=UnaryOp( op=Not(), operand=Call( func=Attribute( value=Name(id='re', ctx=Load()), attr='match', ctx=Load(), ), args=[ Constant(value=pattern, kind=None), Name(id='value', ctx=Load()), Attribute( value=Name(id='re', ctx=Load()), attr='UNICODE', ctx=Load(), ), ], keywords=[], ), ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ), ]
def split_expr(self, expr_ast): if isinstance(expr_ast, BinOp): tl = self.split_expr(expr_ast.left_child) tr = self.split_expr(expr_ast.right_child) if expr_ast.token.type == 'ASGN': self.temp_body.append(BinOp(tl, tr, expr_ast.token)) return None temp_var = Var('t' + str(self.temp_count + self.temp_start)) self.temp_count += 1 self.temp_body.append( BinOp(temp_var, BinOp(tl, tr, expr_ast.token), Token('ASGN', '='))) return temp_var elif isinstance(expr_ast, UnaryOp): if expr_ast.token.type in ('NOT', 'UMINUS'): t = self.split_expr(expr_ast.child) temp_var = Var('t' + str(self.temp_count + self.temp_start)) self.temp_count += 1 self.temp_body.append( BinOp(temp_var, UnaryOp(t, expr_ast.token), Token('ASGN', '='))) return temp_var else: t = self.split_expr(expr_ast.child) return UnaryOp(t, expr_ast.token) elif isinstance(expr_ast, FunctionCall): t_params = [self.split_expr(x) for x in expr_ast.actual_params] # temp_var = Var('t' + str(self.temp_count + self.temp_start)) # self.temp_count += 1 # self.temp_body.append(BinOp(temp_var, FunctionCall(expr_ast.id, t_params), Token('ASGN', '='))) # return temp_var return FunctionCall(expr_ast.id, t_params) else: return expr_ast
def visit_UnaryOp(self, node: ast.UnaryOp): if type(node.op) not in _known_unary_operators: raise Exception(f"Do not know how to translate Unary operator {ast.dump(node.op)}!") operand = self.get_rep(node.operand) s = operand.scope() r = crep.cpp_value(f"({_known_unary_operators[type(node.op)]}({operand.as_cpp()}))", s, operand.cpp_type()) node.rep = r # type: ignore self._result = r
def factor(self, f): if len(f) == 2: op, operand = f op = { '+': UAdd(), '-': USub(), }.get(op.value, None) if op is not None: return UnaryOp(op=op, operand=operand) # print(f) return Tree(data='factor', children=f)
def visit_UnaryOp(self, node: ast.UnaryOp) -> Union[ast.UnaryOp, ast.Constant]: """Evaluate unary operation and return ast.Constant if operand is bound. Args: node: Unary operation to evaluate. Returns: Evaluated value. """ node.operand = self.visit(node.operand) if isinstance(node.operand, (ast.Constant, ast.Num)): val = ast.Constant(n=self._match_ops(node.op, self._unary_ops, node.operand.n)) return ast.copy_location(val, node) return node
def visit_unary(self, node: ast.UnaryOp): print("unary") op = None expr = None for name, child in node.children(): if name == "op": op = child elif name == "expr": expr = child try: if op is not None: pass else: return self.visit(expr) except: pass
def get_module_assignments(node_info_path): """ Returns module assignment nodes which declare ModuleType object in case if this object has not been declared in the current scope. """ target_id = '' module_assignments = [] for item in node_info_path.split('.'): target_id += f'.{item}' if target_id else item target = Name(id=target_id, ctx=Store()) is_module_imported = None scope = Call(func=Name(id='locals'), args=[], keywords=[]) for path_part in target_id.split('.'): is_module_imported = Call( func=Attribute(value=scope, attr='get'), args=[Str(s=path_part), Dict(keys=[], values=[])], keywords=[]) scope = Attribute(value=is_module_imported, attr='__dict__', ctx=Load()) is_module_imported = Call(func=Name(id='isinstance', ctx=Load()), args=[ is_module_imported, Attribute(value=Name(id='types', ctx=Load()), attr='ModuleType', ctx=Load()) ], keywords=[]) module_assignments.append( If(test=UnaryOp(Not(), is_module_imported), body=[ Assign(targets=[target], value=Call(func=Attribute(value=Name(id='types', ctx=Load()), attr='ModuleType', ctx=Load()), args=[ Str(s=target.id), Str(s=f'The {target.id} module') ], keywords=[])) ], orelse=[])) return module_assignments
def visit_UnaryOp( self, ast_node_UnaryOp: ast.UnaryOp) -> Union[ast.UnaryOp, ast.Constant]: """ Evaluate unary operation and return ast.UnaryOp or ast.Constant if operand is bound. :param ast_node_UnaryOp: unary operation to evaluate. :return: evaluated value. """ ast_node_UnaryOp.operand = self.visit(ast_node_UnaryOp.operand) if isinstance(ast_node_UnaryOp.operand, ast.Constant): new_ast_node_UnaryOp = ast.Constant(value=self._match_operator( ast_node_UnaryOp.op, self._ast_math_UnaryOperators, ast_node_UnaryOp.operand.value)) return ast.copy_location(new_ast_node_UnaryOp, ast_node_UnaryOp) return ast_node_UnaryOp
def _union(self, node): values = [] generated = [] for union in node: for what, sub in union.items(): if ':' in what: if what in generated: # only generate any imported function once continue generated.append(what) name = what yield self._type(what, name, sub) else: # this is a build_in type (and my have been refined) # therefore generate one function per type name = self._unique(what) yield self._function(name, self._type(what, what, sub)) values += [ UnaryOp( op=Not(), operand=Call( func=Name(id=self._python_name(name), ctx=Load()), args=[Name(id='value', ctx=Load())], keywords=[], ), ), ] yield [ If( test=BoolOp( op=And(), values=values, ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ), ]
def _if_digit(): return [ If( test=UnaryOp( op=Not(), operand=Call( func=Attribute( value=Name(id='value', ctx=Load()), attr='isdigit', ctx=Load(), ), args=[], keywords=[], ), ), body=[ Return(value=Constant(value=False, kind=None), ), ], orelse=[], ) ]
def visit_UnaryOp(self, un_op: ast.UnaryOp) -> Optional[IType]: """ Verifies if the type of the operand is valid to the operation If the operation is valid, changes de Python operator by the Boa operator in the syntax tree :param un_op: the python ast unary operation node :return: the type of the result of the operation if the operation is valid. Otherwise, returns None :rtype: IType or None """ operator: Operator = self.get_operator(un_op.op) operand = self.visit(un_op.operand) if not isinstance(operator, Operator): # the operator is invalid or it was not implemented yet self._log_error( CompilerError.UnresolvedReference(un_op.lineno, un_op.col_offset, type(un_op.op).__name__) ) try: operation: UnaryOperation = self.get_un_op(operator, operand) if operation is None: self._log_error( CompilerError.NotSupportedOperation(un_op.lineno, un_op.col_offset, operator) ) elif not operation.is_supported: self._log_error( CompilerError.NotSupportedOperation(un_op.lineno, un_op.col_offset, operator) ) else: un_op.op = operation return operation.result except CompilerError.MismatchedTypes as raised_error: raised_error.line = un_op.lineno raised_error.col = un_op.col_offset # raises the exception with the line/col info self._log_error(raised_error)
def p_deref(self, p): '''deref : STAR deref_addr | STAR id''' t = Token('DEREF', p[1]) p[0] = UnaryOp(p[2], t)
def visitExpr(self, ctx: D96Parser.ExprContext): if ctx.getChildCount() == 1: if ctx.literal(): return self.visit(ctx.literal()) if ctx.idx_arr(): return self.visit(ctx.idx_arr()) if ctx.mul_dim_arr(): return self.visit(ctx.mul_dim_arr()) if ctx.SELF(): return NullLiteral() if ctx.NULL(): return SelfLiteral() if ctx.ID(): return Id(ctx.ID().getText()) if ctx.func_call(): return self.visit(ctx.func_call()) elif ctx.NEW(): name = Id(ctx.ID().getText()) expr = self.visit(ctx.expr_list()) return NewExpr(name, expr_list) elif ctx.STATIC_ACC(): id = Id(ctx.ID().getText()) sta_id = Id(ctx.STATIC_ID().getText()) expr_list = self.visit(ctx.expr_list()) return CallExpr(id, sta_id, expr_list) elif ctx.DOT(): id = Id(ctx.ID().getText()) expr = self.visit(ctx.expr()) expr_list = self.visit(ctx.expr_list()) return CallExpr(expr, id, expr_list) elif ctx.LSB() or ctx.RSB(): expr_list = [] for i in ctx.expr(): expr_list.append(self.visit(i)) return ArrayCell(expr_list[:1], expr_list[1:]) elif ctx.SUB(): return UnaryOp("-", self.visit(ctx.expr())) elif ctx.NOT(): return UnaryOp("!", self.visit(ctx.expr())) elif ctx.MUL() or ctx.DIV() or ctx.PRCNT(): left = self.visit(ctx.expr(0)) right = self.visit(ctx.expr(1)) if ctx.MUL(): return BinaryOp("*", left, right) elif ctx.DIV(): return BinaryOp("/", left, right) else: return BinaryOp("%", left, right) elif ctx.ADD() or ctx.SUB(): left = self.visit(ctx.expr(0)) right = self.visit(ctx.expr(1)) if ctx.ADD(): return BinaryOp("+", left, right) else: return BinaryOp("-", left, right) elif ctx.AND() or ctx.OR(): left = self.visit(ctx.expr(0)) right = self.visit(ctx.expr(1)) if ctx.AND(): return BinaryOp("&&", left, right) else: return BinaryOp("||", left, right) elif ctx.EQ() or ctx.NOT_EQ() or ctx.LESS() or ctx.GREAT() or ctx.LESS_EQ() or ctx.GREAT_EQ(): left = self.visit(ctx.expr(0)) right = self.visit(ctx.expr(1)) if ctx.EQ(): return BinaryOp("==", left, right) elif ctx.NOT_EQ(): return BinaryOp("!=", left, right) elif ctx.LESS(): return BinaryOp("<", left, right) elif ctx.GREAT(): return BinaryOp(">", left, right) elif ctx.LESS_EQ(): return BinaryOp("<=", left, right) else: return BinaryOp(">=", left, right) elif ctx.EQ_STR() or ctx.CONCAT_STR(): left = self.visit(ctx.expr(0)) right = self.visit(ctx.expr(1)) if ctx.EQ_STR(): return Binary("==.",left, right) else: return Binary("++.", left, right) else: return self.visit(ctx.expr())
], func=Attribute( Name("math_ops", Load()), "square", Load(), ), keywords=[], expr=None, expr_func=None, ) ], func=Attribute(Name("K", Load()), "mean", Load()), keywords=[ keyword( arg="axis", value=UnaryOp(USub(), set_value(1)), identifier=None, ) ], expr=None, expr_func=None, ), expr=None, ), ], decorator_list=[], name="__call__", returns=None, arguments_args=None, identifier_name=None, stmt=None,
def p_logical_expression_not(self, p): '''logical_expression : BOOL_NOT logical_expression''' t = Token('NOT', '!') p[0] = UnaryOp(p[2], t)
def not_expr(self, n): return UnaryOp(Not(), n[0])
def p_expression_uminus(self, p): '''expression : MINUS expression %prec UMINUS''' t = Token('UMINUS', '-') p[0] = UnaryOp(p[2], t)
def p_addr(self, p): '''addr : AND deref_addr | AND id''' t = Token('ADDR', p[1]) p[0] = UnaryOp(p[2], t)