kirin-toolchain 0.13.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- kirin/__init__.py +7 -0
- kirin/analysis/__init__.py +24 -0
- kirin/analysis/callgraph.py +61 -0
- kirin/analysis/cfg.py +112 -0
- kirin/analysis/const/__init__.py +20 -0
- kirin/analysis/const/_visitor.py +2 -0
- kirin/analysis/const/_visitor.pyi +8 -0
- kirin/analysis/const/lattice.py +219 -0
- kirin/analysis/const/prop.py +116 -0
- kirin/analysis/forward.py +100 -0
- kirin/analysis/typeinfer/__init__.py +5 -0
- kirin/analysis/typeinfer/analysis.py +90 -0
- kirin/analysis/typeinfer/solve.py +141 -0
- kirin/decl/__init__.py +108 -0
- kirin/decl/base.py +65 -0
- kirin/decl/camel2snake.py +2 -0
- kirin/decl/emit/__init__.py +0 -0
- kirin/decl/emit/_create_fn.py +29 -0
- kirin/decl/emit/_set_new_attribute.py +22 -0
- kirin/decl/emit/dialect.py +8 -0
- kirin/decl/emit/init.py +277 -0
- kirin/decl/emit/name.py +10 -0
- kirin/decl/emit/property.py +182 -0
- kirin/decl/emit/repr.py +31 -0
- kirin/decl/emit/traits.py +13 -0
- kirin/decl/emit/typecheck.py +77 -0
- kirin/decl/emit/verify.py +51 -0
- kirin/decl/info.py +346 -0
- kirin/decl/scan_fields.py +157 -0
- kirin/decl/verify.py +69 -0
- kirin/dialects/__init__.py +14 -0
- kirin/dialects/_pprint_helper.py +53 -0
- kirin/dialects/cf/__init__.py +20 -0
- kirin/dialects/cf/constprop.py +51 -0
- kirin/dialects/cf/dialect.py +3 -0
- kirin/dialects/cf/emit.py +58 -0
- kirin/dialects/cf/interp.py +24 -0
- kirin/dialects/cf/stmts.py +68 -0
- kirin/dialects/cf/typeinfer.py +27 -0
- kirin/dialects/eltype.py +23 -0
- kirin/dialects/func/__init__.py +20 -0
- kirin/dialects/func/attrs.py +39 -0
- kirin/dialects/func/constprop.py +138 -0
- kirin/dialects/func/dialect.py +3 -0
- kirin/dialects/func/emit.py +80 -0
- kirin/dialects/func/interp.py +68 -0
- kirin/dialects/func/stmts.py +233 -0
- kirin/dialects/func/typeinfer.py +124 -0
- kirin/dialects/ilist/__init__.py +33 -0
- kirin/dialects/ilist/_dialect.py +3 -0
- kirin/dialects/ilist/_wrapper.py +51 -0
- kirin/dialects/ilist/interp.py +85 -0
- kirin/dialects/ilist/lowering.py +25 -0
- kirin/dialects/ilist/passes.py +32 -0
- kirin/dialects/ilist/rewrite/__init__.py +3 -0
- kirin/dialects/ilist/rewrite/const.py +45 -0
- kirin/dialects/ilist/rewrite/list.py +38 -0
- kirin/dialects/ilist/rewrite/unroll.py +131 -0
- kirin/dialects/ilist/runtime.py +63 -0
- kirin/dialects/ilist/stmts.py +102 -0
- kirin/dialects/ilist/typeinfer.py +120 -0
- kirin/dialects/lowering/__init__.py +7 -0
- kirin/dialects/lowering/call.py +48 -0
- kirin/dialects/lowering/cf.py +206 -0
- kirin/dialects/lowering/func.py +134 -0
- kirin/dialects/math/__init__.py +41 -0
- kirin/dialects/math/_gen.py +176 -0
- kirin/dialects/math/dialect.py +3 -0
- kirin/dialects/math/interp.py +190 -0
- kirin/dialects/math/stmts.py +369 -0
- kirin/dialects/module.py +139 -0
- kirin/dialects/py/__init__.py +40 -0
- kirin/dialects/py/assertion.py +91 -0
- kirin/dialects/py/assign.py +103 -0
- kirin/dialects/py/attr.py +59 -0
- kirin/dialects/py/base.py +34 -0
- kirin/dialects/py/binop/__init__.py +23 -0
- kirin/dialects/py/binop/_dialect.py +3 -0
- kirin/dialects/py/binop/interp.py +60 -0
- kirin/dialects/py/binop/julia.py +33 -0
- kirin/dialects/py/binop/lowering.py +22 -0
- kirin/dialects/py/binop/stmts.py +79 -0
- kirin/dialects/py/binop/typeinfer.py +108 -0
- kirin/dialects/py/boolop.py +84 -0
- kirin/dialects/py/builtin.py +78 -0
- kirin/dialects/py/cmp/__init__.py +16 -0
- kirin/dialects/py/cmp/_dialect.py +3 -0
- kirin/dialects/py/cmp/interp.py +48 -0
- kirin/dialects/py/cmp/julia.py +33 -0
- kirin/dialects/py/cmp/lowering.py +45 -0
- kirin/dialects/py/cmp/stmts.py +62 -0
- kirin/dialects/py/constant.py +79 -0
- kirin/dialects/py/indexing.py +251 -0
- kirin/dialects/py/iterable.py +90 -0
- kirin/dialects/py/len.py +57 -0
- kirin/dialects/py/list/__init__.py +15 -0
- kirin/dialects/py/list/_dialect.py +3 -0
- kirin/dialects/py/list/interp.py +21 -0
- kirin/dialects/py/list/lowering.py +25 -0
- kirin/dialects/py/list/stmts.py +22 -0
- kirin/dialects/py/list/typeinfer.py +54 -0
- kirin/dialects/py/range.py +76 -0
- kirin/dialects/py/slice.py +120 -0
- kirin/dialects/py/tuple.py +109 -0
- kirin/dialects/py/unary/__init__.py +24 -0
- kirin/dialects/py/unary/_dialect.py +3 -0
- kirin/dialects/py/unary/constprop.py +20 -0
- kirin/dialects/py/unary/interp.py +24 -0
- kirin/dialects/py/unary/julia.py +21 -0
- kirin/dialects/py/unary/lowering.py +22 -0
- kirin/dialects/py/unary/stmts.py +33 -0
- kirin/dialects/py/unary/typeinfer.py +23 -0
- kirin/dialects/py/unpack.py +90 -0
- kirin/dialects/scf/__init__.py +23 -0
- kirin/dialects/scf/_dialect.py +3 -0
- kirin/dialects/scf/absint.py +64 -0
- kirin/dialects/scf/constprop.py +140 -0
- kirin/dialects/scf/interp.py +35 -0
- kirin/dialects/scf/lowering.py +123 -0
- kirin/dialects/scf/stmts.py +250 -0
- kirin/dialects/scf/trim.py +36 -0
- kirin/dialects/scf/typeinfer.py +58 -0
- kirin/dialects/scf/unroll.py +92 -0
- kirin/emit/__init__.py +3 -0
- kirin/emit/abc.py +89 -0
- kirin/emit/abc.pyi +38 -0
- kirin/emit/exceptions.py +5 -0
- kirin/emit/julia.py +63 -0
- kirin/emit/str.py +51 -0
- kirin/exceptions.py +59 -0
- kirin/graph.py +34 -0
- kirin/idtable.py +57 -0
- kirin/interp/__init__.py +39 -0
- kirin/interp/abstract.py +253 -0
- kirin/interp/base.py +438 -0
- kirin/interp/concrete.py +62 -0
- kirin/interp/exceptions.py +26 -0
- kirin/interp/frame.py +151 -0
- kirin/interp/impl.py +197 -0
- kirin/interp/result.py +93 -0
- kirin/interp/state.py +71 -0
- kirin/interp/table.py +40 -0
- kirin/interp/value.py +73 -0
- kirin/ir/__init__.py +46 -0
- kirin/ir/attrs/__init__.py +20 -0
- kirin/ir/attrs/_types.py +8 -0
- kirin/ir/attrs/_types.pyi +13 -0
- kirin/ir/attrs/abc.py +46 -0
- kirin/ir/attrs/py.py +45 -0
- kirin/ir/attrs/types.py +522 -0
- kirin/ir/dialect.py +125 -0
- kirin/ir/group.py +249 -0
- kirin/ir/method.py +118 -0
- kirin/ir/nodes/__init__.py +7 -0
- kirin/ir/nodes/base.py +149 -0
- kirin/ir/nodes/block.py +458 -0
- kirin/ir/nodes/region.py +337 -0
- kirin/ir/nodes/stmt.py +713 -0
- kirin/ir/nodes/view.py +142 -0
- kirin/ir/ssa.py +204 -0
- kirin/ir/traits/__init__.py +36 -0
- kirin/ir/traits/abc.py +42 -0
- kirin/ir/traits/basic.py +78 -0
- kirin/ir/traits/callable.py +51 -0
- kirin/ir/traits/lowering/__init__.py +2 -0
- kirin/ir/traits/lowering/call.py +37 -0
- kirin/ir/traits/lowering/context.py +120 -0
- kirin/ir/traits/region/__init__.py +2 -0
- kirin/ir/traits/region/ssacfg.py +22 -0
- kirin/ir/traits/symbol.py +57 -0
- kirin/ir/use.py +17 -0
- kirin/lattice/__init__.py +13 -0
- kirin/lattice/abc.py +128 -0
- kirin/lattice/empty.py +25 -0
- kirin/lattice/mixin.py +51 -0
- kirin/lowering/__init__.py +7 -0
- kirin/lowering/binding.py +65 -0
- kirin/lowering/core.py +72 -0
- kirin/lowering/dialect.py +35 -0
- kirin/lowering/dialect.pyi +183 -0
- kirin/lowering/frame.py +171 -0
- kirin/lowering/result.py +68 -0
- kirin/lowering/state.py +441 -0
- kirin/lowering/stream.py +53 -0
- kirin/passes/__init__.py +3 -0
- kirin/passes/abc.py +44 -0
- kirin/passes/aggressive/__init__.py +1 -0
- kirin/passes/aggressive/fold.py +43 -0
- kirin/passes/fold.py +45 -0
- kirin/passes/inline.py +25 -0
- kirin/passes/typeinfer.py +25 -0
- kirin/prelude.py +197 -0
- kirin/print/__init__.py +15 -0
- kirin/print/printable.py +141 -0
- kirin/print/printer.py +415 -0
- kirin/py.typed +0 -0
- kirin/registry.py +105 -0
- kirin/registry.pyi +52 -0
- kirin/rewrite/__init__.py +14 -0
- kirin/rewrite/abc.py +43 -0
- kirin/rewrite/aggressive/__init__.py +1 -0
- kirin/rewrite/aggressive/fold.py +43 -0
- kirin/rewrite/alias.py +16 -0
- kirin/rewrite/apply_type.py +47 -0
- kirin/rewrite/call2invoke.py +34 -0
- kirin/rewrite/chain.py +39 -0
- kirin/rewrite/compactify.py +288 -0
- kirin/rewrite/cse.py +48 -0
- kirin/rewrite/dce.py +19 -0
- kirin/rewrite/fixpoint.py +34 -0
- kirin/rewrite/fold.py +57 -0
- kirin/rewrite/getfield.py +21 -0
- kirin/rewrite/getitem.py +37 -0
- kirin/rewrite/inline.py +143 -0
- kirin/rewrite/result.py +15 -0
- kirin/rewrite/walk.py +83 -0
- kirin/rewrite/wrap_const.py +55 -0
- kirin/source.py +21 -0
- kirin/symbol_table.py +27 -0
- kirin/types.py +34 -0
- kirin/worklist.py +30 -0
- kirin_toolchain-0.13.0.dist-info/METADATA +42 -0
- kirin_toolchain-0.13.0.dist-info/RECORD +225 -0
- kirin_toolchain-0.13.0.dist-info/WHEEL +4 -0
- kirin_toolchain-0.13.0.dist-info/licenses/LICENSE +234 -0
kirin/decl/emit/init.py
ADDED
@@ -0,0 +1,277 @@
|
|
1
|
+
from typing import Any
|
2
|
+
from dataclasses import MISSING
|
3
|
+
|
4
|
+
from typing_extensions import Unpack
|
5
|
+
|
6
|
+
from kirin import ir, types
|
7
|
+
from kirin.decl import info
|
8
|
+
from kirin.decl.base import BaseModifier, StatementOptions
|
9
|
+
|
10
|
+
from ._create_fn import create_fn
|
11
|
+
from ._set_new_attribute import set_new_attribute
|
12
|
+
|
13
|
+
|
14
|
+
class _HAS_DEFAULT_FACTORY_CLASS:
|
15
|
+
def __repr__(self):
|
16
|
+
return "<factory>"
|
17
|
+
|
18
|
+
|
19
|
+
_HAS_DEFAULT_FACTORY = _HAS_DEFAULT_FACTORY_CLASS()
|
20
|
+
|
21
|
+
|
22
|
+
class EmitInit(BaseModifier):
|
23
|
+
_POST_INIT_NAME = "__post_init__"
|
24
|
+
_RESULT_VALUE_NAME = "_kirin_ResultValue"
|
25
|
+
_KIRIN_PYATTR = "_kirin_PyAttr"
|
26
|
+
_ATTR_FACTORY_PREFIX = "_kirin_attr_factory_"
|
27
|
+
_SELF_CLASS = "_kirin_self_class"
|
28
|
+
_KIRIN_STMT = "_kirin_Statement"
|
29
|
+
|
30
|
+
def __init__(self, cls: type, **kwargs: Unpack[StatementOptions]) -> None:
|
31
|
+
super().__init__(cls, **kwargs)
|
32
|
+
from kirin.ir.attrs.py import PyAttr
|
33
|
+
|
34
|
+
self._init_params: list[str] = []
|
35
|
+
self._init_body: list[str] = []
|
36
|
+
self._init_locals: dict[str, Any] = {}
|
37
|
+
self.has_post_init = hasattr(self.cls, self._POST_INIT_NAME)
|
38
|
+
self.globals.update(
|
39
|
+
{
|
40
|
+
"_PY_ANY": types.Any,
|
41
|
+
self._KIRIN_STMT: ir.Statement,
|
42
|
+
self._SELF_CLASS: self.cls,
|
43
|
+
self._RESULT_VALUE_NAME: ir.ResultValue,
|
44
|
+
self._KIRIN_PYATTR: PyAttr,
|
45
|
+
}
|
46
|
+
)
|
47
|
+
|
48
|
+
@classmethod
|
49
|
+
def _hint_name(cls, f: info.Field):
|
50
|
+
return f"_hint_{f.name}"
|
51
|
+
|
52
|
+
def emit_init(self):
|
53
|
+
_args_groups = []
|
54
|
+
for f in self.fields.args.values():
|
55
|
+
if f.group:
|
56
|
+
_args_groups.append(f.name)
|
57
|
+
setattr(self.cls, "_arg_groups", frozenset(_args_groups))
|
58
|
+
|
59
|
+
if "__init__" in self.cls.__dict__:
|
60
|
+
return True
|
61
|
+
|
62
|
+
self._init_locals.update(
|
63
|
+
{self._hint_name(f): f.annotation for f in self.fields}
|
64
|
+
)
|
65
|
+
self._init_locals.update(
|
66
|
+
{
|
67
|
+
"MISSING": MISSING,
|
68
|
+
"_HAS_DEFAULT_FACTORY": _HAS_DEFAULT_FACTORY,
|
69
|
+
}
|
70
|
+
)
|
71
|
+
|
72
|
+
self._emit_params()
|
73
|
+
self._emit_field_init(len(_args_groups) > 0)
|
74
|
+
|
75
|
+
fn = create_fn(
|
76
|
+
"__init__",
|
77
|
+
self._init_params,
|
78
|
+
self._init_body,
|
79
|
+
globals=self.globals,
|
80
|
+
locals=self._init_locals,
|
81
|
+
return_type=None,
|
82
|
+
)
|
83
|
+
set_new_attribute(self.cls, "__init__", fn)
|
84
|
+
|
85
|
+
def _emit_params(self):
|
86
|
+
self._init_params.append(self._self_name)
|
87
|
+
for f in self.fields.std_args.values():
|
88
|
+
self._init_params.append(self._init_param_value(f))
|
89
|
+
|
90
|
+
kw_params: list[str] = []
|
91
|
+
for f in self.fields.kw_args.values():
|
92
|
+
kw_params.append(self._init_param_value(f))
|
93
|
+
|
94
|
+
for f in self.fields.attributes.values():
|
95
|
+
if f.init:
|
96
|
+
kw_params.append(self._init_param_value(f))
|
97
|
+
|
98
|
+
for f in self.fields.regions.values():
|
99
|
+
if f.init:
|
100
|
+
kw_params.append(self._init_param_value(f))
|
101
|
+
|
102
|
+
for f in self.fields.blocks.values():
|
103
|
+
if f.init:
|
104
|
+
kw_params.append(self._init_param_value(f))
|
105
|
+
|
106
|
+
if kw_params:
|
107
|
+
self._init_params.append("*")
|
108
|
+
self._init_params.extend(kw_params)
|
109
|
+
|
110
|
+
def _emit_field_init(self, has_args_groups: bool):
|
111
|
+
self._init_body.append(
|
112
|
+
(
|
113
|
+
f"{self._KIRIN_STMT}.__init__({self._self_name},"
|
114
|
+
f"args={self._arg_seq()},"
|
115
|
+
f"regions={self._regions_seq()},"
|
116
|
+
f"successors={self._blocks_seq()},"
|
117
|
+
f"result_types={self._result_types_seq()},"
|
118
|
+
f"attributes={self._attribute_seq()},"
|
119
|
+
f"args_slice={self._args_slice(has_args_groups)}"
|
120
|
+
")"
|
121
|
+
)
|
122
|
+
)
|
123
|
+
|
124
|
+
# TODO: support InitVar?
|
125
|
+
if self.has_post_init:
|
126
|
+
self._init_body.append(f"{self._self_name}.{self._POST_INIT_NAME}()")
|
127
|
+
|
128
|
+
def _init_param_value(self, f: info.Field):
|
129
|
+
if isinstance(f, info.AttributeField): # only attribute can have defaults
|
130
|
+
if f.default is MISSING and f.default_factory is None:
|
131
|
+
default = ""
|
132
|
+
elif f.default is not MISSING:
|
133
|
+
default = f"={self._ATTR_FACTORY_PREFIX}{f.name}"
|
134
|
+
elif f.default_factory is not None:
|
135
|
+
default = "=_HAS_DEFAULT_FACTORY"
|
136
|
+
else:
|
137
|
+
raise ValueError("unexpected default")
|
138
|
+
return f"{f.name}:{self._hint_name(f)}{default}"
|
139
|
+
elif isinstance(f, info.ArgumentField): # arguments are always required
|
140
|
+
return f"{f.name}:{self._hint_name(f)}"
|
141
|
+
elif isinstance(f, info.ResultField):
|
142
|
+
raise ValueError("result fields are not allowed in __init__")
|
143
|
+
elif isinstance(f, info.RegionField):
|
144
|
+
return f"{f.name}:{self._hint_name(f)}=_HAS_DEFAULT_FACTORY"
|
145
|
+
elif isinstance(f, info.BlockField):
|
146
|
+
return f"{f.name}:{self._hint_name(f)}=_HAS_DEFAULT_FACTORY"
|
147
|
+
else: # the rest fields are all required
|
148
|
+
raise ValueError(f"unexpected field type {type(f)}")
|
149
|
+
|
150
|
+
def _arg_seq(self):
|
151
|
+
args: list[str] = [self._field_param(f) for f in self.fields.args.values()]
|
152
|
+
return self._tuple_str(args)
|
153
|
+
|
154
|
+
def _field_param(self, f: info.ArgumentField):
|
155
|
+
if f.group:
|
156
|
+
return f"*{f.name}"
|
157
|
+
else:
|
158
|
+
return f"{f.name}"
|
159
|
+
|
160
|
+
def _result_types_seq(self):
|
161
|
+
result_types = [
|
162
|
+
self._result_type_value(f) for f in self.fields.results.values()
|
163
|
+
]
|
164
|
+
return self._tuple_str(result_types)
|
165
|
+
|
166
|
+
def _result_type_value(self, f: info.ResultField):
|
167
|
+
name = f"_result_type_{f.name}"
|
168
|
+
self._init_locals[name] = f.type
|
169
|
+
return name
|
170
|
+
|
171
|
+
def _attribute_seq(self):
|
172
|
+
attrs = ",".join(
|
173
|
+
[
|
174
|
+
f'"{name}": {self._attribute_value(f)}'
|
175
|
+
for name, f in self.fields.attributes.items()
|
176
|
+
]
|
177
|
+
)
|
178
|
+
return "{" + attrs + "}"
|
179
|
+
|
180
|
+
def _attribute_value(self, f: info.AttributeField):
|
181
|
+
default_name = f"{self._ATTR_FACTORY_PREFIX}{f.name}"
|
182
|
+
if f.default_factory is not None:
|
183
|
+
value = self._field_with_default_factory(
|
184
|
+
default_name, f.name, f.init, f.default_factory
|
185
|
+
)
|
186
|
+
else:
|
187
|
+
# no default factory
|
188
|
+
if f.init:
|
189
|
+
if f.default is not MISSING:
|
190
|
+
self._init_locals[default_name] = f.default
|
191
|
+
value: str = f.name # type: ignore
|
192
|
+
else: # no default factory, no init, no default
|
193
|
+
raise ValueError(
|
194
|
+
"attribute must have a default or default factory or be initialized (init=True)"
|
195
|
+
)
|
196
|
+
|
197
|
+
# declared via python type, optionally check if we can
|
198
|
+
# convert the value to data.PyAttr
|
199
|
+
if f.pytype:
|
200
|
+
attr_type = f"_kirin_attr_type_{f.name}"
|
201
|
+
self._init_locals[attr_type] = f.type
|
202
|
+
value = (
|
203
|
+
f"{self._KIRIN_PYATTR}({value}, {attr_type}) "
|
204
|
+
f"if not isinstance({value}, {self._KIRIN_PYATTR}) "
|
205
|
+
f"else {value}"
|
206
|
+
)
|
207
|
+
|
208
|
+
return value
|
209
|
+
|
210
|
+
def _regions_seq(self):
|
211
|
+
regions = [self._regions_value(f) for f in self.fields.regions.values()]
|
212
|
+
return self._tuple_str(regions)
|
213
|
+
|
214
|
+
def _regions_value(self, f: info.RegionField):
|
215
|
+
return self._field_with_default_factory(
|
216
|
+
f"_kirin_region_{f.name}", f.name, f.init, f.default_factory
|
217
|
+
)
|
218
|
+
|
219
|
+
def _blocks_seq(self):
|
220
|
+
blocks = [self._blocks_value(f) for f in self.fields.blocks.values()]
|
221
|
+
return self._tuple_str(blocks)
|
222
|
+
|
223
|
+
def _blocks_value(self, f: info.BlockField):
|
224
|
+
return self._field_with_default_factory(
|
225
|
+
f"_kirin_block_{f.name}", f.name, f.init, f.default_factory
|
226
|
+
)
|
227
|
+
|
228
|
+
def _args_slice(self, has_args_groups: bool):
|
229
|
+
if not has_args_groups:
|
230
|
+
return (
|
231
|
+
"{"
|
232
|
+
+ ", ".join(
|
233
|
+
[
|
234
|
+
f"'{f.name}': {index}"
|
235
|
+
for index, f in enumerate(self.fields.args.values())
|
236
|
+
]
|
237
|
+
)
|
238
|
+
+ "}"
|
239
|
+
)
|
240
|
+
|
241
|
+
# NOTE: SSAValue fields do not have default/default_factory
|
242
|
+
# so we can just count the input arguments
|
243
|
+
ret: list[str] = []
|
244
|
+
self._init_body.append("__args_slice_count = 0")
|
245
|
+
for f in self.fields.args.values():
|
246
|
+
if f.group:
|
247
|
+
self._init_body.append(
|
248
|
+
f"__{f.name}_slice = slice(__args_slice_count, __args_slice_count + len({f.name}))"
|
249
|
+
)
|
250
|
+
self._init_body.append(f"__args_slice_count += len({f.name})")
|
251
|
+
else:
|
252
|
+
self._init_body.append(f"__{f.name}_slice = __args_slice_count")
|
253
|
+
self._init_body.append("__args_slice_count += 1")
|
254
|
+
ret.append(f'"{f.name}": __{f.name}_slice')
|
255
|
+
return "{" + ",".join(ret) + "}"
|
256
|
+
|
257
|
+
def _field_with_default_factory(
|
258
|
+
self, factory_name: str, name: str | None, init: bool, default_factory
|
259
|
+
):
|
260
|
+
# block always has default_factory
|
261
|
+
if init:
|
262
|
+
self._init_locals[factory_name] = default_factory
|
263
|
+
value = (
|
264
|
+
f"{factory_name}() "
|
265
|
+
f"if {name} is _HAS_DEFAULT_FACTORY "
|
266
|
+
f"else {name}"
|
267
|
+
)
|
268
|
+
else:
|
269
|
+
self._init_locals[factory_name] = default_factory
|
270
|
+
value = f"{factory_name}()"
|
271
|
+
return value
|
272
|
+
|
273
|
+
@staticmethod
|
274
|
+
def _tuple_str(seq: list[str]):
|
275
|
+
if not seq:
|
276
|
+
return "()"
|
277
|
+
return f"({', '.join(seq)}, )"
|
kirin/decl/emit/name.py
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
from kirin.decl.base import BaseModifier
|
2
|
+
from kirin.decl.camel2snake import camel2snake
|
3
|
+
|
4
|
+
from ._set_new_attribute import set_new_attribute
|
5
|
+
|
6
|
+
|
7
|
+
class EmitName(BaseModifier):
|
8
|
+
|
9
|
+
def emit_name(self):
|
10
|
+
set_new_attribute(self.cls, "name", camel2snake(self.cls.__name__))
|
@@ -0,0 +1,182 @@
|
|
1
|
+
from kirin import ir
|
2
|
+
from kirin.decl import info
|
3
|
+
from kirin.decl.emit.init import BaseModifier
|
4
|
+
|
5
|
+
from ._create_fn import create_fn
|
6
|
+
from ._set_new_attribute import set_new_attribute
|
7
|
+
|
8
|
+
|
9
|
+
class EmitProperty(BaseModifier):
|
10
|
+
_KIRIN_PYATTR = "_kirin_PyAttr"
|
11
|
+
|
12
|
+
def emit_property(self):
|
13
|
+
for name, f in self.fields.args.items():
|
14
|
+
getter, setter = self._emit_arg_property(f)
|
15
|
+
set_new_attribute(self.cls, name, property(getter, setter))
|
16
|
+
|
17
|
+
for name, f in self.fields.kw_args.items():
|
18
|
+
getter, setter = self._emit_arg_property(f)
|
19
|
+
set_new_attribute(self.cls, name, property(getter, setter))
|
20
|
+
|
21
|
+
for i, (name, f) in enumerate(self.fields.results.items()):
|
22
|
+
getter, setter = self._emit_result_property(i, f)
|
23
|
+
set_new_attribute(self.cls, name, property(getter, setter))
|
24
|
+
|
25
|
+
for name, f in self.fields.attributes.items():
|
26
|
+
getter, setter = self._emit_attribute_property(f)
|
27
|
+
set_new_attribute(self.cls, name, property(getter, setter))
|
28
|
+
|
29
|
+
for i, (name, f) in enumerate(self.fields.blocks.items()):
|
30
|
+
getter, setter = self._emit_successor_property(i, f)
|
31
|
+
set_new_attribute(self.cls, name, property(getter, setter))
|
32
|
+
|
33
|
+
for i, (name, f) in enumerate(self.fields.regions.items()):
|
34
|
+
getter, setter = self._emit_region_property(i, f)
|
35
|
+
set_new_attribute(self.cls, name, property(getter, setter))
|
36
|
+
|
37
|
+
def _emit_arg_property(self, f: info.ArgumentField):
|
38
|
+
getter = create_fn(
|
39
|
+
f"_get_{f.name}",
|
40
|
+
args=[self._self_name],
|
41
|
+
body=[
|
42
|
+
f'return {self._self_name}._args[{self._self_name}._name_args_slice["{f.name}"]]'
|
43
|
+
],
|
44
|
+
globals=self.globals,
|
45
|
+
return_type=tuple[ir.SSAValue, ...] if f.group else ir.SSAValue,
|
46
|
+
)
|
47
|
+
|
48
|
+
if f.group:
|
49
|
+
return getter, self._emit_arg_property_group_setter(f)
|
50
|
+
return getter, self._emit_arg_property_std_setter(f)
|
51
|
+
|
52
|
+
def _emit_arg_property_std_setter(self, f: info.ArgumentField):
|
53
|
+
return create_fn(
|
54
|
+
f"_set_{f.name}",
|
55
|
+
args=[self._self_name, "value: _value_hint"],
|
56
|
+
body=[
|
57
|
+
f"s = {self._self_name}._name_args_slice['{f.name}']",
|
58
|
+
f"old = {self._self_name}.args[s]",
|
59
|
+
f"old.remove_use(Use({self._self_name}, s))",
|
60
|
+
f"value.add_use(Use({self._self_name}, s))",
|
61
|
+
"self.args = (*self.args[:s], value, *self.args[s + 1:])",
|
62
|
+
],
|
63
|
+
globals=self.globals,
|
64
|
+
locals={"_value_hint": ir.SSAValue},
|
65
|
+
return_type=None,
|
66
|
+
)
|
67
|
+
|
68
|
+
def _emit_arg_property_group_setter(self, f: info.ArgumentField):
|
69
|
+
return create_fn(
|
70
|
+
f"_set_{f.name}",
|
71
|
+
args=[self._self_name, "value: _value_hint"],
|
72
|
+
body=[
|
73
|
+
f"s = {self._self_name}._name_args_slice['{f.name}']",
|
74
|
+
"start, stop = s.start, s.stop",
|
75
|
+
f"old = {self._self_name}.args[s]",
|
76
|
+
"a_range = range(start, stop, s.step or 1)",
|
77
|
+
"for i, arg in zip(a_range, old):",
|
78
|
+
f" arg.remove_use(Use({self._self_name}, i))",
|
79
|
+
"for i, arg in zip(a_range, value):",
|
80
|
+
f" arg.add_use(Use({self._self_name}, i))",
|
81
|
+
f"{self._self_name}.args = (*{self._self_name}.args[:start], *value, *{self._self_name}.args[stop + 1:])",
|
82
|
+
],
|
83
|
+
globals=self.globals,
|
84
|
+
locals={"_value_hint": tuple[ir.SSAValue, ...]},
|
85
|
+
return_type=None,
|
86
|
+
)
|
87
|
+
|
88
|
+
def _emit_result_property(self, index: int, f: info.ResultField):
|
89
|
+
getter = create_fn(
|
90
|
+
f"_get_{f.name}",
|
91
|
+
args=[self._self_name],
|
92
|
+
body=[f"return {self._self_name}._results[{index}]"],
|
93
|
+
globals=self.globals,
|
94
|
+
return_type=ir.ResultValue,
|
95
|
+
)
|
96
|
+
|
97
|
+
# well you cannot delete what already happened, can you?
|
98
|
+
setter = create_fn(
|
99
|
+
f"_set_{f.name}",
|
100
|
+
args=[self._self_name, "value: _value_hint"],
|
101
|
+
body=[f"raise AttributeError('result property {f.name} is read-only')"],
|
102
|
+
globals=self.globals,
|
103
|
+
locals={"_value_hint": ir.ResultValue},
|
104
|
+
return_type=None,
|
105
|
+
)
|
106
|
+
|
107
|
+
return getter, setter
|
108
|
+
|
109
|
+
def _emit_attribute_property(self, f: info.AttributeField):
|
110
|
+
from kirin.ir.attrs.py import PyAttr
|
111
|
+
|
112
|
+
storage = "attributes"
|
113
|
+
attr = f"{self._self_name}.{storage}['{f.name}']"
|
114
|
+
getter = create_fn(
|
115
|
+
f"_get_{f.name}",
|
116
|
+
args=[self._self_name],
|
117
|
+
body=[f"return {attr}.data" if f.pytype else f"return {attr}"],
|
118
|
+
globals=self.globals,
|
119
|
+
return_type=f.annotation,
|
120
|
+
)
|
121
|
+
|
122
|
+
setter = create_fn(
|
123
|
+
f"_set_{f.name}",
|
124
|
+
args=[self._self_name, "value: _value_hint"],
|
125
|
+
body=[
|
126
|
+
(
|
127
|
+
f"{attr} = value if isinstance(value, {self._KIRIN_PYATTR}) else {self._KIRIN_PYATTR}(value)"
|
128
|
+
if f.pytype
|
129
|
+
else f"{attr} = value"
|
130
|
+
)
|
131
|
+
],
|
132
|
+
globals=self.globals,
|
133
|
+
locals={"_value_hint": PyAttr if f.pytype else f.annotation},
|
134
|
+
return_type=None,
|
135
|
+
)
|
136
|
+
|
137
|
+
return getter, setter
|
138
|
+
|
139
|
+
def _emit_successor_property(self, index: int, f: info.BlockField):
|
140
|
+
getter = create_fn(
|
141
|
+
f"_get_{f.name}",
|
142
|
+
args=[self._self_name],
|
143
|
+
body=[f"return {self._self_name}.successors[{index}]"],
|
144
|
+
globals=self.globals,
|
145
|
+
return_type=ir.Block,
|
146
|
+
)
|
147
|
+
|
148
|
+
setter = create_fn(
|
149
|
+
f"_set_{f.name}",
|
150
|
+
args=[self._self_name, "value: _value_hint"],
|
151
|
+
body=[f"{self._self_name}.successors[{index}] = value"],
|
152
|
+
globals=self.globals,
|
153
|
+
locals={"_value_hint": ir.Block},
|
154
|
+
return_type=None,
|
155
|
+
)
|
156
|
+
|
157
|
+
return getter, setter
|
158
|
+
|
159
|
+
def _emit_region_property(self, index: int, f: info.RegionField):
|
160
|
+
getter = create_fn(
|
161
|
+
f"_get_{f.name}",
|
162
|
+
args=[self._self_name],
|
163
|
+
body=[f"return {self._self_name}.regions[{index}]"],
|
164
|
+
globals=self.globals,
|
165
|
+
return_type=ir.Region,
|
166
|
+
)
|
167
|
+
|
168
|
+
setter = create_fn(
|
169
|
+
f"_set_{f.name}",
|
170
|
+
args=[self._self_name, "value: _value_hint"],
|
171
|
+
body=[
|
172
|
+
f"old = {self._self_name}.regions[{index}]",
|
173
|
+
"old.parent = None",
|
174
|
+
f"value.parent = {self._self_name}",
|
175
|
+
f"{self._self_name}.regions[{index}] = value",
|
176
|
+
],
|
177
|
+
globals=self.globals,
|
178
|
+
locals={"_value_hint": ir.Region},
|
179
|
+
return_type=None,
|
180
|
+
)
|
181
|
+
|
182
|
+
return getter, setter
|
kirin/decl/emit/repr.py
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
from kirin.decl.base import BaseModifier
|
2
|
+
|
3
|
+
from ._create_fn import create_fn
|
4
|
+
from ._set_new_attribute import set_new_attribute
|
5
|
+
|
6
|
+
|
7
|
+
class EmitRepr(BaseModifier):
|
8
|
+
|
9
|
+
def emit_repr(self):
|
10
|
+
if "repr" not in self.params or not self.params["repr"]:
|
11
|
+
return
|
12
|
+
|
13
|
+
body = [f'ret = "{self.cls.__name__}("']
|
14
|
+
for idx, field in enumerate(self.fields):
|
15
|
+
if idx > 0:
|
16
|
+
body.append('ret += ", "')
|
17
|
+
body.append(f'ret += f"{field.name}={{{self._self_name}.{field.name}}}"')
|
18
|
+
body.append('ret += ")"')
|
19
|
+
body.append("return ret")
|
20
|
+
|
21
|
+
set_new_attribute(
|
22
|
+
self.cls,
|
23
|
+
"__repr__",
|
24
|
+
create_fn(
|
25
|
+
"__repr__",
|
26
|
+
args=[self._self_name],
|
27
|
+
body=body,
|
28
|
+
globals=self.globals,
|
29
|
+
return_type=str,
|
30
|
+
),
|
31
|
+
)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from kirin.decl.base import BaseModifier
|
2
|
+
|
3
|
+
from ._set_new_attribute import set_new_attribute
|
4
|
+
|
5
|
+
|
6
|
+
class EmitTraits(BaseModifier):
|
7
|
+
|
8
|
+
def emit_traits(self):
|
9
|
+
# if no parent defines traits, set it to empty set
|
10
|
+
for base in self.cls.__mro__[-1:0:-1]:
|
11
|
+
if hasattr(base, "traits"):
|
12
|
+
return
|
13
|
+
set_new_attribute(self.cls, "traits", frozenset({}))
|
@@ -0,0 +1,77 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from kirin.exceptions import VerificationError
|
4
|
+
from kirin.decl.emit.init import BaseModifier
|
5
|
+
|
6
|
+
from ._create_fn import create_fn
|
7
|
+
from ._set_new_attribute import set_new_attribute
|
8
|
+
|
9
|
+
|
10
|
+
class EmitTypeCheck(BaseModifier):
|
11
|
+
_VERIFICATION_ERROR = "_kirin_VerificationError"
|
12
|
+
|
13
|
+
def emit_typecheck(self):
|
14
|
+
typecheck_locals: dict[str, Any] = {
|
15
|
+
self._VERIFICATION_ERROR: VerificationError,
|
16
|
+
}
|
17
|
+
body: list[str] = []
|
18
|
+
for name, f in self.fields.args.items():
|
19
|
+
if f.type is f.type.top():
|
20
|
+
continue
|
21
|
+
|
22
|
+
value_type = f"_args_{f.name}_type"
|
23
|
+
typecheck_locals.update({value_type: f.type})
|
24
|
+
if f.group:
|
25
|
+
body.extend(
|
26
|
+
(
|
27
|
+
f"for v in {self._self_name}.{f.name}:",
|
28
|
+
*self._guard_ssa_type("v", f.name, value_type, indent=1),
|
29
|
+
)
|
30
|
+
)
|
31
|
+
else:
|
32
|
+
body.extend(
|
33
|
+
self._guard_ssa_type(
|
34
|
+
f"{self._self_name}.{name}", f.name, value_type
|
35
|
+
)
|
36
|
+
)
|
37
|
+
|
38
|
+
for name, f in self.fields.results.items():
|
39
|
+
if f.type is f.type.top():
|
40
|
+
continue
|
41
|
+
|
42
|
+
value_type = f"_results_{f.name}_type"
|
43
|
+
typecheck_locals.update({value_type: f.type})
|
44
|
+
body.extend(
|
45
|
+
self._guard_ssa_type(f"{self._self_name}.{name}", name, value_type)
|
46
|
+
)
|
47
|
+
|
48
|
+
for name in self.fields.blocks.keys():
|
49
|
+
body.append(f"{self._self_name}.{name}.typecheck()")
|
50
|
+
|
51
|
+
for name, f in self.fields.regions.items():
|
52
|
+
body.append(f"{self._self_name}.{name}.typecheck()")
|
53
|
+
|
54
|
+
# NOTE: we still need to generate this because it is abstract
|
55
|
+
if not body:
|
56
|
+
body.append("pass")
|
57
|
+
|
58
|
+
set_new_attribute(
|
59
|
+
self.cls,
|
60
|
+
"typecheck",
|
61
|
+
create_fn(
|
62
|
+
name="_kirin_decl_typecheck",
|
63
|
+
args=[self._self_name],
|
64
|
+
body=body,
|
65
|
+
globals=self.globals,
|
66
|
+
locals=typecheck_locals,
|
67
|
+
return_type=None,
|
68
|
+
),
|
69
|
+
)
|
70
|
+
|
71
|
+
def _guard_ssa_type(self, ssa, name, type, indent: int = 0):
|
72
|
+
space = " " * indent
|
73
|
+
msg = f"'Invalid type for {name}, expected ' + repr({type}) + ', got ' + repr({ssa}.type)"
|
74
|
+
return (
|
75
|
+
space + f"if not {ssa}.type.is_subseteq({type}):",
|
76
|
+
space + f" raise {self._VERIFICATION_ERROR}({self._self_name}, {msg})",
|
77
|
+
)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from kirin.exceptions import VerificationError
|
4
|
+
from kirin.decl.emit.init import BaseModifier
|
5
|
+
|
6
|
+
from ._create_fn import create_fn
|
7
|
+
from ._set_new_attribute import set_new_attribute
|
8
|
+
|
9
|
+
|
10
|
+
class EmitVerify(BaseModifier):
|
11
|
+
_VERIFICATION_ERROR = "_kirin_VerificationError"
|
12
|
+
|
13
|
+
def emit_verify(self):
|
14
|
+
verify_locals: dict[str, Any] = {
|
15
|
+
self._VERIFICATION_ERROR: VerificationError,
|
16
|
+
}
|
17
|
+
body: list[str] = []
|
18
|
+
for name in self.fields.blocks.keys():
|
19
|
+
body.append(f"{self._self_name}.{name}.verify()")
|
20
|
+
|
21
|
+
for name, f in self.fields.regions.items():
|
22
|
+
body.append(f"{self._self_name}.{name}.verify()")
|
23
|
+
if not f.multi:
|
24
|
+
body.append(f"if len({self._self_name}.{name}.blocks) != 1:")
|
25
|
+
body.append(
|
26
|
+
f" raise {self._VERIFICATION_ERROR}({self._self_name},"
|
27
|
+
f" 'Invalid number of blocks for {name}')"
|
28
|
+
)
|
29
|
+
|
30
|
+
if (traits := getattr(self.cls, "traits", None)) is not None:
|
31
|
+
for trait in traits:
|
32
|
+
trait_obj = f"_kirin_verify_trait_{trait.__class__.__name__}"
|
33
|
+
verify_locals.update({trait_obj: trait})
|
34
|
+
body.append(f"{trait_obj}.verify({self._self_name})")
|
35
|
+
|
36
|
+
# NOTE: we still need to generate this because it is abstract
|
37
|
+
if not body:
|
38
|
+
body.append("pass")
|
39
|
+
|
40
|
+
set_new_attribute(
|
41
|
+
self.cls,
|
42
|
+
"verify",
|
43
|
+
create_fn(
|
44
|
+
name="_kirin_decl_verify",
|
45
|
+
args=[self._self_name],
|
46
|
+
body=body,
|
47
|
+
globals=self.globals,
|
48
|
+
locals=verify_locals,
|
49
|
+
return_type=None,
|
50
|
+
),
|
51
|
+
)
|