Commit e97a14ce authored by Dylan Trotter's avatar Dylan Trotter

Move some methods from Block -> ModuleBlock

Previously add_import(), add_native_import() and intern() were Block
methods that delegated to the root ModuleBlock internally. Now that the
ModuleBlock is accessible from any Block via the root attr, move those
methods to ModuleBlock.
parent 4672b492
......@@ -101,29 +101,6 @@ class Block(object):
"""
pass
def add_import(self, name):
"""Register the named Go package for import in this block's ModuleBlock.
add_import walks the block chain to the root ModuleBlock and adds a Package
to its imports dict.
Args:
name: The fully qualified Go package name.
Returns:
A Package representing the import.
"""
return self.add_native_import('__python__/' + name)
def add_native_import(self, name):
alias = None
if name == 'grumpy':
alias = 'πg'
if name in self.root.imports:
return self.root.imports[name]
package = Package(name, alias)
self.root.imports[name] = package
return package
def genlabel(self, is_checkpoint=False):
self.label_count += 1
if is_checkpoint:
......@@ -159,16 +136,10 @@ class Block(object):
def top_loop(self):
return self.loop_stack[-1]
def intern(self, s):
if len(s) > 64 or _non_word_re.search(s):
return 'πg.NewStr({})'.format(util.go_str(s))
self.root.strings.add(s)
return 'ß' + s
def _resolve_global(self, writer, name):
result = self.alloc_temp()
writer.write_checked_call2(
result, 'πg.ResolveGlobal(πF, {})', self.intern(name))
result, 'πg.ResolveGlobal(πF, {})', self.root.intern(name))
return result
......@@ -200,6 +171,32 @@ class ModuleBlock(Block):
def resolve_name(self, writer, name):
return self._resolve_global(writer, name)
def add_import(self, name):
"""Register the named Go package for import.
Args:
name: The fully qualified Go package name.
Returns:
A Package representing the import.
"""
return self.add_native_import('__python__/' + name)
def add_native_import(self, name):
alias = None
if name == 'grumpy':
alias = 'πg'
if name in self.imports:
return self.imports[name]
package = Package(name, alias)
self.imports[name] = package
return package
def intern(self, s):
if len(s) > 64 or _non_word_re.search(s):
return 'πg.NewStr({})'.format(util.go_str(s))
self.strings.add(s)
return 'ß' + s
class ClassBlock(Block):
"""Python block for a class definition."""
......@@ -212,12 +209,13 @@ class ClassBlock(Block):
if name in self.global_vars:
return self.root.bind_var(writer, name, value)
writer.write_checked_call1('πClass.SetItem(πF, {}.ToObject(), {})',
self.intern(name), value)
self.root.intern(name), value)
def del_var(self, writer, name):
if name in self.global_vars:
return self.root.del_var(writer, name)
writer.write_checked_call1('πg.DelVar(πF, πClass, {})', self.intern(name))
writer.write_checked_call1('πg.DelVar(πF, πClass, {})',
self.root.intern(name))
def resolve_name(self, writer, name):
local = 'nil'
......@@ -237,7 +235,7 @@ class ClassBlock(Block):
result = self.alloc_temp()
writer.write_checked_call2(
result, 'πg.ResolveClass(πF, πClass, {}, {})',
local, self.intern(name))
local, self.root.intern(name))
return result
......
......@@ -46,18 +46,18 @@ class BlockTest(unittest.TestCase):
module_block = _MakeModuleBlock()
func1_block = block.FunctionBlock(module_block, 'func1', {}, False)
func2_block = block.FunctionBlock(func1_block, 'func2', {}, False)
package = func2_block.add_import('foo/bar')
package = func2_block.root.add_import('foo/bar')
self.assertEqual(package.name, '__python__/foo/bar')
self.assertEqual(package.alias, 'π___python__ΓfooΓbar')
self.assertEqual(module_block.imports, {'__python__/foo/bar': package})
def testAddImportRepeated(self):
b = _MakeModuleBlock()
package = b.add_import('foo')
package = b.root.add_import('foo')
self.assertEqual(package.name, '__python__/foo')
self.assertEqual(package.alias, 'π___python__Γfoo')
self.assertEqual(b.imports, {'__python__/foo': package})
package2 = b.add_import('foo')
package2 = b.root.add_import('foo')
self.assertIs(package, package2)
self.assertEqual(b.imports, {'__python__/foo': package})
......
......@@ -47,7 +47,7 @@ class ExprVisitor(algorithm.Visitor):
attr = self.block.alloc_temp()
self.writer.write_checked_call2(
attr, 'πg.GetAttr(πF, {}, {}, nil)',
obj.expr, self.block.intern(node.attr))
obj.expr, self.block.root.intern(node.attr))
return attr
def visit_BinOp(self, node):
......@@ -336,7 +336,7 @@ class ExprVisitor(algorithm.Visitor):
expr_str = 'πg.NewUnicode({}).ToObject()'.format(
util.go_str(node.s.encode('utf-8')))
else:
expr_str = '{}.ToObject()'.format(self.block.intern(node.s))
expr_str = '{}.ToObject()'.format(self.block.root.intern(node.s))
return expr.GeneratedLiteral(expr_str)
def visit_Tuple(self, node):
......
......@@ -211,10 +211,10 @@ class StatementVisitor(algorithm.Visitor):
self.writer.write('{} = πg.NewDict()'.format(cls.name))
self.writer.write_checked_call2(
mod_name, 'πF.Globals().GetItem(πF, {}.ToObject())',
self.block.intern('__name__'))
self.block.root.intern('__name__'))
self.writer.write_checked_call1(
'{}.SetItem(πF, {}.ToObject(), {})',
cls.expr, self.block.intern('__module__'), mod_name.expr)
cls.expr, self.block.root.intern('__module__'), mod_name.expr)
tmpl = textwrap.dedent("""
_, πE = πg.NewCode($name, $filename, nil, 0, func(πF *πg.Frame, _ []*πg.Object) (*πg.Object, *πg.BaseException) {
\tπClass := $cls
......@@ -237,8 +237,9 @@ class StatementVisitor(algorithm.Visitor):
if $meta == nil {
\t$meta = πg.TypeType.ToObject()
}""")
self.writer.write_tmpl(tmpl, meta=meta.name, cls=cls.expr,
metaclass_str=self.block.intern('__metaclass__'))
self.writer.write_tmpl(
tmpl, meta=meta.name, cls=cls.expr,
metaclass_str=self.block.root.intern('__metaclass__'))
with self.block.alloc_temp() as type_:
type_expr = ('{}.Call(πF, []*πg.Object{{πg.NewStr({}).ToObject(), '
'πg.NewTuple({}...).ToObject(), {}.ToObject()}}, nil)')
......@@ -259,7 +260,8 @@ class StatementVisitor(algorithm.Visitor):
if isinstance(target, ast.Attribute):
with self.expr_visitor.visit(target.value) as t:
self.writer.write_checked_call1(
'πg.DelAttr(πF, {}, {})', t.expr, self.block.intern(target.attr))
'π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):
......@@ -401,7 +403,7 @@ class StatementVisitor(algorithm.Visitor):
with self.block.alloc_temp() as member:
self.writer.write_checked_call2(
member, 'πg.GetAttr(πF, {}, {}, nil)',
mod.expr, self.block.intern(name))
mod.expr, self.block.root.intern(name))
self.block.bind_var(
self.writer, alias.asname or alias.name, member.expr)
elif node.module == '__future__':
......@@ -598,11 +600,11 @@ class StatementVisitor(algorithm.Visitor):
# exit := type(mgr).__exit__
self.writer.write_checked_call2(
exit_func, 'πg.GetAttr(πF, {}.Type().ToObject(), {}, nil)',
mgr.expr, self.block.intern('__exit__'))
mgr.expr, self.block.root.intern('__exit__'))
# value := type(mgr).__enter__(mgr)
self.writer.write_checked_call2(
value, 'πg.GetAttr(πF, {}.Type().ToObject(), {}, nil)',
mgr.expr, self.block.intern('__enter__'))
mgr.expr, self.block.root.intern('__enter__'))
self.writer.write_checked_call2(
value, '{}.Call(πF, πg.Args{{{}}}, nil)',
value.expr, mgr.expr)
......@@ -657,7 +659,7 @@ class StatementVisitor(algorithm.Visitor):
with self.expr_visitor.visit(target.value) as obj:
self.writer.write_checked_call1(
'πg.SetAttr(πF, {}, {}, {})', obj.expr,
self.block.intern(target.attr), value)
self.block.root.intern(target.attr), value)
elif isinstance(target, ast.Subscript):
with self.expr_visitor.visit(target.value) as mapping,\
self.expr_visitor.visit(target.slice) as index:
......@@ -695,7 +697,7 @@ class StatementVisitor(algorithm.Visitor):
for i in xrange(len(parts)):
package_name = '/'.join(parts[:i + 1])
if package_name != self.block.root.full_package_name:
package = self.block.add_import(package_name)
package = self.block.root.add_import(package_name)
code_objs.append('{}.Code'.format(package.alias))
else:
code_objs.append('Code')
......@@ -709,7 +711,7 @@ class StatementVisitor(algorithm.Visitor):
return mod
def _import_native(self, name, values):
reflect_package = self.block.add_native_import('reflect')
reflect_package = self.block.root.add_native_import('reflect')
import_name = name[len(_NATIVE_MODULE_PREFIX):]
# Work-around for importing go module from VCS
# TODO: support bzr|git|hg|svn from any server
......@@ -721,7 +723,7 @@ class StatementVisitor(algorithm.Visitor):
if not package_name:
package_name = import_name.replace('.', '/')
package = self.block.add_native_import(package_name)
package = self.block.root.add_native_import(package_name)
mod = self.block.alloc_temp()
with self.block.alloc_temp('map[string]*πg.Object') as members:
self.writer.write_tmpl('$members = map[string]*πg.Object{}',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment