Example #1
0
 def testWriteExceptDispatcherBareExceptionNotLast(self):
   visitor = stmt.StatementVisitor(_MakeModuleBlock())
   handlers = [ast.ExceptHandler(type=None),
               ast.ExceptHandler(type=ast.Name(id='foo'))]
   self.assertRaisesRegexp(util.ParseError, r"default 'except:' must be last",
                           visitor._write_except_dispatcher,  # pylint: disable=protected-access
                           'exc', 'tb', handlers)
Example #2
0
def _ParseAndVisit(source):
    mod = pythonparser.parse(source)
    future_features = stmt.visit_future(mod)
    b = block.ModuleBlock('__main__', '<test>', source, future_features)
    visitor = stmt.StatementVisitor(b)
    visitor.visit(mod)
    return visitor
Example #3
0
def _ParseAndVisit(source):
  mod = ast.parse(source)
  future_features = stmt.visit_future(mod)
  b = block.ModuleBlock('__main__', 'grumpy', 'grumpy/lib', '<test>',
                        source.split('\n'), future_features)
  visitor = stmt.StatementVisitor(b)
  visitor.visit(mod)
  return visitor
Example #4
0
def _ParseAndVisit(source):
  mod = pythonparser.parse(source)
  _, future_features = imputil.parse_future_features(mod)
  importer = imputil.Importer(None, 'foo', 'foo.py', False)
  b = block.ModuleBlock(importer, '__main__', '<test>',
                        source, future_features)
  visitor = stmt.StatementVisitor(b)
  visitor.visit(mod)
  return visitor
Example #5
0
 def testWriteExceptDispatcherBareExcept(self):
   visitor = stmt.StatementVisitor(_MakeModuleBlock())
   handlers = [ast.ExceptHandler(type=ast.Name(id='foo')),
               ast.ExceptHandler(type=None)]
   self.assertEqual(visitor._write_except_dispatcher(  # pylint: disable=protected-access
       'exc', 'tb', handlers), [1, 2])
   expected = re.compile(r'ResolveGlobal\(.*foo.*\bIsInstance\(.*'
                         r'goto Label1.*goto Label2', re.DOTALL)
   self.assertRegexpMatches(visitor.writer.getvalue(), expected)
Example #6
0
 def testWriteExceptDispatcherMultipleExcept(self):
   visitor = stmt.StatementVisitor(_MakeModuleBlock())
   handlers = [ast.ExceptHandler(type=ast.Name(id='foo')),
               ast.ExceptHandler(type=ast.Name(id='bar'))]
   self.assertEqual(visitor._write_except_dispatcher(  # pylint: disable=protected-access
       'exc', 'tb', handlers), [1, 2])
   expected = re.compile(
       r'ResolveGlobal\(.*foo.*\bif .*\bIsInstance\(.*\{.*goto Label1.*'
       r'ResolveGlobal\(.*bar.*\bif .*\bIsInstance\(.*\{.*goto Label2.*'
       r'\bRaise\(exc\.ToObject\(\), nil, tb\.ToObject\(\)\)', re.DOTALL)
   self.assertRegexpMatches(visitor.writer.getvalue(), expected)
Example #7
0
  def visit_function_inline(self, node):
    """Returns an GeneratedExpr for a function with the given body."""
    # First pass collects the names of locals used in this function. Do this in
    # a separate pass so that we know whether to resolve a name as a local or a
    # global during the second pass.
    func_visitor = block.FunctionBlockVisitor(node)
    for child in node.body:
      func_visitor.visit(child)
    func_block = block.FunctionBlock(self.block, node.name, func_visitor.vars,
                                     func_visitor.is_generator)
    # TODO: Find a better way to reduce coupling between ExprVisitor and
    # StatementVisitor.
    from grumpy.compiler import stmt  # pylint: disable=g-import-not-at-top
    visitor = stmt.StatementVisitor(func_block)
    # Indent so that the function body is aligned with the goto labels.
    with visitor.writer.indent_block():
      visitor._visit_each(node.body)  # pylint: disable=protected-access

    result = self.block.alloc_temp()
    with self.block.alloc_temp('[]πg.Param') as func_args:
      args = node.args
      argc = len(args.args)
      self.writer.write('{} = make([]πg.Param, {})'.format(
          func_args.expr, argc))
      # The list of defaults only contains args for which a default value is
      # specified so pad it with None to make it the same length as args.
      defaults = [None] * (argc - len(args.defaults)) + args.defaults
      for i, (a, d) in enumerate(zip(args.args, defaults)):
        with self.visit(d) if d else expr.nil_expr as default:
          tmpl = '$args[$i] = πg.Param{Name: $name, Def: $default}'
          self.writer.write_tmpl(tmpl, args=func_args.expr, i=i,
                                 name=util.go_str(a.id), default=default.expr)
      flags = []
      if args.vararg:
        flags.append('πg.CodeFlagVarArg')
      if args.kwarg:
        flags.append('πg.CodeFlagKWArg')
      # The function object gets written to a temporary writer because we need
      # it as an expression that we subsequently bind to some variable.
      self.writer.write_tmpl(
          '$result = πg.NewFunction(πg.NewCode($name, $filename, $args, '
          '$flags, func(πF *πg.Frame, πArgs []*πg.Object) '
          '(*πg.Object, *πg.BaseException) {',
          result=result.name, name=util.go_str(node.name),
          filename=util.go_str(self.block.filename), args=func_args.expr,
          flags=' | '.join(flags) if flags else 0)
      with self.writer.indent_block():
        for var in func_block.vars.values():
          if var.type != block.Var.TYPE_GLOBAL:
            fmt = 'var {0} *πg.Object = {1}; _ = {0}'
            self.writer.write(fmt.format(
                util.adjust_local_name(var.name), var.init_expr))
        self.writer.write_temp_decls(func_block)
        if func_block.is_generator:
          self.writer.write('return πg.NewGenerator(πF, func(πSent *πg.Object) '
                            '(*πg.Object, *πg.BaseException) {')
          with self.writer.indent_block():
            self.writer.write_block(func_block, visitor.writer.out.getvalue())
          self.writer.write('}).ToObject(), nil')
        else:
          self.writer.write_block(func_block, visitor.writer.out.getvalue())
      self.writer.write('}), πF.Globals()).ToObject()')
    return result
Example #8
0
def _ParseAndVisitExpr(expr):
    visitor = stmt.StatementVisitor(_MakeModuleBlock())
    visitor.visit_expr(_ParseExpr(expr))
    return visitor.writer.getvalue()
Example #9
0
def _ParseAndVisit(source):
    b = block.ModuleBlock('__main__', 'grumpy', 'grumpy/lib', '<test>',
                          source.split('\n'))
    visitor = stmt.StatementVisitor(b)
    visitor.visit(ast.parse(source))
    return visitor
Example #10
0
def main(script=None, modname=None):
    assert script and modname, 'Script "%s" or Modname "%s" is empty' % (
        script, modname)

    gopath = os.getenv('GOPATH', None)
    if not gopath:
        print >> sys.stderr, 'GOPATH not set'
        return 1

    with open(script) as py_file:
        py_contents = py_file.read()
    try:
        mod = pythonparser.parse(py_contents)
    except SyntaxError as e:
        print >> sys.stderr, '{}: line {}: invalid syntax: {}'.format(
            e.filename, e.lineno, e.text)
        return 2

    # Do a pass for compiler directives from `from __future__ import *` statements
    try:
        future_node, future_features = imputil.parse_future_features(mod)
    except util.CompileError as e:
        print >> sys.stderr, str(e)
        return 2

    importer = imputil.Importer(gopath, modname, script,
                                future_features.absolute_import)
    full_package_name = modname.replace('.', '/')
    mod_block = block.ModuleBlock(importer, full_package_name, script,
                                  py_contents, future_features)

    visitor = stmt.StatementVisitor(mod_block, future_node)
    # Indent so that the module body is aligned with the goto labels.
    with visitor.writer.indent_block():
        try:
            visitor.visit(mod)
        except util.ParseError as e:
            print >> sys.stderr, str(e)
            return 2

    writer = util.Writer(sys.stdout)
    tmpl = textwrap.dedent("""\
      package $package
      import πg "grumpy"
      var Code *πg.Code
      func init() {
      \tCode = πg.NewCode("<module>", $script, nil, 0, func(πF *πg.Frame, _ []*πg.Object) (*πg.Object, *πg.BaseException) {
      \t\tvar πR *πg.Object; _ = πR
      \t\tvar πE *πg.BaseException; _ = πE""")
    writer.write_tmpl(tmpl,
                      package=modname.split('.')[-1],
                      script=util.go_str(script))
    with writer.indent_block(2):
        for s in sorted(mod_block.strings):
            writer.write('ß{} := πg.InternStr({})'.format(s, util.go_str(s)))
        writer.write_temp_decls(mod_block)
        writer.write_block(mod_block, visitor.writer.getvalue())
    writer.write_tmpl(textwrap.dedent("""\
    \t\treturn nil, πE
    \t})
    \tπg.RegisterModule($modname, Code)
    }"""),
                      modname=util.go_str(modname))
    return 0