jaseci 1.4.2.5__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jaseci might be problematic. Click here for more details.
- jaseci/__init__.py +3 -37
- jaseci-2.0.0.dist-info/METADATA +65 -0
- jaseci-2.0.0.dist-info/RECORD +4 -0
- {jaseci-1.4.2.5.dist-info → jaseci-2.0.0.dist-info}/WHEEL +1 -2
- jaseci/VERSION +0 -1
- jaseci/cli_tools/__init__.py +0 -0
- jaseci/cli_tools/book_tools.py +0 -457
- jaseci/cli_tools/jsctl.py +0 -500
- jaseci/cli_tools/tests/__init__.py +0 -0
- jaseci/cli_tools/tests/test_jsctl.py +0 -556
- jaseci/extens/__init__.py +0 -0
- jaseci/extens/act_lib/__init__.py +0 -0
- jaseci/extens/act_lib/date.py +0 -117
- jaseci/extens/act_lib/elastic.py +0 -87
- jaseci/extens/act_lib/file.py +0 -76
- jaseci/extens/act_lib/file_handler.py +0 -189
- jaseci/extens/act_lib/internal.py +0 -18
- jaseci/extens/act_lib/jaseci.py +0 -61
- jaseci/extens/act_lib/mail.py +0 -10
- jaseci/extens/act_lib/maths.py +0 -168
- jaseci/extens/act_lib/net.py +0 -191
- jaseci/extens/act_lib/rand.py +0 -82
- jaseci/extens/act_lib/regex.py +0 -85
- jaseci/extens/act_lib/request.py +0 -169
- jaseci/extens/act_lib/std.py +0 -235
- jaseci/extens/act_lib/storage.py +0 -53
- jaseci/extens/act_lib/stripe.py +0 -337
- jaseci/extens/act_lib/task.py +0 -13
- jaseci/extens/act_lib/tests/__init__.py +0 -0
- jaseci/extens/act_lib/tests/std_test_code.py +0 -37
- jaseci/extens/act_lib/tests/test_date.py +0 -26
- jaseci/extens/act_lib/tests/test_elastic.py +0 -159
- jaseci/extens/act_lib/tests/test_file.py +0 -116
- jaseci/extens/act_lib/tests/test_file_lib.py +0 -40
- jaseci/extens/act_lib/tests/test_mail_lib.py +0 -33
- jaseci/extens/act_lib/tests/test_maths.py +0 -147
- jaseci/extens/act_lib/tests/test_net_lib.py +0 -62
- jaseci/extens/act_lib/tests/test_regex.py +0 -61
- jaseci/extens/act_lib/tests/test_std.py +0 -51
- jaseci/extens/act_lib/tests/test_std_lib.py +0 -36
- jaseci/extens/act_lib/tests/test_url.py +0 -32
- jaseci/extens/act_lib/tests/test_vector.py +0 -36
- jaseci/extens/act_lib/tests/test_webtool.py +0 -44
- jaseci/extens/act_lib/tests/test_zlib.py +0 -24
- jaseci/extens/act_lib/url.py +0 -79
- jaseci/extens/act_lib/vector.py +0 -157
- jaseci/extens/act_lib/webtool.py +0 -28
- jaseci/extens/act_lib/zip.py +0 -33
- jaseci/extens/api/__init__.py +0 -0
- jaseci/extens/api/actions_api.py +0 -170
- jaseci/extens/api/alias_api.py +0 -139
- jaseci/extens/api/architype_api.py +0 -196
- jaseci/extens/api/config_api.py +0 -129
- jaseci/extens/api/global_api.py +0 -84
- jaseci/extens/api/graph_api.py +0 -167
- jaseci/extens/api/health_api.py +0 -20
- jaseci/extens/api/interface.py +0 -268
- jaseci/extens/api/jac_api.py +0 -171
- jaseci/extens/api/jsorc_api.py +0 -316
- jaseci/extens/api/logger_api.py +0 -89
- jaseci/extens/api/master_api.py +0 -133
- jaseci/extens/api/object_api.py +0 -101
- jaseci/extens/api/prometheus_api.py +0 -74
- jaseci/extens/api/queue_api.py +0 -140
- jaseci/extens/api/sentinel_api.py +0 -270
- jaseci/extens/api/super_api.py +0 -64
- jaseci/extens/api/tests/__init__.py +0 -0
- jaseci/extens/api/tests/test_architype_api.py +0 -66
- jaseci/extens/api/tests/test_global_api.py +0 -179
- jaseci/extens/api/tests/test_graph_api.py +0 -64
- jaseci/extens/api/tests/test_logger_api.py +0 -43
- jaseci/extens/api/tests/test_object_api.py +0 -20
- jaseci/extens/api/tests/test_sentinel_api.py +0 -66
- jaseci/extens/api/tests/test_uncommon.py +0 -107
- jaseci/extens/api/tests/test_user_api.py +0 -32
- jaseci/extens/api/tests/test_walker_api.py +0 -316
- jaseci/extens/api/user_api.py +0 -144
- jaseci/extens/api/walker_api.py +0 -298
- jaseci/extens/api/webhook_api.py +0 -74
- jaseci/extens/svc/__init__.py +0 -0
- jaseci/extens/svc/elastic_svc.py +0 -366
- jaseci/extens/svc/kube_svc.py +0 -432
- jaseci/extens/svc/mail_svc.py +0 -156
- jaseci/extens/svc/prome_svc.py +0 -378
- jaseci/extens/svc/redis_svc.py +0 -63
- jaseci/extens/svc/storage_svc.py +0 -193
- jaseci/extens/svc/stripe_svc.py +0 -51
- jaseci/extens/svc/task_svc.py +0 -155
- jaseci/extens/svc/tasks.py +0 -302
- jaseci/jac/__init__.py +0 -0
- jaseci/jac/interpreter/__init__.py +0 -0
- jaseci/jac/interpreter/architype_interp.py +0 -214
- jaseci/jac/interpreter/interp.py +0 -1783
- jaseci/jac/interpreter/sentinel_interp.py +0 -257
- jaseci/jac/interpreter/tests/__init__.py +0 -0
- jaseci/jac/interpreter/tests/test_interp.py +0 -42
- jaseci/jac/interpreter/walker_interp.py +0 -248
- jaseci/jac/ir/__init__.py +0 -0
- jaseci/jac/ir/ast.py +0 -73
- jaseci/jac/ir/ast_builder.py +0 -249
- jaseci/jac/ir/jac_code.py +0 -152
- jaseci/jac/ir/passes/__init__.py +0 -6
- jaseci/jac/ir/passes/ast_prune_pass.py +0 -9
- jaseci/jac/ir/passes/codegen_pass.py +0 -244
- jaseci/jac/ir/passes/ir_pass.py +0 -29
- jaseci/jac/ir/passes/printer_pass.py +0 -23
- jaseci/jac/ir/passes/pt_prune_pass.py +0 -29
- jaseci/jac/ir/passes/schedule.py +0 -23
- jaseci/jac/ir/passes/stats_pass.py +0 -16
- jaseci/jac/jac.g4 +0 -450
- jaseci/jac/jac_parse/__init__.py +0 -0
- jaseci/jac/jac_parse/jacLexer.py +0 -809
- jaseci/jac/jac_parse/jacListener.py +0 -853
- jaseci/jac/jac_parse/jacParser.py +0 -9192
- jaseci/jac/jac_set.py +0 -119
- jaseci/jac/jsci_vm/__init__.py +0 -0
- jaseci/jac/jsci_vm/disasm.py +0 -94
- jaseci/jac/jsci_vm/inst_ptr.py +0 -31
- jaseci/jac/jsci_vm/machine.py +0 -188
- jaseci/jac/jsci_vm/op_codes.py +0 -82
- jaseci/jac/jsci_vm/tests/__init__.py +0 -0
- jaseci/jac/jsci_vm/tests/test_codegen.py +0 -31
- jaseci/jac/machine/__init__.py +0 -0
- jaseci/jac/machine/jac_scope.py +0 -85
- jaseci/jac/machine/jac_value.py +0 -226
- jaseci/jac/machine/machine_state.py +0 -383
- jaseci/jac/tests/__init__.py +0 -0
- jaseci/jac/tests/book_code.py +0 -624
- jaseci/jac/tests/test_book.py +0 -380
- jaseci/jac/tests/test_lang_14.py +0 -49
- jaseci/jsorc/__init__.py +0 -7
- jaseci/jsorc/jsorc.py +0 -642
- jaseci/jsorc/jsorc_settings.py +0 -211
- jaseci/jsorc/jsorc_utils.py +0 -298
- jaseci/jsorc/live_actions.py +0 -364
- jaseci/jsorc/manifests/__init__.py +0 -0
- jaseci/jsorc/manifests/database.yaml +0 -109
- jaseci/jsorc/manifests/elastic.yaml +0 -6024
- jaseci/jsorc/manifests/prometheus.yaml +0 -1383
- jaseci/jsorc/manifests/redis.yaml +0 -64
- jaseci/jsorc/memory.py +0 -258
- jaseci/jsorc/redis.py +0 -139
- jaseci/jsorc/remote_actions.py +0 -157
- jaseci/jsorc/tests/__init__.py +0 -0
- jaseci/jsorc/tests/test_actions.py +0 -542
- jaseci/jsorc/tests/test_jsorc.py +0 -112
- jaseci/prim/__init__.py +0 -0
- jaseci/prim/ability.py +0 -93
- jaseci/prim/architype.py +0 -89
- jaseci/prim/edge.py +0 -172
- jaseci/prim/element.py +0 -233
- jaseci/prim/graph.py +0 -26
- jaseci/prim/master.py +0 -64
- jaseci/prim/node.py +0 -532
- jaseci/prim/obj_mixins.py +0 -235
- jaseci/prim/sentinel.py +0 -281
- jaseci/prim/super_master.py +0 -31
- jaseci/prim/walker.py +0 -261
- jaseci/svc/__init__.py +0 -0
- jaseci/tests/__init__.py +0 -0
- jaseci/tests/infer.py +0 -39
- jaseci/tests/jac_test_code.py +0 -1293
- jaseci/tests/jac_test_progs.py +0 -774
- jaseci/tests/test_core.py +0 -153
- jaseci/tests/test_jac.py +0 -824
- jaseci/tests/test_node.py +0 -89
- jaseci/tests/test_progs.py +0 -702
- jaseci/tests/test_stack.py +0 -220
- jaseci/tests/test_stripe.py +0 -225
- jaseci/utils/__init__.py +0 -0
- jaseci/utils/actions/__init__.py +0 -0
- jaseci/utils/actions/actions_manager.py +0 -254
- jaseci/utils/actions/actions_optimizer.py +0 -516
- jaseci/utils/actions/actions_state.py +0 -95
- jaseci/utils/file_handler.py +0 -171
- jaseci/utils/gprof2dot.py +0 -3786
- jaseci/utils/id_list.py +0 -168
- jaseci/utils/json_handler.py +0 -70
- jaseci/utils/log_utils.py +0 -57
- jaseci/utils/test_core.py +0 -62
- jaseci/utils/utils.py +0 -387
- jaseci-1.4.2.5.dist-info/LICENSE +0 -21
- jaseci-1.4.2.5.dist-info/METADATA +0 -39
- jaseci-1.4.2.5.dist-info/RECORD +0 -184
- jaseci-1.4.2.5.dist-info/entry_points.txt +0 -3
- jaseci-1.4.2.5.dist-info/top_level.txt +0 -1
jaseci/jac/ir/ast_builder.py
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from antlr4 import ParseTreeListener
|
|
3
|
-
from antlr4.error.ErrorListener import ErrorListener
|
|
4
|
-
from jaseci.utils.utils import logger, parse_str_token
|
|
5
|
-
from jaseci.jac.jac_parse.jacParser import jacParser, ParseTreeWalker
|
|
6
|
-
from jaseci.jac.jac_parse.jacLexer import jacLexer
|
|
7
|
-
from antlr4 import InputStream, CommonTokenStream
|
|
8
|
-
from jaseci.jac.ir.ast import Ast
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class JacAstBuilder:
|
|
12
|
-
"""
|
|
13
|
-
Jac Code to AST Tree
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
_ast_head_map = {}
|
|
17
|
-
|
|
18
|
-
def __init__(
|
|
19
|
-
self,
|
|
20
|
-
mod_name,
|
|
21
|
-
mod_dir="./",
|
|
22
|
-
jac_text=None,
|
|
23
|
-
start_rule="start",
|
|
24
|
-
):
|
|
25
|
-
self.root = Ast(mod_name)
|
|
26
|
-
self._parse_errors = []
|
|
27
|
-
self._start_rule = start_rule
|
|
28
|
-
self._mod_dir = mod_dir
|
|
29
|
-
self.dependencies = []
|
|
30
|
-
if jac_text:
|
|
31
|
-
self.jac_code_to_ast(jac_text)
|
|
32
|
-
|
|
33
|
-
def jac_code_to_ast(self, jac_str):
|
|
34
|
-
"""Parse language and build ast from string"""
|
|
35
|
-
JacAstBuilder._ast_head_map[self._mod_dir + self.root.loc[2]] = self
|
|
36
|
-
input_stream = InputStream(jac_str)
|
|
37
|
-
lexer = jacLexer(input_stream)
|
|
38
|
-
stream = CommonTokenStream(lexer)
|
|
39
|
-
errors = JacTreeError(self)
|
|
40
|
-
parser = jacParser(stream)
|
|
41
|
-
parser.removeErrorListeners()
|
|
42
|
-
parser.addErrorListener(errors)
|
|
43
|
-
tree = getattr(parser, self._start_rule)()
|
|
44
|
-
builder = JacTreeBuilder(builder=self, code=jac_str)
|
|
45
|
-
walker = ParseTreeWalker()
|
|
46
|
-
walker.walk(builder, tree)
|
|
47
|
-
|
|
48
|
-
if self._parse_errors:
|
|
49
|
-
logger.error(str(f"Parse errors encountered - {self}"))
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class JacTreeBuilder(ParseTreeListener):
|
|
53
|
-
"""Converter class from Antlr trees to Jaseci Tree"""
|
|
54
|
-
|
|
55
|
-
def __init__(self, builder, code):
|
|
56
|
-
self.builder = builder
|
|
57
|
-
self.code = code
|
|
58
|
-
self.node_stack = []
|
|
59
|
-
|
|
60
|
-
def run_import_module(self, jac_ast):
|
|
61
|
-
"""
|
|
62
|
-
import_module:
|
|
63
|
-
KW_IMPORT LBRACE (import_items | '*') RBRACE
|
|
64
|
-
KW_WITH STRING SEMI;
|
|
65
|
-
|
|
66
|
-
TODO: Check for duplicate imports and ignore if imported
|
|
67
|
-
"""
|
|
68
|
-
kid = jac_ast.kid
|
|
69
|
-
fn = os.path.join(self.builder._mod_dir, parse_str_token(kid[-2].token_text()))
|
|
70
|
-
full_path = os.path.realpath(fn)
|
|
71
|
-
mod_name = os.path.basename(fn)
|
|
72
|
-
mdir = os.path.dirname(full_path) + "/"
|
|
73
|
-
from_mod = self.builder.root.loc[2]
|
|
74
|
-
logger.debug(f"Importing items from {mod_name} to {from_mod}...")
|
|
75
|
-
pre_build = None
|
|
76
|
-
if (mdir + mod_name) in JacAstBuilder._ast_head_map.keys():
|
|
77
|
-
pre_build = JacAstBuilder._ast_head_map[mdir + mod_name]
|
|
78
|
-
elif os.path.isfile(fn):
|
|
79
|
-
with open(fn, "r") as file:
|
|
80
|
-
jac_text = file.read()
|
|
81
|
-
pre_build = JacAstBuilder(
|
|
82
|
-
jac_text=jac_text,
|
|
83
|
-
mod_name=mod_name,
|
|
84
|
-
mod_dir=mdir,
|
|
85
|
-
)
|
|
86
|
-
else:
|
|
87
|
-
err = (
|
|
88
|
-
f"Module not found for import! {mod_name} from" + f" {from_mod} - {fn}"
|
|
89
|
-
)
|
|
90
|
-
self.builder._parse_errors.append(err)
|
|
91
|
-
if pre_build:
|
|
92
|
-
self.builder._parse_errors += pre_build._parse_errors
|
|
93
|
-
self.builder.dependencies += pre_build.dependencies
|
|
94
|
-
import_elements = list(
|
|
95
|
-
filter(lambda x: x.name == "element", pre_build.root.kid)
|
|
96
|
-
)
|
|
97
|
-
if kid[2].name == "STAR_MUL":
|
|
98
|
-
ret = import_elements
|
|
99
|
-
else:
|
|
100
|
-
ret = self.run_import_items(kid[2], import_elements)
|
|
101
|
-
for i in ret:
|
|
102
|
-
self.builder.dependencies.append(i)
|
|
103
|
-
return ret
|
|
104
|
-
else:
|
|
105
|
-
return []
|
|
106
|
-
|
|
107
|
-
def run_import_items(self, jac_ast, import_elements):
|
|
108
|
-
"""
|
|
109
|
-
import_items:
|
|
110
|
-
WALKER_DBL_COLON (STAR_MUL | import_names) (
|
|
111
|
-
COMMA import_items
|
|
112
|
-
)?
|
|
113
|
-
| NODE_DBL_COLON (STAR_MUL | import_names) (
|
|
114
|
-
COMMA import_items
|
|
115
|
-
)?
|
|
116
|
-
| EDGE_DBL_COLON (STAR_MUL | import_names) (
|
|
117
|
-
COMMA import_items
|
|
118
|
-
)?
|
|
119
|
-
| GRAPH_DBL_COLON (STAR_MUL | import_names) (
|
|
120
|
-
COMMA import_items
|
|
121
|
-
)?
|
|
122
|
-
| KW_GLOBAL DBL_COLON (STAR_MUL | import_names) (
|
|
123
|
-
COMMA import_items
|
|
124
|
-
)?
|
|
125
|
-
| TYPE_DBL_COLON (STAR_MUL | import_names) (
|
|
126
|
-
COMMA import_items
|
|
127
|
-
)?;
|
|
128
|
-
"""
|
|
129
|
-
kid = jac_ast.kid
|
|
130
|
-
type_name = (
|
|
131
|
-
"KW_" + kid[0].name.split("_")[0]
|
|
132
|
-
if not kid[0].name.startswith("KW_")
|
|
133
|
-
else kid[0].name
|
|
134
|
-
)
|
|
135
|
-
kid = kid[2:] if kid[1].name == "DBL_COLON" else kid[1:]
|
|
136
|
-
ret_elements = list(
|
|
137
|
-
filter(
|
|
138
|
-
lambda x: x in self.builder.dependencies
|
|
139
|
-
or x.kid[0].kid[0].name == type_name,
|
|
140
|
-
import_elements,
|
|
141
|
-
)
|
|
142
|
-
)
|
|
143
|
-
if kid[0].name == "import_names":
|
|
144
|
-
import_names = self.run_import_names(kid[0])
|
|
145
|
-
ret_elements = list(
|
|
146
|
-
filter(
|
|
147
|
-
lambda x: x in self.builder.dependencies
|
|
148
|
-
or x.kid[0].kid[1].token_text() in import_names,
|
|
149
|
-
ret_elements,
|
|
150
|
-
)
|
|
151
|
-
)
|
|
152
|
-
if len(ret_elements) < len(import_names):
|
|
153
|
-
err = (
|
|
154
|
-
f"{kid[0].loc[2]}: Line {kid[0].loc[0]}: "
|
|
155
|
-
+ "Module name not found!"
|
|
156
|
-
)
|
|
157
|
-
self.builder._parse_errors.append(err)
|
|
158
|
-
|
|
159
|
-
if kid[-1].name == "import_items":
|
|
160
|
-
return ret_elements + self.run_import_items(kid[-1], import_elements)
|
|
161
|
-
|
|
162
|
-
return ret_elements
|
|
163
|
-
|
|
164
|
-
def run_import_names(self, jac_ast):
|
|
165
|
-
"""
|
|
166
|
-
import_names: NAME | LBRACE name_list RBRACE;
|
|
167
|
-
"""
|
|
168
|
-
kid = jac_ast.kid
|
|
169
|
-
if kid[0].name == "NAME":
|
|
170
|
-
return [kid[0].token_text()]
|
|
171
|
-
else:
|
|
172
|
-
return self.run_name_list(kid[1])
|
|
173
|
-
|
|
174
|
-
def run_name_list(self, jac_ast):
|
|
175
|
-
"""
|
|
176
|
-
name_list: NAME (COMMA NAME)*;
|
|
177
|
-
"""
|
|
178
|
-
kid = jac_ast.kid
|
|
179
|
-
ret = []
|
|
180
|
-
for i in kid:
|
|
181
|
-
if i.name == "NAME":
|
|
182
|
-
ret.append(i.token_text())
|
|
183
|
-
return ret
|
|
184
|
-
|
|
185
|
-
def enterEveryRule(self, ctx): # noqa
|
|
186
|
-
"""Visits every node in antlr parse tree"""
|
|
187
|
-
if len(self.node_stack) == 0:
|
|
188
|
-
new_node = self.builder.root
|
|
189
|
-
else:
|
|
190
|
-
new_node = Ast(mod_name=self.builder.root.loc[2])
|
|
191
|
-
new_node.name = jacParser.ruleNames[ctx.getRuleIndex()]
|
|
192
|
-
new_node.loc[0] = ctx.start.line
|
|
193
|
-
if new_node.name == "architype":
|
|
194
|
-
new_node.src = self.get_code(ctx)
|
|
195
|
-
new_node.loc[1] = ctx.start.column
|
|
196
|
-
|
|
197
|
-
if len(self.node_stack) and new_node.name != "import_module":
|
|
198
|
-
self.node_stack[-1].kid.append(new_node)
|
|
199
|
-
self.node_stack.append(new_node)
|
|
200
|
-
|
|
201
|
-
def exitEveryRule(self, ctx): # noqa
|
|
202
|
-
"""Overloaded function that visits every node on exit"""
|
|
203
|
-
top = self.node_stack.pop()
|
|
204
|
-
if top.name == "import_module":
|
|
205
|
-
for i in self.run_import_module(top):
|
|
206
|
-
if i not in self.node_stack[-1].kid:
|
|
207
|
-
self.node_stack[-1].kid.append(i)
|
|
208
|
-
|
|
209
|
-
def visitTerminal(self, node): # noqa
|
|
210
|
-
"""Visits terminals as walker walks, adds ast node"""
|
|
211
|
-
new_node = Ast(mod_name=self.builder.root.loc[2])
|
|
212
|
-
new_node.name = jacParser.symbolicNames[node.getSymbol().type]
|
|
213
|
-
new_node.loc[0] = node.getSymbol().line
|
|
214
|
-
new_node.loc[1] = node.getSymbol().column
|
|
215
|
-
|
|
216
|
-
token = {
|
|
217
|
-
"symbol": jacParser.symbolicNames[node.getSymbol().type],
|
|
218
|
-
"text": node.getSymbol().text,
|
|
219
|
-
}
|
|
220
|
-
new_node.loc[3]["token"] = token
|
|
221
|
-
|
|
222
|
-
self.node_stack[-1].kid.append(new_node)
|
|
223
|
-
|
|
224
|
-
def get_code(self, ctx):
|
|
225
|
-
out = ""
|
|
226
|
-
lines = self.code.split("\n")
|
|
227
|
-
|
|
228
|
-
for idx, i in enumerate(lines[ctx.start.line - 1 : ctx.stop.line]):
|
|
229
|
-
out += i
|
|
230
|
-
if idx != ctx.stop.line - 1:
|
|
231
|
-
out += "\n"
|
|
232
|
-
|
|
233
|
-
return out
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
class JacTreeError(ErrorListener):
|
|
237
|
-
"""Accumulate errors as parse tree is walked"""
|
|
238
|
-
|
|
239
|
-
def __init__(self, builder):
|
|
240
|
-
self.builder = builder
|
|
241
|
-
|
|
242
|
-
def syntaxError( # noqa
|
|
243
|
-
self, recognizer, offendingSymbol, line, column, msg, e # noqa
|
|
244
|
-
):
|
|
245
|
-
"""Add error to error list"""
|
|
246
|
-
root = self.builder.root
|
|
247
|
-
self.builder._parse_errors.append(
|
|
248
|
-
f"{str(root.loc[2])}: line {str(line)}:" f"{str(column)} - {root} - {msg}"
|
|
249
|
-
)
|
jaseci/jac/ir/jac_code.py
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Mix in for jac code object in Jaseci
|
|
3
|
-
"""
|
|
4
|
-
import json
|
|
5
|
-
from jaseci.utils.utils import logger
|
|
6
|
-
from jaseci.jac.ir.ast_builder import JacAstBuilder
|
|
7
|
-
from jaseci.jac.ir.passes.schedule import multi_pass_optimizer
|
|
8
|
-
from jaseci.jac.ir.ast import Ast
|
|
9
|
-
import hashlib
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
from os.path import dirname
|
|
12
|
-
|
|
13
|
-
from jaseci.jac.ir.passes.printer_pass import PrinterPass
|
|
14
|
-
|
|
15
|
-
# Used to check ir matches grammar of current Jaseci instance
|
|
16
|
-
grammar_hash = hashlib.md5(
|
|
17
|
-
Path(dirname(__file__) + "/../jac.g4").read_text().encode()
|
|
18
|
-
).hexdigest()
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class JacJsonEnc(json.JSONEncoder):
|
|
22
|
-
"""Custom Json encoder for Jac ASTs"""
|
|
23
|
-
|
|
24
|
-
def default(self, obj):
|
|
25
|
-
if isinstance(obj, Ast):
|
|
26
|
-
retd = {}
|
|
27
|
-
for i in obj.__dict__.keys():
|
|
28
|
-
if not i.startswith("_"):
|
|
29
|
-
retd[i] = obj.__dict__[i]
|
|
30
|
-
return retd
|
|
31
|
-
return super().default(obj)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class JacJsonDec(json.JSONDecoder):
|
|
35
|
-
"""Custom hook for decoding Jac ASTs"""
|
|
36
|
-
|
|
37
|
-
def __init__(self, *args, **kwargs):
|
|
38
|
-
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs)
|
|
39
|
-
|
|
40
|
-
def object_hook(self, obj):
|
|
41
|
-
if isinstance(obj, dict) and "loc" in obj and "kid" in obj:
|
|
42
|
-
ret = Ast(mod_name=obj["loc"][2])
|
|
43
|
-
for i in obj.keys():
|
|
44
|
-
setattr(ret, i, obj[i])
|
|
45
|
-
return ret
|
|
46
|
-
return obj
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def jac_ast_to_ir(jac_ast: Ast):
|
|
50
|
-
"""Convert AST to IR string"""
|
|
51
|
-
return json.dumps(cls=JacJsonEnc, obj={"gram_hash": grammar_hash, "ir": jac_ast})
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def jac_ir_to_ast(ir: str):
|
|
55
|
-
"""Convert IR string to AST"""
|
|
56
|
-
ir_load = json.loads(cls=JacJsonDec, s=ir)
|
|
57
|
-
if (
|
|
58
|
-
not isinstance(ir_load, dict)
|
|
59
|
-
or "gram_hash" not in ir_load
|
|
60
|
-
or ir_load["gram_hash"] != grammar_hash
|
|
61
|
-
or (not isinstance(ir_load["ir"], Ast) and not ir_load["ir"] is None)
|
|
62
|
-
):
|
|
63
|
-
logger.error(
|
|
64
|
-
"Jac IR invalid or incompatible with current Jaseci "
|
|
65
|
-
f"(valid gram_hash: {grammar_hash}!"
|
|
66
|
-
)
|
|
67
|
-
return ir_load["ir"]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class JacCode:
|
|
71
|
-
"""Obj mixin to code pickling"""
|
|
72
|
-
|
|
73
|
-
def __init__(self, code_ir=None):
|
|
74
|
-
self.is_active = False
|
|
75
|
-
self.code_ir = None
|
|
76
|
-
self.code_sig = None
|
|
77
|
-
self._jac_ast = None
|
|
78
|
-
self.errors = []
|
|
79
|
-
self.apply_ir(code_ir)
|
|
80
|
-
|
|
81
|
-
def reset(self):
|
|
82
|
-
JacCode.__init__(self)
|
|
83
|
-
|
|
84
|
-
def refresh(self):
|
|
85
|
-
self._jac_ast = jac_ir_to_ast(self.code_ir) if self.code_ir else None
|
|
86
|
-
if self._jac_ast:
|
|
87
|
-
self.is_active = True
|
|
88
|
-
else:
|
|
89
|
-
self.is_active = False
|
|
90
|
-
|
|
91
|
-
def apply_ir(self, ir):
|
|
92
|
-
"""Apply's IR to object"""
|
|
93
|
-
self.code_ir = (
|
|
94
|
-
ir.strip()
|
|
95
|
-
if (isinstance(ir, str))
|
|
96
|
-
else json.dumps(ir)
|
|
97
|
-
if (isinstance(ir, dict))
|
|
98
|
-
else jac_ast_to_ir(ir)
|
|
99
|
-
)
|
|
100
|
-
self.code_sig = hashlib.md5(self.code_ir.encode()).hexdigest()
|
|
101
|
-
JacCode.refresh(self) # should disregard overloaded versions
|
|
102
|
-
|
|
103
|
-
def compile_jac(self, code, dir, start_rule="start", opt_level=4):
|
|
104
|
-
"""Generate AST tree from Jac code text"""
|
|
105
|
-
tree = JacAstBuilder(
|
|
106
|
-
jac_text=code, start_rule=start_rule, mod_name=self.name, mod_dir=dir
|
|
107
|
-
)
|
|
108
|
-
# Must clear this state across compiles (so fresh imports dont use stale data)
|
|
109
|
-
JacAstBuilder._ast_head_map = {}
|
|
110
|
-
|
|
111
|
-
self.errors = tree._parse_errors
|
|
112
|
-
if tree._parse_errors:
|
|
113
|
-
logger.error(str(f"{self.name}: Invalid syntax in Jac code!"))
|
|
114
|
-
for i in tree._parse_errors:
|
|
115
|
-
logger.error(i)
|
|
116
|
-
return None
|
|
117
|
-
|
|
118
|
-
multi_pass_optimizer(
|
|
119
|
-
tree.root, opt_level=opt_level
|
|
120
|
-
) # run analysis and optimizers
|
|
121
|
-
|
|
122
|
-
return tree.root
|
|
123
|
-
|
|
124
|
-
def get_jac_ast(self):
|
|
125
|
-
if not self._jac_ast:
|
|
126
|
-
self.refresh()
|
|
127
|
-
return self._jac_ast
|
|
128
|
-
|
|
129
|
-
def print_ir(self, to_screen=True):
|
|
130
|
-
irout = PrinterPass(ir=self.get_jac_ast(), to_screen=to_screen)
|
|
131
|
-
irout.run()
|
|
132
|
-
return irout.output
|
|
133
|
-
|
|
134
|
-
def register(self, code, dir, opt_level=4):
|
|
135
|
-
"""
|
|
136
|
-
Parses Jac code and saves IR
|
|
137
|
-
"""
|
|
138
|
-
start_rule = "start" if self.j_type == "sentinel" else self.j_type
|
|
139
|
-
tree = self.compile_jac(code, dir, start_rule=start_rule, opt_level=opt_level)
|
|
140
|
-
|
|
141
|
-
if not tree:
|
|
142
|
-
self.is_active = False
|
|
143
|
-
else:
|
|
144
|
-
self.apply_ir(tree)
|
|
145
|
-
|
|
146
|
-
if not self.is_active:
|
|
147
|
-
logger.error(str(f"{self.name}: Code not registered"))
|
|
148
|
-
return self.is_active
|
|
149
|
-
|
|
150
|
-
def ir_dict(self):
|
|
151
|
-
"""Return IR as dictionary"""
|
|
152
|
-
return json.loads(self.code_ir)
|
jaseci/jac/ir/passes/__init__.py
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
from jaseci.jac.ir.passes.ir_pass import IrPass # noqa
|
|
2
|
-
from jaseci.jac.ir.passes.pt_prune_pass import ParseTreePrunePass # noqa
|
|
3
|
-
from jaseci.jac.ir.passes.printer_pass import PrinterPass # noqa
|
|
4
|
-
from jaseci.jac.ir.passes.stats_pass import StatsPass # noqa
|
|
5
|
-
from jaseci.jac.ir.passes.codegen_pass import CodeGenPass # noqa
|
|
6
|
-
from jaseci.jac.ir.passes.ast_prune_pass import AstPrunePass # noqa
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
from jaseci.jac.ir.passes.ir_pass import IrPass
|
|
2
|
-
from base64 import b64encode
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class AstPrunePass(IrPass):
|
|
6
|
-
def enter_node(self, node):
|
|
7
|
-
if hasattr(node, "bytecode") and node.bytecode:
|
|
8
|
-
node.bytecode = b64encode(node.bytecode).decode()
|
|
9
|
-
node.kid = [] if node.name != "inc_assign" else [node.kid[0]]
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
from jaseci.jac.ir.passes import IrPass
|
|
2
|
-
from jaseci.jac.jsci_vm.op_codes import JsCmp, JsOp, JsType
|
|
3
|
-
from struct import pack
|
|
4
|
-
|
|
5
|
-
from jaseci.utils.utils import parse_str_token
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def byte_length(val):
|
|
9
|
-
if type(val) == str:
|
|
10
|
-
return len(bytes(val, "unicode_escape"))
|
|
11
|
-
else:
|
|
12
|
-
return (val.bit_length() + 7) // 8
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def to_bytes(val):
|
|
16
|
-
if type(val) == str:
|
|
17
|
-
return bytes(val, "unicode_escape")
|
|
18
|
-
elif type(val) == float:
|
|
19
|
-
return pack("d", val)
|
|
20
|
-
elif type(val) == int:
|
|
21
|
-
return val.to_bytes(byte_length(val), "little")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def has_bytecode(node):
|
|
25
|
-
if not hasattr(node, "bytecode"):
|
|
26
|
-
return False
|
|
27
|
-
return True
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def is_bytecode_complete(node):
|
|
31
|
-
for i in node.kid:
|
|
32
|
-
if not i.is_terminal() and not has_bytecode(i) and i.name != "cmp_op":
|
|
33
|
-
return False
|
|
34
|
-
return True
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class CodeGenPass(IrPass):
|
|
38
|
-
def __init__(self, debug_info=True, **kwargs):
|
|
39
|
-
super().__init__(**kwargs)
|
|
40
|
-
self.debug_info = debug_info
|
|
41
|
-
self.cur_loc = None
|
|
42
|
-
self.create_var_mode = 0
|
|
43
|
-
|
|
44
|
-
def emit(self, node, *items):
|
|
45
|
-
if not has_bytecode(node):
|
|
46
|
-
node.bytecode = bytearray()
|
|
47
|
-
node_loc = [node.loc[0], node.loc[2]]
|
|
48
|
-
if self.debug_info and self.cur_loc != node_loc:
|
|
49
|
-
debug_inst = [
|
|
50
|
-
JsOp.DEBUG_INFO,
|
|
51
|
-
byte_length(node_loc[0]),
|
|
52
|
-
to_bytes(node_loc[0]),
|
|
53
|
-
]
|
|
54
|
-
if not self.cur_loc or self.cur_loc[1] != node_loc[1]:
|
|
55
|
-
debug_inst += [byte_length(node_loc[1]), to_bytes(node_loc[1])]
|
|
56
|
-
else:
|
|
57
|
-
debug_inst += [0]
|
|
58
|
-
self.cur_loc = node_loc
|
|
59
|
-
items = debug_inst + list(items)
|
|
60
|
-
for i in items:
|
|
61
|
-
if type(i) in [bytes, bytearray]:
|
|
62
|
-
node.bytecode += bytearray(i)
|
|
63
|
-
elif type(i) is str:
|
|
64
|
-
node.bytecode += bytearray(i, "utf-8")
|
|
65
|
-
else:
|
|
66
|
-
node.bytecode.append(i)
|
|
67
|
-
|
|
68
|
-
def enter_node(self, node):
|
|
69
|
-
# print("entering", node)
|
|
70
|
-
if hasattr(self, f"enter_{node.name}"):
|
|
71
|
-
getattr(self, f"enter_{node.name}")(node)
|
|
72
|
-
|
|
73
|
-
def exit_node(self, node):
|
|
74
|
-
# print("exiting", node)
|
|
75
|
-
if hasattr(self, f"exit_{node.name}"):
|
|
76
|
-
getattr(self, f"exit_{node.name}")(node)
|
|
77
|
-
if hasattr(node, "_create_flag"):
|
|
78
|
-
self.create_var_mode -= 1
|
|
79
|
-
|
|
80
|
-
def enter_expression(self, node):
|
|
81
|
-
kid = node.kid
|
|
82
|
-
if len(kid) > 1 and kid[-1].name == "assignment":
|
|
83
|
-
kid[-1]._create_flag = True
|
|
84
|
-
self.create_var_mode += 1
|
|
85
|
-
|
|
86
|
-
def exit_expression(self, node): # TODO: Incomplete
|
|
87
|
-
kid = node.kid
|
|
88
|
-
if is_bytecode_complete(node):
|
|
89
|
-
for i in reversed(node.kid):
|
|
90
|
-
if has_bytecode(i):
|
|
91
|
-
self.emit(node, i.bytecode)
|
|
92
|
-
if len(kid) > 1 and kid[1].name == "assignment":
|
|
93
|
-
self.emit(node, JsOp.ASSIGN)
|
|
94
|
-
elif len(kid) > 1 and kid[1].name == "copy_assign":
|
|
95
|
-
self.emit(node, JsOp.COPY_FIELDS)
|
|
96
|
-
elif len(kid) > 1 and kid[1].name == "inc_assign":
|
|
97
|
-
self.emit(node, JsOp.INCREMENT, JsCmp[kid[1].kid[0].name])
|
|
98
|
-
|
|
99
|
-
def exit_assignment(self, node):
|
|
100
|
-
if is_bytecode_complete(node):
|
|
101
|
-
if has_bytecode(node.kid[-1]):
|
|
102
|
-
self.emit(node, node.kid[-1].bytecode)
|
|
103
|
-
|
|
104
|
-
def exit_copy_assign(self, node):
|
|
105
|
-
if is_bytecode_complete(node):
|
|
106
|
-
if has_bytecode(node.kid[-1]):
|
|
107
|
-
self.emit(node, node.kid[-1].bytecode)
|
|
108
|
-
|
|
109
|
-
def exit_inc_assign(self, node):
|
|
110
|
-
if is_bytecode_complete(node):
|
|
111
|
-
if has_bytecode(node.kid[-1]):
|
|
112
|
-
self.emit(node, node.kid[-1].bytecode)
|
|
113
|
-
|
|
114
|
-
def exit_logical(self, node):
|
|
115
|
-
if is_bytecode_complete(node):
|
|
116
|
-
for i in reversed(node.kid):
|
|
117
|
-
if has_bytecode(i):
|
|
118
|
-
self.emit(node, i.bytecode)
|
|
119
|
-
for i in node.kid:
|
|
120
|
-
if i.name == "KW_AND":
|
|
121
|
-
self.emit(node, JsOp.AND)
|
|
122
|
-
elif i.name == "KW_OR":
|
|
123
|
-
self.emit(node, JsOp.OR)
|
|
124
|
-
|
|
125
|
-
def exit_compare(self, node):
|
|
126
|
-
if is_bytecode_complete(node):
|
|
127
|
-
for i in reversed(node.kid):
|
|
128
|
-
if has_bytecode(i):
|
|
129
|
-
self.emit(node, i.bytecode)
|
|
130
|
-
for i in node.kid:
|
|
131
|
-
if i.name == "NOT":
|
|
132
|
-
self.emit(node, JsOp.COMPARE, JsCmp.NOT)
|
|
133
|
-
elif i.name == "cmp_op" and i.kid[0].name == "EE":
|
|
134
|
-
self.emit(node, JsOp.COMPARE, JsCmp.EE)
|
|
135
|
-
elif i.name == "cmp_op" and i.kid[0].name == "LT":
|
|
136
|
-
self.emit(node, JsOp.COMPARE, JsCmp.LT)
|
|
137
|
-
elif i.name == "cmp_op" and i.kid[0].name == "GT":
|
|
138
|
-
self.emit(node, JsOp.COMPARE, JsCmp.GT)
|
|
139
|
-
elif i.name == "cmp_op" and i.kid[0].name == "LTE":
|
|
140
|
-
self.emit(node, JsOp.COMPARE, JsCmp.LTE)
|
|
141
|
-
elif i.name == "cmp_op" and i.kid[0].name == "GTE":
|
|
142
|
-
self.emit(node, JsOp.COMPARE, JsCmp.GTE)
|
|
143
|
-
elif i.name == "cmp_op" and i.kid[0].name == "NE":
|
|
144
|
-
self.emit(node, JsOp.COMPARE, JsCmp.NE)
|
|
145
|
-
elif i.name == "cmp_op" and i.kid[0].name == "KW_IN":
|
|
146
|
-
self.emit(node, JsOp.COMPARE, JsCmp.IN)
|
|
147
|
-
elif i.name == "cmp_op" and i.kid[0].name == "nin":
|
|
148
|
-
self.emit(node, JsOp.COMPARE, JsCmp.NIN)
|
|
149
|
-
|
|
150
|
-
def exit_arithmetic(self, node):
|
|
151
|
-
if is_bytecode_complete(node):
|
|
152
|
-
for i in reversed(node.kid):
|
|
153
|
-
if has_bytecode(i):
|
|
154
|
-
self.emit(node, i.bytecode)
|
|
155
|
-
for i in node.kid:
|
|
156
|
-
if i.name == "PLUS":
|
|
157
|
-
self.emit(node, JsOp.ADD)
|
|
158
|
-
elif i.name == "MINUS":
|
|
159
|
-
self.emit(node, JsOp.SUBTRACT)
|
|
160
|
-
|
|
161
|
-
def exit_term(self, node):
|
|
162
|
-
if is_bytecode_complete(node):
|
|
163
|
-
for i in reversed(node.kid):
|
|
164
|
-
if has_bytecode(i):
|
|
165
|
-
self.emit(node, i.bytecode)
|
|
166
|
-
for i in node.kid:
|
|
167
|
-
if i.name == "STAR_MUL":
|
|
168
|
-
self.emit(node, JsOp.MULTIPLY)
|
|
169
|
-
elif i.name == "DIV":
|
|
170
|
-
self.emit(node, JsOp.DIVIDE)
|
|
171
|
-
elif i.name == "MOD":
|
|
172
|
-
self.emit(node, JsOp.MODULO)
|
|
173
|
-
|
|
174
|
-
def exit_factor(self, node):
|
|
175
|
-
if is_bytecode_complete(node):
|
|
176
|
-
self.emit(node, node.kid[-1].bytecode)
|
|
177
|
-
if node.kid[0].name == "MINUS":
|
|
178
|
-
self.emit(node, JsOp.NEGATE)
|
|
179
|
-
|
|
180
|
-
def exit_power(self, node):
|
|
181
|
-
if is_bytecode_complete(node):
|
|
182
|
-
for i in reversed(node.kid):
|
|
183
|
-
if has_bytecode(i):
|
|
184
|
-
self.emit(node, i.bytecode)
|
|
185
|
-
for i in node.kid:
|
|
186
|
-
if i.name == "POW":
|
|
187
|
-
self.emit(node, JsOp.POWER)
|
|
188
|
-
|
|
189
|
-
def exit_atom(self, node): # TODO: Incomplete
|
|
190
|
-
kid = node.kid
|
|
191
|
-
if kid[0].name == "INT":
|
|
192
|
-
val = int(kid[0].token_text())
|
|
193
|
-
self.emit(
|
|
194
|
-
node, JsOp.LOAD_CONST, JsType.INT, byte_length(val), to_bytes(val)
|
|
195
|
-
)
|
|
196
|
-
elif kid[0].name == "FLOAT":
|
|
197
|
-
val = float(kid[0].token_text())
|
|
198
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.FLOAT, to_bytes(val))
|
|
199
|
-
elif kid[0].name == "multistring":
|
|
200
|
-
val = ""
|
|
201
|
-
for i in kid[0].kid:
|
|
202
|
-
val += parse_str_token(i.token_text())
|
|
203
|
-
str_len = byte_length(val)
|
|
204
|
-
self.emit(
|
|
205
|
-
node,
|
|
206
|
-
JsOp.LOAD_CONST,
|
|
207
|
-
JsType.STRING,
|
|
208
|
-
byte_length(str_len),
|
|
209
|
-
to_bytes(str_len),
|
|
210
|
-
)
|
|
211
|
-
if str_len > 0:
|
|
212
|
-
self.emit(node, to_bytes(val))
|
|
213
|
-
elif kid[0].name == "BOOL":
|
|
214
|
-
val = int(kid[0].token_text() == "true")
|
|
215
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.BOOL, val)
|
|
216
|
-
elif kid[0].name == "NULL":
|
|
217
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.NULL)
|
|
218
|
-
elif kid[0].name == "NAME":
|
|
219
|
-
name = kid[0].token_text()
|
|
220
|
-
if self.create_var_mode:
|
|
221
|
-
self.emit(node, JsOp.CREATE_VAR, byte_length(name), to_bytes(name))
|
|
222
|
-
else:
|
|
223
|
-
self.emit(node, JsOp.LOAD_VAR, byte_length(name), to_bytes(name))
|
|
224
|
-
|
|
225
|
-
def exit_any_type(self, node):
|
|
226
|
-
kid = node.kid
|
|
227
|
-
if kid[0].name == "TYP_STRING":
|
|
228
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.STRING)
|
|
229
|
-
elif kid[0].name == "TYP_INT":
|
|
230
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.INT)
|
|
231
|
-
elif kid[0].name == "TYP_FLOAT":
|
|
232
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.FLOAT)
|
|
233
|
-
elif kid[0].name == "TYP_LIST":
|
|
234
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.LIST)
|
|
235
|
-
elif kid[0].name == "TYP_DICT":
|
|
236
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.DICT)
|
|
237
|
-
elif kid[0].name == "TYP_BOOL":
|
|
238
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.BOOL)
|
|
239
|
-
elif kid[0].name == "KW_NODE":
|
|
240
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.NODE)
|
|
241
|
-
elif kid[0].name == "KW_EDGE":
|
|
242
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.EDGE)
|
|
243
|
-
elif kid[0].name == "KW_TYPE":
|
|
244
|
-
self.emit(node, JsOp.LOAD_CONST, JsType.TYPE, JsType.TYPE)
|
jaseci/jac/ir/passes/ir_pass.py
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
class IrPass:
|
|
2
|
-
def __init__(self, ir=None):
|
|
3
|
-
self.ir = ir
|
|
4
|
-
|
|
5
|
-
def before_pass(self):
|
|
6
|
-
pass
|
|
7
|
-
|
|
8
|
-
def after_pass(self):
|
|
9
|
-
pass
|
|
10
|
-
|
|
11
|
-
def enter_node(self, node):
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
def exit_node(self, node):
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
def run(self):
|
|
18
|
-
self.before_pass()
|
|
19
|
-
self.traverse()
|
|
20
|
-
self.after_pass()
|
|
21
|
-
return self
|
|
22
|
-
|
|
23
|
-
def traverse(self, node=None):
|
|
24
|
-
if node is None:
|
|
25
|
-
node = self.ir
|
|
26
|
-
self.enter_node(node)
|
|
27
|
-
for i in node.kid:
|
|
28
|
-
self.traverse(i)
|
|
29
|
-
self.exit_node(node)
|