Example #1
0
 def _register_global(self, node, name):
     var = self.vars.get(name)
     if var:
         if var.type == Var.TYPE_PARAM:
             msg = "name '{}' is parameter and global"
             raise util.ParseError(node, msg.format(name))
         if var.type == Var.TYPE_LOCAL:
             msg = "name '{}' is used prior to global declaration"
             raise util.ParseError(node, msg.format(name))
     else:
         self.vars[name] = Var(name, Var.TYPE_GLOBAL)
Example #2
0
 def visit_Break(self, node):
   if not self.block.loop_stack:
     raise util.ParseError(node, "'break' not in loop")
   self._write_py_context(node.lineno)
   self.writer.write_tmpl(textwrap.dedent("""\
       $breakvar = true
       continue"""), breakvar=self.block.top_loop().breakvar.name)
Example #3
0
def _make_future_features(node):
    """Processes a future import statement, returning set of flags it defines."""
    assert isinstance(node, ast.ImportFrom)
    assert node.module == '__future__'
    features = FutureFeatures()
    for alias in node.names:
        name = alias.name
        if name in _FUTURE_FEATURES:
            if name not in _IMPLEMENTED_FUTURE_FEATURES:
                msg = 'future feature {} not yet implemented by grumpy'.format(
                    name)
                raise util.ParseError(node, msg)
            setattr(features, name, True)
        elif name == 'braces':
            raise util.ParseError(node, 'not a chance')
        elif name not in _REDUNDANT_FUTURE_FEATURES:
            msg = 'future feature {} is not defined'.format(name)
            raise util.ParseError(node, msg)
    return features
Example #4
0
 def visit_Return(self, node):
   assert isinstance(self.block, block.FunctionBlock)
   self._write_py_context(node.lineno)
   if self.block.is_generator and node.value:
     raise util.ParseError(node, 'returning a value in a generator function')
   if node.value:
     with self.visit_expr(node.value) as value:
       self.writer.write('πR = {}'.format(value.expr))
   else:
     self.writer.write('πR = πg.None')
   self.writer.write('continue')
Example #5
0
 def del_var(self, writer, name):
     var = self.vars.get(name)
     if not var:
         raise util.ParseError(
             None, 'cannot delete nonexistent local: {}'.format(name))
     if var.type == Var.TYPE_GLOBAL:
         return self.root.del_var(writer, name)
     adjusted_name = util.adjust_local_name(name)
     # Resolve local first to ensure the variable is already bound.
     writer.write_checked_call1('πg.CheckLocal(πF, {}, {})', adjusted_name,
                                util.go_str(name))
     writer.write('{} = πg.UnboundLocal'.format(adjusted_name))
Example #6
0
 def visit_BinOp(self, node):
   result = self.block.alloc_temp()
   with self.visit(node.left) as lhs, self.visit(node.right) as rhs:
     op_type = type(node.op)
     if op_type in ExprVisitor._BIN_OP_TEMPLATES:
       tmpl = ExprVisitor._BIN_OP_TEMPLATES[op_type]
       self.writer.write_checked_call2(
           result, tmpl, lhs=lhs.expr, rhs=rhs.expr)
     else:
       msg = 'binary op not implemented: {}'.format(op_type.__name__)
       raise util.ParseError(node, msg)
   return result
Example #7
0
 def visit_Print(self, node):
   if self.block.root.future_features.print_function:
     raise util.ParseError(node, 'syntax error (print is not a keyword)')
   self._write_py_context(node.lineno)
   with self.block.alloc_temp('[]*πg.Object') as args:
     self.writer.write('{} = make([]*πg.Object, {})'.format(
         args.expr, len(node.values)))
     for i, v in enumerate(node.values):
       with self.visit_expr(v) as arg:
         self.writer.write('{}[{}] = {}'.format(args.expr, i, arg.expr))
     self.writer.write_checked_call1('πg.Print(πF, {}, {})', args.expr,
                                     'true' if node.nl else 'false')
Example #8
0
 def visit_AugAssign(self, node):
   op_type = type(node.op)
   if op_type not in StatementVisitor._AUG_ASSIGN_TEMPLATES:
     fmt = 'augmented assignment op not implemented: {}'
     raise util.ParseError(node, fmt.format(op_type.__name__))
   self._write_py_context(node.lineno)
   with self.visit_expr(node.target) as target,\
       self.visit_expr(node.value) as value,\
       self.block.alloc_temp() as temp:
     self.writer.write_checked_call2(
         temp, StatementVisitor._AUG_ASSIGN_TEMPLATES[op_type],
         lhs=target.expr, rhs=value.expr)
     self._assign_target(node.target, temp.expr)
Example #9
0
 def __init__(self, node):
     BlockVisitor.__init__(self)
     self.is_generator = False
     node_args = node.args
     args = [a.arg for a in node_args.args]
     if node_args.vararg:
         args.append(node_args.vararg.arg)
     if node_args.kwarg:
         args.append(node_args.kwarg.arg)
     for i, name in enumerate(args):
         if name in self.vars:
             msg = "duplicate argument '{}' in function definition".format(
                 name)
             raise util.ParseError(node, msg)
         self.vars[name] = Var(name, Var.TYPE_PARAM, arg_index=i)
Example #10
0
 def _assign_target(self, target, value):
   if isinstance(target, ast.Name):
     self.block.bind_var(self.writer, target.id, value)
   elif isinstance(target, ast.Attribute):
     with self.visit_expr(target.value) as obj:
       self.writer.write_checked_call1(
           'πg.SetAttr(πF, {}, {}, {})', obj.expr,
           self.block.root.intern(target.attr), value)
   elif isinstance(target, ast.Subscript):
     with self.visit_expr(target.value) as mapping,\
         self.visit_expr(target.slice) as index:
       self.writer.write_checked_call1('πg.SetItem(πF, {}, {}, {})',
                                       mapping.expr, index.expr, value)
   else:
     msg = 'assignment target not yet implemented: ' + type(target).__name__
     raise util.ParseError(target, msg)
Example #11
0
 def visit_Delete(self, node):
   self._write_py_context(node.lineno)
   for target in node.targets:
     if isinstance(target, ast.Attribute):
       with self.visit_expr(target.value) as t:
         self.writer.write_checked_call1(
             'πg.DelAttr(πF, {}, {})', t.expr,
             self.block.root.intern(target.attr))
     elif isinstance(target, ast.Name):
       self.block.del_var(self.writer, target.id)
     elif isinstance(target, ast.Subscript):
       with self.visit_expr(target.value) as t,\
           self.visit_expr(target.slice) as index:
         self.writer.write_checked_call1('πg.DelItem(πF, {}, {})',
                                         t.expr, index.expr)
     else:
       msg = 'del target not implemented: {}'.format(type(target).__name__)
       raise util.ParseError(node, msg)
Example #12
0
 def visit_UnaryOp(self, node):
   result = self.block.alloc_temp()
   with self.visit(node.operand) as operand:
     op_type = type(node.op)
     if op_type in ExprVisitor._UNARY_OP_TEMPLATES:
       self.writer.write_checked_call2(
           result, ExprVisitor._UNARY_OP_TEMPLATES[op_type],
           operand=operand.expr)
     elif isinstance(node.op, ast.Not):
       with self.block.alloc_temp('bool') as is_true:
         self.writer.write_checked_call2(
             is_true, 'πg.IsTrue(πF, {})', operand.expr)
         self.writer.write('{} = πg.GetBool(!{}).ToObject()'.format(
             result.name, is_true.expr))
     else:
       msg = 'unary op not implemented: {}'.format(op_type.__name__)
       raise util.ParseError(node, msg)
   return result
Example #13
0
    def _write_except_dispatcher(self, exc, tb, handlers):
        """Outputs a Go code that jumps to the appropriate except handler.

    Args:
      exc: Go variable holding the current exception.
      tb: Go variable holding the current exception's traceback.
      handlers: A list of ast.ExceptHandler nodes.

    Returns:
      A list of Go labels indexes corresponding to the exception handlers.

    Raises:
      ParseError: Except handlers are in an invalid order.
    """
        handler_labels = []
        for i, except_node in enumerate(handlers):
            handler_labels.append(self.block.genlabel())
            if except_node.type:
                with self.visit_expr(except_node.type) as type_,\
                    self.block.alloc_temp('bool') as is_inst:
                    self.writer.write_checked_call2(
                        is_inst, 'πg.IsInstance(πF, {}.ToObject(), {})', exc,
                        type_.expr)
                    self.writer.write_tmpl(textwrap.dedent("""\
              if $is_inst {
              \tgoto Label$label
              }"""),
                                           is_inst=is_inst.expr,
                                           label=handler_labels[-1])
            else:
                # This is a bare except. It should be the last handler.
                if i != len(handlers) - 1:
                    msg = "default 'except:' must be last"
                    raise util.ParseError(except_node, msg)
                self.writer.write('goto Label{}'.format(handler_labels[-1]))
        if handlers[-1].type:
            # There's no bare except, so the fallback is to re-raise.
            self.writer.write(
                'πE = πF.Raise({}.ToObject(), nil, {}.ToObject())'.format(
                    exc, tb))
            self.writer.write('continue')
        return handler_labels
Example #14
0
 def visit_Num(self, node):
   if isinstance(node.n, int):
     expr_str = 'NewInt({})'.format(node.n)
   elif isinstance(node.n, long):
     a = abs(node.n)
     gobytes = ''
     while a:
       gobytes = hex(int(a&255)) + ',' + gobytes
       a >>= 8
     expr_str = 'NewLongFromBytes([]byte{{{}}})'.format(gobytes)
     if node.n < 0:
       expr_str = expr_str + '.Neg()'
   elif isinstance(node.n, float):
     expr_str = 'NewFloat({})'.format(node.n)
   elif isinstance(node.n, complex):
     expr_str = 'NewComplex(complex({}, {}))'.format(node.n.real, node.n.imag)
   else:
     msg = 'number type not yet implemented: ' + type(node.n).__name__
     raise util.ParseError(node, msg)
   return expr.GeneratedLiteral('πg.' + expr_str + '.ToObject()')
Example #15
0
 def _node_not_implemented(self, node):
     msg = 'node not yet implemented: ' + type(node).__name__
     raise util.ParseError(node, msg)
Example #16
0
 def generic_visit(self, node):
     msg = 'expression node not yet implemented: ' + type(node).__name__
     raise util.ParseError(node, msg)
Example #17
0
 def _check_duplicate_args(self, name, node):
     if name in self.vars:
         msg = "duplicate argument '{}' in function definition".format(name)
         raise util.ParseError(node, msg)
Example #18
0
 def visit_Continue(self, node):
   if not self.block.loop_stack:
     raise util.ParseError(node, "'continue' not in loop")
   self._write_py_context(node.lineno)
   self.writer.write('continue')
Example #19
0
 def generic_visit(self, node):
   msg = 'node not yet implemented: {}'.format(type(node).__name__)
   raise util.ParseError(node, msg)