OILS / mycpp / ir_pass.py View on Github | oilshell.org

99 lines, 52 significant
1"""
2ir_pass.py - Translate (eventually) the mypy AST into our own IR.
3"""
4from typing import Dict
5
6import mypy
7from mypy.nodes import Expression, NameExpr
8from mypy.types import Type
9
10from mycpp.util import split_py_name
11from mycpp.visitor import SimpleVisitor, T
12from mycpp import util
13from mycpp import pass_state
14
15
16class UnsupportedException(Exception):
17 pass
18
19
20class Build(SimpleVisitor):
21
22 def __init__(self, types: Dict[Expression, Type]):
23
24 self.types = types
25 self.dot_exprs = {}
26
27 self.imported_names = set() # MemberExpr -> module::Foo() or self->foo
28 # HACK for conditional import inside mylib.PYTHON
29 # in core/shell.py
30 self.imported_names.add('help_meta')
31
32 # Statements
33
34 def visit_import(self, o: 'mypy.nodes.Import') -> T:
35 for name, as_name in o.ids:
36 if as_name is not None:
37 # import time as time_
38 self.imported_names.add(as_name)
39 else:
40 # import libc
41 self.imported_names.add(name)
42
43 def visit_import_from(self, o: 'mypy.nodes.ImportFrom') -> T:
44 """
45 Write C++ namespace aliases and 'using' for imports.
46 We need them in the 'decl' phase for default arguments like
47 runtime_asdl::scope_e -> scope_e
48 """
49 # For MemberExpr . -> module::func() or this->field. Also needed in
50 # the decl phase for default arg values.
51 for name, alias in o.names:
52 if alias:
53 self.imported_names.add(alias)
54 else:
55 self.imported_names.add(name)
56
57 # Expressions
58
59 def visit_member_expr(self, o: 'mypy.nodes.MemberExpr') -> T:
60 # Why do we not get some of the types? e.g. hnode.Record in asdl/runtime
61 # But this might suffice for the "Str_v" and "value_v" refactoring.
62 # We want to rewrite w.parts not to w->parts, but to w.parts() (method call)
63
64 is_small_str = False
65 if util.SMALL_STR:
66 lhs_type = self.types.get(o.expr)
67 if util.IsStr(lhs_type):
68 is_small_str = True
69 else:
70 #self.log('NOT a string %s %s', o.expr, o.name)
71 pass
72 """
73 if lhs_type is not None and isinstance(lhs_type, Instance):
74 self.log('lhs_type %s expr %s name %s',
75 lhs_type.type.fullname, o.expr, o.name)
76
77 """
78
79 is_asdl = o.name == 'CreateNull' # hack for MyType.CreateNull(alloc_lists=True)
80 is_module = (isinstance(o.expr, NameExpr) and
81 o.expr.name in self.imported_names)
82
83 # This is an approximate hack that assumes that locals don't shadow
84 # imported names. Might be a problem with names like 'word'?
85 if is_small_str:
86 self.dot_exprs[o] = pass_state.StackObjectMember(
87 o.expr, self.types[o.expr], o.name)
88 elif is_asdl:
89 self.dot_exprs[o] = pass_state.StaticObjectMember(
90 self.types[o].ret_type.type.fullname, o.name)
91 elif is_module:
92 self.dot_exprs[o] = pass_state.ModuleMember(
93 split_py_name(o.expr.fullname or o.expr.name), o.name)
94
95 else:
96 self.dot_exprs[o] = pass_state.HeapObjectMember(
97 o.expr, self.types[o.expr], o.name)
98
99 self.accept(o.expr)