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/interpreter/interp.py
DELETED
|
@@ -1,1783 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Interpreter for jac code in AST form
|
|
3
|
-
|
|
4
|
-
This interpreter should be inhereted from the class that manages state
|
|
5
|
-
referenced through self.
|
|
6
|
-
"""
|
|
7
|
-
from jaseci.jsorc.jsorc import JsOrc
|
|
8
|
-
from jaseci.extens.svc.task_svc import TaskService
|
|
9
|
-
from jaseci.utils.utils import is_jsonable, parse_str_token, uuid_re
|
|
10
|
-
from jaseci.prim.element import Element
|
|
11
|
-
from jaseci.prim.node import Node
|
|
12
|
-
from jaseci.prim.edge import Edge
|
|
13
|
-
from jaseci.jac.jac_set import JacSet
|
|
14
|
-
from jaseci.jac.ir.jac_code import jac_ast_to_ir, jac_ir_to_ast
|
|
15
|
-
from jaseci.jac.machine.jac_scope import JacScope
|
|
16
|
-
from jaseci.jac.jsci_vm.machine import VirtualMachine
|
|
17
|
-
from jaseci.jac.machine.machine_state import TryException
|
|
18
|
-
|
|
19
|
-
from jaseci.jac.machine.jac_value import JacValue
|
|
20
|
-
from jaseci.jac.machine.jac_value import jac_elem_unwrap as jeu
|
|
21
|
-
from jaseci.jac.machine.jac_value import jac_wrap_value as jwv
|
|
22
|
-
from json import dumps, loads
|
|
23
|
-
from copy import copy, deepcopy
|
|
24
|
-
from base64 import b64decode
|
|
25
|
-
from itertools import pairwise
|
|
26
|
-
from types import GeneratorType
|
|
27
|
-
|
|
28
|
-
from jaseci.jac.jsci_vm.op_codes import JsCmp
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class Interp(VirtualMachine):
|
|
32
|
-
"""Shared interpreter class across both sentinels and walkers"""
|
|
33
|
-
|
|
34
|
-
def run_dotted_name(self, jac_ast):
|
|
35
|
-
"""
|
|
36
|
-
dotted_name: NAME (DOT NAME)*;
|
|
37
|
-
"""
|
|
38
|
-
kid = self.set_cur_ast(jac_ast)
|
|
39
|
-
ret = ""
|
|
40
|
-
for i in kid:
|
|
41
|
-
if i.name == "NAME":
|
|
42
|
-
ret += i.token_text()
|
|
43
|
-
if i == kid[-1]:
|
|
44
|
-
break
|
|
45
|
-
ret += "."
|
|
46
|
-
return ret
|
|
47
|
-
|
|
48
|
-
def run_name_list(self, jac_ast):
|
|
49
|
-
"""
|
|
50
|
-
name_list: NAME (COMMA NAME)*;
|
|
51
|
-
"""
|
|
52
|
-
kid = self.set_cur_ast(jac_ast)
|
|
53
|
-
ret = []
|
|
54
|
-
for i in kid:
|
|
55
|
-
if i.name == "NAME":
|
|
56
|
-
ret.append(i.token_text())
|
|
57
|
-
return ret
|
|
58
|
-
|
|
59
|
-
def run_param_list(self, jac_ast):
|
|
60
|
-
"""
|
|
61
|
-
param_list:
|
|
62
|
-
expr_list
|
|
63
|
-
| kw_expr_list
|
|
64
|
-
| expr_list COMMA kw_expr_list;
|
|
65
|
-
"""
|
|
66
|
-
kid = self.set_cur_ast(jac_ast)
|
|
67
|
-
ret = {"args": [], "kwargs": {}}
|
|
68
|
-
if kid[0].name == "expr_list":
|
|
69
|
-
ret["args"] = self.run_expr_list(kid[0]).value
|
|
70
|
-
elif kid[0].name == "kw_expr_list":
|
|
71
|
-
ret["kwargs"] = self.run_kw_expr_list(kid[0]).value
|
|
72
|
-
if len(kid) > 1:
|
|
73
|
-
ret["kwargs"] = self.run_kw_expr_list(kid[2]).value
|
|
74
|
-
return JacValue(self, value=ret)
|
|
75
|
-
|
|
76
|
-
def run_expr_list(self, jac_ast):
|
|
77
|
-
"""
|
|
78
|
-
expr_list: connect (COMMA connect)*;
|
|
79
|
-
"""
|
|
80
|
-
kid = self.set_cur_ast(jac_ast)
|
|
81
|
-
ret = []
|
|
82
|
-
for i in kid:
|
|
83
|
-
if i.name != "COMMA":
|
|
84
|
-
ret.append(self.run_rule(i).value)
|
|
85
|
-
return JacValue(self, value=ret)
|
|
86
|
-
|
|
87
|
-
def run_kw_expr_list(self, jac_ast):
|
|
88
|
-
"""
|
|
89
|
-
kw_expr_list: NAME EQ connect (COMMA NAME EQ connect)*;
|
|
90
|
-
"""
|
|
91
|
-
kid = self.set_cur_ast(jac_ast)
|
|
92
|
-
ret = {}
|
|
93
|
-
while len(kid):
|
|
94
|
-
ret[kid[0].token_text()] = self.run_rule(kid[2]).value
|
|
95
|
-
kid = kid[3:]
|
|
96
|
-
if len(kid):
|
|
97
|
-
kid = kid[1:]
|
|
98
|
-
return JacValue(self, value=ret)
|
|
99
|
-
|
|
100
|
-
def run_code_block(self, jac_ast):
|
|
101
|
-
"""
|
|
102
|
-
code_block: LBRACE statement* RBRACE | COLON statement;
|
|
103
|
-
"""
|
|
104
|
-
kid = self.set_cur_ast(jac_ast)
|
|
105
|
-
for i in kid:
|
|
106
|
-
if i.name == "statement" and not self._loop_ctrl:
|
|
107
|
-
self.run_statement(jac_ast=i)
|
|
108
|
-
|
|
109
|
-
def run_statement(self, jac_ast):
|
|
110
|
-
"""
|
|
111
|
-
statement:
|
|
112
|
-
code_block
|
|
113
|
-
| node_ctx_block
|
|
114
|
-
| expression SEMI
|
|
115
|
-
| if_stmt
|
|
116
|
-
| try_stmt
|
|
117
|
-
| for_stmt
|
|
118
|
-
| while_stmt
|
|
119
|
-
| assert_stmt SEMI
|
|
120
|
-
| ctrl_stmt SEMI
|
|
121
|
-
| destroy_action
|
|
122
|
-
| report_action
|
|
123
|
-
| walker_action;
|
|
124
|
-
"""
|
|
125
|
-
if self._stopped:
|
|
126
|
-
return
|
|
127
|
-
kid = self.set_cur_ast(jac_ast)
|
|
128
|
-
self.run_rule(kid[0])
|
|
129
|
-
|
|
130
|
-
def run_if_stmt(self, jac_ast):
|
|
131
|
-
"""
|
|
132
|
-
if_stmt: KW_IF expression code_block elif_stmt* else_stmt?;
|
|
133
|
-
"""
|
|
134
|
-
kid = self.set_cur_ast(jac_ast)
|
|
135
|
-
self.run_expression(kid[1])
|
|
136
|
-
if self.pop().value:
|
|
137
|
-
self.run_code_block(kid[2])
|
|
138
|
-
return
|
|
139
|
-
kid = kid[3:]
|
|
140
|
-
if len(kid):
|
|
141
|
-
while True:
|
|
142
|
-
if kid[0].name == "elif_stmt":
|
|
143
|
-
if self.run_elif_stmt(kid[0]):
|
|
144
|
-
return
|
|
145
|
-
elif kid[0].name == "else_stmt":
|
|
146
|
-
self.run_else_stmt(kid[0])
|
|
147
|
-
return
|
|
148
|
-
kid = kid[1:]
|
|
149
|
-
if not len(kid):
|
|
150
|
-
break
|
|
151
|
-
|
|
152
|
-
def run_try_stmt(self, jac_ast):
|
|
153
|
-
"""
|
|
154
|
-
try_stmt: KW_TRY code_block else_from_try?;
|
|
155
|
-
"""
|
|
156
|
-
kid = self.set_cur_ast(jac_ast)
|
|
157
|
-
self._jac_try_mode += 1
|
|
158
|
-
try:
|
|
159
|
-
self.run_code_block(kid[1])
|
|
160
|
-
self._jac_try_mode -= 1
|
|
161
|
-
except TryException as e:
|
|
162
|
-
self._jac_try_mode -= 1
|
|
163
|
-
if len(kid) > 2:
|
|
164
|
-
self.run_else_from_try(kid[2], e.ref)
|
|
165
|
-
except Exception as e:
|
|
166
|
-
self._jac_try_mode -= 1
|
|
167
|
-
if len(kid) > 2:
|
|
168
|
-
self.run_else_from_try(kid[2], self.jac_exception(e, kid[2]))
|
|
169
|
-
|
|
170
|
-
def run_else_from_try(self, jac_ast, jac_ex):
|
|
171
|
-
"""
|
|
172
|
-
else_from_try:
|
|
173
|
-
KW_ELSE (LPAREN NAME RPAREN)? code_block
|
|
174
|
-
| KW_ELSE (KW_WITH NAME)? code_block;
|
|
175
|
-
"""
|
|
176
|
-
kid = self.set_cur_ast(jac_ast)
|
|
177
|
-
if len(kid) > 2:
|
|
178
|
-
JacValue(
|
|
179
|
-
self,
|
|
180
|
-
ctx=self._jac_scope.local_scope,
|
|
181
|
-
name=kid[2].token_text(),
|
|
182
|
-
value=jac_ex,
|
|
183
|
-
).write(kid[2])
|
|
184
|
-
self.run_code_block(kid[-1])
|
|
185
|
-
|
|
186
|
-
def run_elif_stmt(self, jac_ast):
|
|
187
|
-
"""
|
|
188
|
-
elif_stmt: KW_ELIF expression code_block;
|
|
189
|
-
"""
|
|
190
|
-
kid = self.set_cur_ast(jac_ast)
|
|
191
|
-
self.run_expression(kid[1])
|
|
192
|
-
if self.pop().value:
|
|
193
|
-
self.run_code_block(kid[2])
|
|
194
|
-
return True
|
|
195
|
-
else:
|
|
196
|
-
return False
|
|
197
|
-
|
|
198
|
-
def run_else_stmt(self, jac_ast):
|
|
199
|
-
"""
|
|
200
|
-
else_stmt: KW_ELSE code_block;
|
|
201
|
-
"""
|
|
202
|
-
kid = self.set_cur_ast(jac_ast)
|
|
203
|
-
self.run_code_block(kid[1])
|
|
204
|
-
|
|
205
|
-
def run_for_stmt(self, jac_ast):
|
|
206
|
-
"""
|
|
207
|
-
for_stmt:
|
|
208
|
-
KW_FOR expression KW_TO expression KW_BY expression code_block
|
|
209
|
-
| KW_FOR NAME (COMMA NAME)? KW_IN expression code_block;
|
|
210
|
-
"""
|
|
211
|
-
kid = self.set_cur_ast(jac_ast)
|
|
212
|
-
loops = 0
|
|
213
|
-
if kid[1].name == "expression":
|
|
214
|
-
self.run_expression(kid[1])
|
|
215
|
-
self.pop()
|
|
216
|
-
self.run_expression(kid[3])
|
|
217
|
-
while self.pop().value:
|
|
218
|
-
self._loop_ctrl = None
|
|
219
|
-
self.run_code_block(kid[6])
|
|
220
|
-
self.run_expression(kid[5])
|
|
221
|
-
self.pop()
|
|
222
|
-
loops += 1
|
|
223
|
-
if self._loop_ctrl and self._loop_ctrl == "break":
|
|
224
|
-
self._loop_ctrl = None
|
|
225
|
-
break
|
|
226
|
-
if loops > self._loop_limit:
|
|
227
|
-
self.rt_error(f"Hit loop limit [{self._loop_limit}]!", kid[0])
|
|
228
|
-
self.run_expression(kid[3])
|
|
229
|
-
elif kid[3].name == "expression":
|
|
230
|
-
var = self._jac_scope.get_live_var(kid[1].token_text(), create_mode=True)
|
|
231
|
-
self.run_expression(kid[3])
|
|
232
|
-
lst = self.pop().value
|
|
233
|
-
|
|
234
|
-
if isinstance(lst, (list, dict, GeneratorType)):
|
|
235
|
-
for i in lst:
|
|
236
|
-
self._loop_ctrl = None
|
|
237
|
-
var.value = i
|
|
238
|
-
var.write(kid[1])
|
|
239
|
-
self.run_code_block(kid[4])
|
|
240
|
-
loops += 1
|
|
241
|
-
if self._loop_ctrl and self._loop_ctrl == "break":
|
|
242
|
-
self._loop_ctrl = None
|
|
243
|
-
break
|
|
244
|
-
if loops > self._loop_limit:
|
|
245
|
-
self.rt_error(f"Hit loop limit [{self._loop_limit}]!", kid[0])
|
|
246
|
-
else:
|
|
247
|
-
self.rt_error("Not a list/dict for iteration!", kid[3])
|
|
248
|
-
else:
|
|
249
|
-
key = self._jac_scope.get_live_var(kid[1].token_text(), create_mode=True)
|
|
250
|
-
val = self._jac_scope.get_live_var(kid[3].token_text(), create_mode=True)
|
|
251
|
-
self.run_expression(kid[5])
|
|
252
|
-
source = self.pop().value
|
|
253
|
-
|
|
254
|
-
lst = None
|
|
255
|
-
if isinstance(source, dict):
|
|
256
|
-
lst = source.items()
|
|
257
|
-
elif isinstance(source, list):
|
|
258
|
-
lst = enumerate(source)
|
|
259
|
-
|
|
260
|
-
if not (lst is None):
|
|
261
|
-
for k, v in lst:
|
|
262
|
-
self._loop_ctrl = None
|
|
263
|
-
key.value = k
|
|
264
|
-
key.write(kid[1])
|
|
265
|
-
val.value = v
|
|
266
|
-
val.write(kid[3])
|
|
267
|
-
self.run_code_block(kid[6])
|
|
268
|
-
loops += 1
|
|
269
|
-
if self._loop_ctrl and self._loop_ctrl == "break":
|
|
270
|
-
self._loop_ctrl = None
|
|
271
|
-
break
|
|
272
|
-
if loops > self._loop_limit:
|
|
273
|
-
self.rt_error(f"Hit loop limit [{self._loop_limit}]!", kid[0])
|
|
274
|
-
else:
|
|
275
|
-
self.rt_error("Not a list/dict for iteration!", kid[5])
|
|
276
|
-
if self._loop_ctrl and self._loop_ctrl == "continue":
|
|
277
|
-
self._loop_ctrl = None
|
|
278
|
-
|
|
279
|
-
def run_while_stmt(self, jac_ast):
|
|
280
|
-
"""
|
|
281
|
-
while_stmt: KW_WHILE expression code_block;
|
|
282
|
-
"""
|
|
283
|
-
kid = self.set_cur_ast(jac_ast)
|
|
284
|
-
loops = 0
|
|
285
|
-
self.run_expression(kid[1])
|
|
286
|
-
while self.pop().value:
|
|
287
|
-
self._loop_ctrl = None
|
|
288
|
-
self.run_code_block(kid[2])
|
|
289
|
-
loops += 1
|
|
290
|
-
if self._loop_ctrl and self._loop_ctrl == "break":
|
|
291
|
-
self._loop_ctrl = None
|
|
292
|
-
break
|
|
293
|
-
if loops > self._loop_limit:
|
|
294
|
-
self.rt_error(f"Hit loop limit [{self._loop_limit}]!", kid[0])
|
|
295
|
-
self.run_expression(kid[1])
|
|
296
|
-
if self._loop_ctrl and self._loop_ctrl == "continue":
|
|
297
|
-
self._loop_ctrl = None
|
|
298
|
-
|
|
299
|
-
def run_ctrl_stmt(self, jac_ast):
|
|
300
|
-
"""
|
|
301
|
-
ctrl_stmt: KW_CONTINUE | KW_BREAK | KW_SKIP;
|
|
302
|
-
"""
|
|
303
|
-
kid = self.set_cur_ast(jac_ast)
|
|
304
|
-
if kid[0].name == "KW_SKIP":
|
|
305
|
-
self._stopped = "skip"
|
|
306
|
-
elif kid[0].name == "KW_BREAK":
|
|
307
|
-
self._loop_ctrl = "break"
|
|
308
|
-
elif kid[0].name == "KW_CONTINUE":
|
|
309
|
-
self._loop_ctrl = "continue"
|
|
310
|
-
|
|
311
|
-
def run_assert_stmt(self, jac_ast):
|
|
312
|
-
"""
|
|
313
|
-
assert_stmt: KW_ASSERT expression;
|
|
314
|
-
"""
|
|
315
|
-
kid = self.set_cur_ast(jac_ast)
|
|
316
|
-
passed = False
|
|
317
|
-
try:
|
|
318
|
-
self.run_expression(kid[1])
|
|
319
|
-
passed = self.pop().value
|
|
320
|
-
except Exception as e:
|
|
321
|
-
e = self.jac_exception(e, jac_ast)
|
|
322
|
-
raise Exception("Jac Assert Failed", kid[1].get_text(), e)
|
|
323
|
-
if not passed:
|
|
324
|
-
raise Exception("Jac Assert Failed", kid[1].get_text())
|
|
325
|
-
|
|
326
|
-
def run_destroy_action(self, jac_ast):
|
|
327
|
-
"""
|
|
328
|
-
destroy_action: KW_DESTROY expression SEMI;
|
|
329
|
-
"""
|
|
330
|
-
from jaseci.prim.ability import Ability
|
|
331
|
-
|
|
332
|
-
kid = self.set_cur_ast(jac_ast)
|
|
333
|
-
self.run_expression(kid[1])
|
|
334
|
-
result = self.pop()
|
|
335
|
-
|
|
336
|
-
destroy_node_ids = None
|
|
337
|
-
if isinstance(self, Ability):
|
|
338
|
-
# currently, only walker process destroy_node_ids
|
|
339
|
-
# ability should be able to trigger destroy but still connected to current walker
|
|
340
|
-
destroy_node_ids = self._jac_scope.local_scope["visitor"].destroy_node_ids
|
|
341
|
-
else:
|
|
342
|
-
destroy_node_ids = self.destroy_node_ids
|
|
343
|
-
|
|
344
|
-
if isinstance(result.value, Element):
|
|
345
|
-
destroy_node_ids.add_obj(result.value)
|
|
346
|
-
elif isinstance(result.value, JacSet):
|
|
347
|
-
destroy_node_ids.add_obj_list(result.value)
|
|
348
|
-
result.self_destruct(kid[1])
|
|
349
|
-
|
|
350
|
-
def run_report_action(self, jac_ast):
|
|
351
|
-
"""
|
|
352
|
-
report_action:
|
|
353
|
-
KW_REPORT expression SEMI
|
|
354
|
-
| KW_REPORT COLON NAME EQ expression SEMI;
|
|
355
|
-
"""
|
|
356
|
-
kid = self.set_cur_ast(jac_ast)
|
|
357
|
-
if kid[1].name == "COLON":
|
|
358
|
-
self.run_expression(kid[4])
|
|
359
|
-
if kid[2].token_text() in ["status", "status_code"]:
|
|
360
|
-
self.report_status = self.pop().value
|
|
361
|
-
elif kid[2].token_text() == "custom":
|
|
362
|
-
self.report_custom = jwv(self.pop().value, serialize_mode=True)
|
|
363
|
-
elif kid[2].token_text() == "file":
|
|
364
|
-
self.report_file = self.pop().value
|
|
365
|
-
elif kid[2].token_text() == "error":
|
|
366
|
-
err = self.pop().value
|
|
367
|
-
if isinstance(err, str):
|
|
368
|
-
self.runtime_errors.append(err)
|
|
369
|
-
else:
|
|
370
|
-
self.runtime_errors.append(
|
|
371
|
-
f'{err["mod"]}:{err["name"]} - line {err["line"]}, '
|
|
372
|
-
+ f'col {err["col"]} - rule {err["rule"]} - {err["msg"]}'
|
|
373
|
-
)
|
|
374
|
-
for stk in err.get("stack_trace", []):
|
|
375
|
-
self.runtime_stack_trace.append(stk)
|
|
376
|
-
else:
|
|
377
|
-
self.rt_error("Invalid report attribute to set", kid[2])
|
|
378
|
-
else:
|
|
379
|
-
self.run_expression(kid[1])
|
|
380
|
-
report = jwv(self.pop().value, serialize_mode=True)
|
|
381
|
-
if not is_jsonable(report):
|
|
382
|
-
self.rt_error(f"Report {report} not Json serializable", kid[0])
|
|
383
|
-
self.report.append(copy(report))
|
|
384
|
-
|
|
385
|
-
def run_expression(self, jac_ast):
|
|
386
|
-
"""
|
|
387
|
-
expression: connect (assignment | copy_assign | inc_assign)?;
|
|
388
|
-
"""
|
|
389
|
-
try:
|
|
390
|
-
if self.attempt_bytecode(jac_ast):
|
|
391
|
-
return
|
|
392
|
-
kid = self.set_cur_ast(jac_ast)
|
|
393
|
-
if len(kid) == 1:
|
|
394
|
-
self.push(self.run_rule(kid[0]))
|
|
395
|
-
else:
|
|
396
|
-
if kid[1].name == "assignment":
|
|
397
|
-
self._assign_mode = True
|
|
398
|
-
dest = self.run_rule(kid[0])
|
|
399
|
-
self._assign_mode = False
|
|
400
|
-
self.run_assignment(kid[1])
|
|
401
|
-
self.perform_assignment(dest, self.pop(), kid[0])
|
|
402
|
-
elif kid[1].name == "copy_assign":
|
|
403
|
-
self._assign_mode = True
|
|
404
|
-
dest = self.run_rule(kid[0])
|
|
405
|
-
self._assign_mode = False
|
|
406
|
-
self.run_copy_assign(kid[1])
|
|
407
|
-
self.perform_copy_fields(dest, self.pop(), kid[0])
|
|
408
|
-
elif kid[1].name == "inc_assign":
|
|
409
|
-
self._assign_mode = True
|
|
410
|
-
dest = self.run_rule(kid[0])
|
|
411
|
-
self._assign_mode = False
|
|
412
|
-
self.run_inc_assign(kid[1])
|
|
413
|
-
self.perform_increment(
|
|
414
|
-
dest, self.pop(), JsCmp[kid[1].kid[0].name], kid[0]
|
|
415
|
-
)
|
|
416
|
-
except Exception as e:
|
|
417
|
-
self.rt_error(e, jac_ast)
|
|
418
|
-
|
|
419
|
-
def run_assignment(self, jac_ast):
|
|
420
|
-
"""
|
|
421
|
-
assignment: EQ expression;
|
|
422
|
-
"""
|
|
423
|
-
if self.attempt_bytecode(jac_ast):
|
|
424
|
-
return
|
|
425
|
-
kid = self.set_cur_ast(jac_ast)
|
|
426
|
-
self.run_expression(kid[1])
|
|
427
|
-
|
|
428
|
-
def run_copy_assign(self, jac_ast):
|
|
429
|
-
"""
|
|
430
|
-
copy_assign: CPY_EQ expression;
|
|
431
|
-
"""
|
|
432
|
-
if self.attempt_bytecode(jac_ast):
|
|
433
|
-
return
|
|
434
|
-
kid = self.set_cur_ast(jac_ast)
|
|
435
|
-
self.run_expression(kid[1])
|
|
436
|
-
|
|
437
|
-
def run_inc_assign(self, jac_ast):
|
|
438
|
-
"""
|
|
439
|
-
inc_assign: (PEQ | MEQ | TEQ | DEQ) expression;
|
|
440
|
-
"""
|
|
441
|
-
if self.attempt_bytecode(jac_ast):
|
|
442
|
-
return
|
|
443
|
-
kid = self.set_cur_ast(jac_ast)
|
|
444
|
-
self.run_expression(kid[1])
|
|
445
|
-
|
|
446
|
-
def run_connect(self, jac_ast):
|
|
447
|
-
"""
|
|
448
|
-
connect: logical ( (NOT edge_ref | connect_op) expression)?;
|
|
449
|
-
"""
|
|
450
|
-
kid = self.set_cur_ast(jac_ast)
|
|
451
|
-
if len(kid) < 2:
|
|
452
|
-
return self.run_rule(kid[0])
|
|
453
|
-
bret = self.run_rule(kid[0])
|
|
454
|
-
base = bret.value
|
|
455
|
-
self.run_expression(kid[-1])
|
|
456
|
-
tret = self.pop()
|
|
457
|
-
target = tret.value
|
|
458
|
-
self.rt_check_type(base, [Node, JacSet], kid[0])
|
|
459
|
-
self.rt_check_type(target, [Node, JacSet], kid[-1])
|
|
460
|
-
if isinstance(base, Node):
|
|
461
|
-
base = JacSet(in_list=[base])
|
|
462
|
-
if isinstance(target, Node):
|
|
463
|
-
target = JacSet(in_list=[target])
|
|
464
|
-
if kid[1].name == "NOT":
|
|
465
|
-
for i in target.obj_list():
|
|
466
|
-
for j in base.obj_list():
|
|
467
|
-
j.detach_edges(i, self.run_edge_ref(kid[2]).obj_list())
|
|
468
|
-
return bret
|
|
469
|
-
else:
|
|
470
|
-
direction = kid[1].kid[0].name
|
|
471
|
-
for i in target.obj_list():
|
|
472
|
-
for j in base.obj_list():
|
|
473
|
-
use_edge = self.run_connect_op(kid[1])
|
|
474
|
-
self.rt_check_type(i, Node, kid[-1])
|
|
475
|
-
self.rt_check_type(j, Node, kid[-1])
|
|
476
|
-
if direction == "connect_from":
|
|
477
|
-
j.attach_inbound(i, [use_edge])
|
|
478
|
-
elif direction == "connect_to":
|
|
479
|
-
j.attach_outbound(i, [use_edge])
|
|
480
|
-
else:
|
|
481
|
-
j.attach_bidirected(i, [use_edge])
|
|
482
|
-
return bret
|
|
483
|
-
|
|
484
|
-
def run_logical(self, jac_ast):
|
|
485
|
-
"""
|
|
486
|
-
logical: compare ((KW_AND | KW_OR) compare)*;
|
|
487
|
-
"""
|
|
488
|
-
if self.attempt_bytecode(jac_ast):
|
|
489
|
-
return
|
|
490
|
-
kid = self.set_cur_ast(jac_ast)
|
|
491
|
-
result = self.run_rule(kid[0])
|
|
492
|
-
kid = kid[1:]
|
|
493
|
-
while kid:
|
|
494
|
-
if kid[0].name == "KW_AND":
|
|
495
|
-
if result.value:
|
|
496
|
-
result.value = result.value and self.run_rule(kid[1]).value
|
|
497
|
-
elif kid[0].name == "KW_OR":
|
|
498
|
-
if not result.value:
|
|
499
|
-
result.value = result.value or self.run_rule(kid[1]).value
|
|
500
|
-
kid = kid[2:]
|
|
501
|
-
if not kid:
|
|
502
|
-
break
|
|
503
|
-
self.push(result)
|
|
504
|
-
|
|
505
|
-
def run_compare(self, jac_ast):
|
|
506
|
-
"""
|
|
507
|
-
compare: NOT compare | arithmetic (cmp_op arithmetic)*;
|
|
508
|
-
"""
|
|
509
|
-
if self.attempt_bytecode(jac_ast):
|
|
510
|
-
return
|
|
511
|
-
kid = self.set_cur_ast(jac_ast)
|
|
512
|
-
if kid[0].name == "NOT":
|
|
513
|
-
self.push(JacValue(self, value=not self.run_rule(kid[1]).value))
|
|
514
|
-
else:
|
|
515
|
-
result = self.run_rule(kid[0])
|
|
516
|
-
kid = kid[1:]
|
|
517
|
-
while kid:
|
|
518
|
-
other_res = self.run_rule(kid[1])
|
|
519
|
-
self.run_cmp_op(kid[0], result, other_res)
|
|
520
|
-
result = self.pop()
|
|
521
|
-
kid = kid[2:]
|
|
522
|
-
if not kid:
|
|
523
|
-
break
|
|
524
|
-
self.push(result)
|
|
525
|
-
|
|
526
|
-
def run_cmp_op(self, jac_ast, val1, val2):
|
|
527
|
-
"""
|
|
528
|
-
cmp_op: EE | LT | GT | LTE | GTE | NE | KW_IN | nin;
|
|
529
|
-
"""
|
|
530
|
-
kid = self.set_cur_ast(jac_ast)
|
|
531
|
-
if kid[0].name == "EE":
|
|
532
|
-
self.push(JacValue(self, value=val1.value == val2.value))
|
|
533
|
-
elif kid[0].name == "LT":
|
|
534
|
-
self.push(JacValue(self, value=val1.value < val2.value))
|
|
535
|
-
elif kid[0].name == "GT":
|
|
536
|
-
self.push(JacValue(self, value=val1.value > val2.value))
|
|
537
|
-
elif kid[0].name == "LTE":
|
|
538
|
-
self.push(JacValue(self, value=val1.value <= val2.value))
|
|
539
|
-
elif kid[0].name == "GTE":
|
|
540
|
-
self.push(JacValue(self, value=val1.value >= val2.value))
|
|
541
|
-
elif kid[0].name == "NE":
|
|
542
|
-
self.push(JacValue(self, value=val1.value != val2.value))
|
|
543
|
-
elif kid[0].name == "KW_IN":
|
|
544
|
-
self.push(JacValue(self, value=val1.value in val2.value))
|
|
545
|
-
elif kid[0].name == "nin":
|
|
546
|
-
self.push(JacValue(self, value=val1.value not in val2.value))
|
|
547
|
-
|
|
548
|
-
def run_arithmetic(self, jac_ast):
|
|
549
|
-
"""
|
|
550
|
-
arithmetic: term ((PLUS | MINUS) term)*;
|
|
551
|
-
"""
|
|
552
|
-
if self.attempt_bytecode(jac_ast):
|
|
553
|
-
return
|
|
554
|
-
kid = self.set_cur_ast(jac_ast)
|
|
555
|
-
result = self.run_rule(kid[0])
|
|
556
|
-
kid = kid[1:]
|
|
557
|
-
while kid:
|
|
558
|
-
other_res = self.run_rule(kid[1])
|
|
559
|
-
if kid[0].name == "PLUS":
|
|
560
|
-
result.value = result.value + other_res.value
|
|
561
|
-
elif kid[0].name == "MINUS":
|
|
562
|
-
result.value = result.value - other_res.value
|
|
563
|
-
kid = kid[2:]
|
|
564
|
-
if not kid:
|
|
565
|
-
break
|
|
566
|
-
self.push(result)
|
|
567
|
-
|
|
568
|
-
def run_term(self, jac_ast):
|
|
569
|
-
"""
|
|
570
|
-
term: factor ((STAR_MUL | DIV | MOD) factor)*;
|
|
571
|
-
"""
|
|
572
|
-
if self.attempt_bytecode(jac_ast):
|
|
573
|
-
return
|
|
574
|
-
kid = self.set_cur_ast(jac_ast)
|
|
575
|
-
result = self.run_rule(kid[0])
|
|
576
|
-
kid = kid[1:]
|
|
577
|
-
while kid:
|
|
578
|
-
other_res = self.run_rule(kid[1])
|
|
579
|
-
if kid[0].name == "STAR_MUL":
|
|
580
|
-
result.value = result.value * other_res.value
|
|
581
|
-
elif kid[0].name == "DIV":
|
|
582
|
-
result.value = result.value / other_res.value
|
|
583
|
-
elif kid[0].name == "MOD":
|
|
584
|
-
result.value = result.value % other_res.value
|
|
585
|
-
kid = kid[2:]
|
|
586
|
-
if not kid:
|
|
587
|
-
break
|
|
588
|
-
self.push(result)
|
|
589
|
-
|
|
590
|
-
def run_factor(self, jac_ast):
|
|
591
|
-
"""
|
|
592
|
-
factor: (PLUS | MINUS) factor | power;
|
|
593
|
-
"""
|
|
594
|
-
if self.attempt_bytecode(jac_ast):
|
|
595
|
-
return
|
|
596
|
-
kid = self.set_cur_ast(jac_ast)
|
|
597
|
-
if len(kid) < 2:
|
|
598
|
-
self.push(self.run_rule(kid[0]))
|
|
599
|
-
else:
|
|
600
|
-
result = self.run_rule(kid[1])
|
|
601
|
-
if kid[0].name == "MINUS":
|
|
602
|
-
result.value = -(result.value)
|
|
603
|
-
self.push(result)
|
|
604
|
-
|
|
605
|
-
def run_power(self, jac_ast):
|
|
606
|
-
"""
|
|
607
|
-
power: atom (POW factor)*;
|
|
608
|
-
"""
|
|
609
|
-
if self.attempt_bytecode(jac_ast):
|
|
610
|
-
return
|
|
611
|
-
kid = self.set_cur_ast(jac_ast)
|
|
612
|
-
result = self.run_rule(kid[0])
|
|
613
|
-
kid = kid[1:]
|
|
614
|
-
if len(kid) < 1:
|
|
615
|
-
self.push(result)
|
|
616
|
-
elif kid[0].name == "POW":
|
|
617
|
-
while kid:
|
|
618
|
-
result.value = result.value ** self.run_rule(kid[1]).value
|
|
619
|
-
kid = kid[2:]
|
|
620
|
-
if not kid:
|
|
621
|
-
break
|
|
622
|
-
self.push(result)
|
|
623
|
-
|
|
624
|
-
def run_global_ref(self, jac_ast):
|
|
625
|
-
"""
|
|
626
|
-
global_ref: KW_GLOBAL DOT (obj_built_in | NAME);
|
|
627
|
-
"""
|
|
628
|
-
try:
|
|
629
|
-
kid = self.set_cur_ast(jac_ast)
|
|
630
|
-
if kid[2].name == "obj_built_in":
|
|
631
|
-
kid = self.set_cur_ast(kid[2])
|
|
632
|
-
if kid[0].name == "KW_CONTEXT":
|
|
633
|
-
return JacValue(self, value=self.parent().global_vars)
|
|
634
|
-
elif kid[0].name == "KW_INFO":
|
|
635
|
-
# Add additional accessible fields
|
|
636
|
-
return JacValue(self, value=self.get_info())
|
|
637
|
-
else:
|
|
638
|
-
self.rt_error(f"Global {kid[0].name} is not supported!", jac_ast)
|
|
639
|
-
else:
|
|
640
|
-
token = kid[2].token_text()
|
|
641
|
-
if token not in self.parent().global_vars:
|
|
642
|
-
self.rt_error(f"Global not defined - {token}", kid[2])
|
|
643
|
-
|
|
644
|
-
return JacValue(self, ctx=self.parent().global_vars, name=token)
|
|
645
|
-
|
|
646
|
-
except Exception as e:
|
|
647
|
-
self.rt_error(e, jac_ast)
|
|
648
|
-
|
|
649
|
-
def run_atom(self, jac_ast):
|
|
650
|
-
"""
|
|
651
|
-
atom:
|
|
652
|
-
INT
|
|
653
|
-
| FLOAT
|
|
654
|
-
| multistring
|
|
655
|
-
| BOOL
|
|
656
|
-
| NULL
|
|
657
|
-
| NAME
|
|
658
|
-
| global_ref
|
|
659
|
-
| node_edge_ref
|
|
660
|
-
| list_val
|
|
661
|
-
| dict_val
|
|
662
|
-
| LPAREN expression RPAREN
|
|
663
|
-
| ability_op NAME spawn_ctx?
|
|
664
|
-
| atom atom_trailer
|
|
665
|
-
| KW_SYNC atom
|
|
666
|
-
| spawn
|
|
667
|
-
| ref
|
|
668
|
-
| deref
|
|
669
|
-
| any_type;
|
|
670
|
-
"""
|
|
671
|
-
try:
|
|
672
|
-
if self.attempt_bytecode(jac_ast):
|
|
673
|
-
return
|
|
674
|
-
kid = self.set_cur_ast(jac_ast)
|
|
675
|
-
if kid[0].name == "INT":
|
|
676
|
-
self.push(JacValue(self, value=int(kid[0].token_text())))
|
|
677
|
-
elif kid[0].name == "FLOAT":
|
|
678
|
-
self.push(JacValue(self, value=float(kid[0].token_text())))
|
|
679
|
-
elif kid[0].name == "multistring":
|
|
680
|
-
self.run_multistring(kid[0])
|
|
681
|
-
elif kid[0].name == "BOOL":
|
|
682
|
-
self.push(JacValue(self, value=bool(kid[0].token_text() == "true")))
|
|
683
|
-
elif kid[0].name == "NULL":
|
|
684
|
-
self.push(JacValue(self, value=None))
|
|
685
|
-
elif kid[0].name == "NAME":
|
|
686
|
-
self.load_variable(kid[0].token_text(), kid[0])
|
|
687
|
-
elif kid[0].name == "LPAREN":
|
|
688
|
-
self.run_expression(kid[1])
|
|
689
|
-
elif kid[0].name == "ability_op":
|
|
690
|
-
self.push(
|
|
691
|
-
self.run_ability_call(
|
|
692
|
-
jac_ast, atom_res=JacValue(self, value=self._jac_scope.has_obj)
|
|
693
|
-
)
|
|
694
|
-
)
|
|
695
|
-
elif kid[0].name == "atom":
|
|
696
|
-
self.run_atom(kid[0])
|
|
697
|
-
ret = self.pop()
|
|
698
|
-
for i in kid[1:]:
|
|
699
|
-
ret = self.run_atom_trailer(i, ret)
|
|
700
|
-
self.push(ret)
|
|
701
|
-
elif kid[0].name == "KW_SYNC":
|
|
702
|
-
self.run_atom(kid[1])
|
|
703
|
-
val = self.pop()
|
|
704
|
-
self.push(
|
|
705
|
-
JacValue(
|
|
706
|
-
self,
|
|
707
|
-
value=(
|
|
708
|
-
JsOrc.svc("task")
|
|
709
|
-
.poke(TaskService)
|
|
710
|
-
.get_by_task_id(val.value["result"], True)
|
|
711
|
-
),
|
|
712
|
-
)
|
|
713
|
-
)
|
|
714
|
-
else:
|
|
715
|
-
self.push(self.run_rule(kid[0]))
|
|
716
|
-
|
|
717
|
-
except Exception as e:
|
|
718
|
-
self.rt_error(e, jac_ast)
|
|
719
|
-
|
|
720
|
-
def run_atom_trailer(self, jac_ast, atom_res):
|
|
721
|
-
"""
|
|
722
|
-
atom_trailer:
|
|
723
|
-
DOT built_in
|
|
724
|
-
| DOT NAME
|
|
725
|
-
| index_slice
|
|
726
|
-
| ability_call;
|
|
727
|
-
"""
|
|
728
|
-
try:
|
|
729
|
-
kid = self.set_cur_ast(jac_ast)
|
|
730
|
-
if isinstance(atom_res.value, Element):
|
|
731
|
-
self._write_candidate = atom_res.value
|
|
732
|
-
if kid[0].name == "DOT":
|
|
733
|
-
if kid[1].name == "built_in":
|
|
734
|
-
return self.run_built_in(kid[1], atom_res)
|
|
735
|
-
elif kid[1].name == "NAME":
|
|
736
|
-
d = atom_res.value
|
|
737
|
-
n = kid[1].token_text()
|
|
738
|
-
if self.rt_check_type(d, [dict, Element, JacSet], kid[0]):
|
|
739
|
-
if isinstance(d, Element):
|
|
740
|
-
self._write_candidate = d
|
|
741
|
-
if not isinstance(d, JacSet):
|
|
742
|
-
ret = JacValue(self, ctx=d, name=n)
|
|
743
|
-
else:
|
|
744
|
-
plucked = []
|
|
745
|
-
for i in d:
|
|
746
|
-
if n in i.context.keys():
|
|
747
|
-
plucked.append(i.context[n])
|
|
748
|
-
else:
|
|
749
|
-
self.rt_error(
|
|
750
|
-
f"Some elements in set does not have {n}",
|
|
751
|
-
kid[1],
|
|
752
|
-
)
|
|
753
|
-
ret = JacValue(self, value=plucked)
|
|
754
|
-
return ret
|
|
755
|
-
else:
|
|
756
|
-
self.rt_error(f"Invalid variable {n}", kid[0])
|
|
757
|
-
elif kid[0].name == "index_slice":
|
|
758
|
-
if not self.rt_check_type(atom_res.value, [list, str, dict], kid[0]):
|
|
759
|
-
return atom_res
|
|
760
|
-
return self.run_index_slice(kid[0], atom_res)
|
|
761
|
-
elif kid[0].name == "ability_call":
|
|
762
|
-
return self.run_ability_call(kid[0], atom_res)
|
|
763
|
-
except Exception as e:
|
|
764
|
-
self.rt_error(e, jac_ast)
|
|
765
|
-
|
|
766
|
-
def run_ability_call(self, jac_ast, atom_res):
|
|
767
|
-
"""
|
|
768
|
-
ability_call:
|
|
769
|
-
LPAREN param_list? RPAREN
|
|
770
|
-
| ability_op NAME spawn_ctx?;
|
|
771
|
-
"""
|
|
772
|
-
from jaseci.prim.ability import Ability
|
|
773
|
-
|
|
774
|
-
kid = self.set_cur_ast(jac_ast)
|
|
775
|
-
if kid[0].name == "LPAREN":
|
|
776
|
-
param_list = {"args": [], "kwargs": {}}
|
|
777
|
-
if kid[1].name == "param_list":
|
|
778
|
-
param_list = self.run_param_list(kid[1]).value
|
|
779
|
-
if isinstance(atom_res.value, Ability):
|
|
780
|
-
ret = atom_res.value.run_action(
|
|
781
|
-
param_list, self._jac_scope, self, jac_ast
|
|
782
|
-
)
|
|
783
|
-
return JacValue(self, value=ret)
|
|
784
|
-
else:
|
|
785
|
-
self.rt_error("Unable to execute ability", kid[0])
|
|
786
|
-
elif kid[0].name == "ability_op":
|
|
787
|
-
arch = self.run_ability_op(kid[0], atom_res)
|
|
788
|
-
if len(kid) > 2:
|
|
789
|
-
self.run_spawn_ctx(kid[2], atom_res.value)
|
|
790
|
-
self.call_ability(
|
|
791
|
-
nd=atom_res.value,
|
|
792
|
-
name=kid[1].token_text(),
|
|
793
|
-
act_list=arch.get_all_abilities(),
|
|
794
|
-
)
|
|
795
|
-
return atom_res
|
|
796
|
-
|
|
797
|
-
def run_ability_op(self, jac_ast, atom_res):
|
|
798
|
-
"""
|
|
799
|
-
ability_op: DBL_COLON | DBL_COLON NAME COLON;
|
|
800
|
-
"""
|
|
801
|
-
kid = self.set_cur_ast(jac_ast)
|
|
802
|
-
base_arch = atom_res.value.get_architype()
|
|
803
|
-
if len(kid) > 1:
|
|
804
|
-
kind = atom_res.value.kind
|
|
805
|
-
name = kid[1].token_text()
|
|
806
|
-
if name in base_arch.derived_types():
|
|
807
|
-
return self.parent().arch_ids.get_obj_by_name(name=name, kind=kind)
|
|
808
|
-
else:
|
|
809
|
-
self.rt_error(f"{name} is not a super arch of {base_arch.name}", kid[1])
|
|
810
|
-
else:
|
|
811
|
-
return base_arch
|
|
812
|
-
|
|
813
|
-
def run_ref(self, jac_ast):
|
|
814
|
-
"""
|
|
815
|
-
ref: '&' atom;
|
|
816
|
-
"""
|
|
817
|
-
kid = self.set_cur_ast(jac_ast)
|
|
818
|
-
self.run_atom(kid[1])
|
|
819
|
-
result = self.pop()
|
|
820
|
-
if self.rt_check_type(result.value, Element, kid[1]):
|
|
821
|
-
result = JacValue(self, value=result.value.jid)
|
|
822
|
-
return result
|
|
823
|
-
|
|
824
|
-
def run_deref(self, jac_ast):
|
|
825
|
-
"""
|
|
826
|
-
deref: '*' atom;
|
|
827
|
-
"""
|
|
828
|
-
kid = self.set_cur_ast(jac_ast)
|
|
829
|
-
self.run_atom(kid[1])
|
|
830
|
-
result = self.pop()
|
|
831
|
-
|
|
832
|
-
if (
|
|
833
|
-
isinstance(result.value, str)
|
|
834
|
-
and len(result.value) < 64 # super long string, untrustworthy
|
|
835
|
-
and not result.value.startswith("jac:uuid:") # already an object
|
|
836
|
-
):
|
|
837
|
-
matcher = uuid_re.search(result.value)
|
|
838
|
-
if matcher and matcher.group(1):
|
|
839
|
-
nd = jeu(f"jac:uuid:{matcher.group(1)}", self)
|
|
840
|
-
if nd is not None:
|
|
841
|
-
return JacValue(self, value=nd)
|
|
842
|
-
|
|
843
|
-
self.rt_error(f"{result.value} not valid reference", kid[1])
|
|
844
|
-
|
|
845
|
-
def run_built_in(self, jac_ast, atom_res):
|
|
846
|
-
"""
|
|
847
|
-
built_in:
|
|
848
|
-
cast_built_in
|
|
849
|
-
| obj_built_in
|
|
850
|
-
| dict_built_in
|
|
851
|
-
| list_built_in
|
|
852
|
-
| string_built_in;
|
|
853
|
-
"""
|
|
854
|
-
return self.run_rule(jac_ast.kid[0], atom_res)
|
|
855
|
-
|
|
856
|
-
def run_cast_built_in(self, jac_ast, atom_res):
|
|
857
|
-
"""
|
|
858
|
-
arch_built_in: any_type;
|
|
859
|
-
"""
|
|
860
|
-
kid = self.set_cur_ast(jac_ast)
|
|
861
|
-
self.run_any_type(kid[0])
|
|
862
|
-
typ = self.pop()
|
|
863
|
-
if typ.value == Edge:
|
|
864
|
-
if isinstance(atom_res.value, Node):
|
|
865
|
-
return JacValue(
|
|
866
|
-
self,
|
|
867
|
-
value=self.obj_set_to_jac_set(
|
|
868
|
-
self.here().attached_edges(atom_res.value)
|
|
869
|
-
),
|
|
870
|
-
)
|
|
871
|
-
elif isinstance(atom_res.value, Edge):
|
|
872
|
-
return atom_res
|
|
873
|
-
elif isinstance(atom_res.value, JacSet):
|
|
874
|
-
return JacValue(self, value=self._relevant_edges)
|
|
875
|
-
else:
|
|
876
|
-
self.rt_error(
|
|
877
|
-
f"Cannot get edges from {atom_res.value}. "
|
|
878
|
-
f"Type {atom_res.jac_type()} invalid",
|
|
879
|
-
kid[0],
|
|
880
|
-
)
|
|
881
|
-
# may want to remove 'here" node from return below
|
|
882
|
-
elif typ.value == Node:
|
|
883
|
-
if isinstance(atom_res.value, Node):
|
|
884
|
-
return atom_res
|
|
885
|
-
elif isinstance(atom_res.value, Edge):
|
|
886
|
-
return JacValue(
|
|
887
|
-
self, value=self.obj_set_to_jac_set(atom_res.value.nodes())
|
|
888
|
-
)
|
|
889
|
-
elif isinstance(atom_res.value, JacSet):
|
|
890
|
-
res = JacSet()
|
|
891
|
-
for i in atom_res.value.obj_list():
|
|
892
|
-
if isinstance(i, Edge):
|
|
893
|
-
res.add_obj(i.to_node())
|
|
894
|
-
res.add_obj(i.from_node())
|
|
895
|
-
elif isinstance(i, Node):
|
|
896
|
-
res.add_obj(i)
|
|
897
|
-
return JacValue(self, value=res)
|
|
898
|
-
else:
|
|
899
|
-
self.rt_error(
|
|
900
|
-
f"Cannot get nodes from {atom_res}. "
|
|
901
|
-
f"Type {atom_res.jac_type()} invalid",
|
|
902
|
-
kid[0],
|
|
903
|
-
)
|
|
904
|
-
else:
|
|
905
|
-
try:
|
|
906
|
-
if isinstance(atom_res.value, str) and typ.value == dict:
|
|
907
|
-
atom_res.value = loads(atom_res.value)
|
|
908
|
-
elif isinstance(atom_res.value, dict) and typ.value == str:
|
|
909
|
-
atom_res.value = dumps(atom_res.value)
|
|
910
|
-
else:
|
|
911
|
-
atom_res.value = typ.value(atom_res.value)
|
|
912
|
-
except Exception as e:
|
|
913
|
-
self.rt_error(
|
|
914
|
-
f"Invalid cast of {atom_res.jac_type()} "
|
|
915
|
-
f"to {jwv(typ.value)}: {e}",
|
|
916
|
-
kid[0],
|
|
917
|
-
)
|
|
918
|
-
return atom_res
|
|
919
|
-
|
|
920
|
-
return atom_res
|
|
921
|
-
|
|
922
|
-
def run_obj_built_in(self, jac_ast, atom_res):
|
|
923
|
-
"""
|
|
924
|
-
obj_built_in: KW_CONTEXT | KW_INFO | KW_DETAILS;
|
|
925
|
-
"""
|
|
926
|
-
kid = self.set_cur_ast(jac_ast)
|
|
927
|
-
from jaseci.prim.walker import Walker
|
|
928
|
-
|
|
929
|
-
if kid[0].name == "KW_CONTEXT":
|
|
930
|
-
if self.rt_check_type(atom_res.value, [Node, Edge, Walker], kid[0]):
|
|
931
|
-
return JacValue(self, ctx=atom_res.value, value=atom_res.value.context)
|
|
932
|
-
elif kid[0].name == "KW_INFO":
|
|
933
|
-
if self.rt_check_type(atom_res.value, [Node, Edge, Walker], kid[0]):
|
|
934
|
-
return JacValue(
|
|
935
|
-
self,
|
|
936
|
-
ctx=atom_res.value,
|
|
937
|
-
value=atom_res.value.serialize(detailed=False),
|
|
938
|
-
)
|
|
939
|
-
elif kid[0].name == "KW_DETAILS":
|
|
940
|
-
if self.rt_check_type(atom_res.value, [Node, Edge, Walker], kid[0]):
|
|
941
|
-
return JacValue(
|
|
942
|
-
self,
|
|
943
|
-
ctx=atom_res.value,
|
|
944
|
-
value=atom_res.value.serialize(detailed=True),
|
|
945
|
-
)
|
|
946
|
-
return atom_res
|
|
947
|
-
|
|
948
|
-
def run_dict_built_in(self, jac_ast, atom_res):
|
|
949
|
-
"""
|
|
950
|
-
dict_built_in:
|
|
951
|
-
KW_KEYS
|
|
952
|
-
| LBRACE name_list RBRACE
|
|
953
|
-
| (TYP_DICT DBL_COLON | DICT_DBL_COLON) NAME (
|
|
954
|
-
LPAREN expr_list RPAREN
|
|
955
|
-
)?;
|
|
956
|
-
"""
|
|
957
|
-
kid = self.set_cur_ast(jac_ast)
|
|
958
|
-
if kid[0].name == "KW_KEYS":
|
|
959
|
-
if isinstance(atom_res.value, dict):
|
|
960
|
-
return JacValue(self, value=list(atom_res.value.keys()))
|
|
961
|
-
else:
|
|
962
|
-
self.rt_error(
|
|
963
|
-
f"Cannot get keys of {atom_res}. " f"Not Dictionary!", kid[0]
|
|
964
|
-
)
|
|
965
|
-
elif len(kid) > 1 and kid[1].name == "name_list":
|
|
966
|
-
filter_on = self.run_name_list(kid[1])
|
|
967
|
-
d = atom_res.value
|
|
968
|
-
if self.rt_check_type(d, [dict], kid[0]):
|
|
969
|
-
d = {k: d[k] for k in d if k in filter_on}
|
|
970
|
-
return JacValue(self, value=d)
|
|
971
|
-
else:
|
|
972
|
-
if not self.rt_check_type(atom_res.value, [dict], kid[0]):
|
|
973
|
-
return atom_res
|
|
974
|
-
kid = kid[1:]
|
|
975
|
-
if kid[0].name == "DBL_COLON":
|
|
976
|
-
kid = kid[1:]
|
|
977
|
-
result = None
|
|
978
|
-
op = kid[0].token_text()
|
|
979
|
-
try:
|
|
980
|
-
if op == "items":
|
|
981
|
-
result = JacValue(
|
|
982
|
-
self, value=list(map(list, atom_res.value.items()))
|
|
983
|
-
)
|
|
984
|
-
elif op == "copy":
|
|
985
|
-
result = JacValue(self, value=atom_res.value.copy())
|
|
986
|
-
elif op == "deepcopy":
|
|
987
|
-
result = JacValue(self, value=deepcopy(atom_res.value))
|
|
988
|
-
elif op == "keys":
|
|
989
|
-
result = JacValue(self, value=list(atom_res.value.keys()))
|
|
990
|
-
elif op == "clear":
|
|
991
|
-
result = JacValue(self, value=atom_res.value.clear())
|
|
992
|
-
self.candidate_writethrough()
|
|
993
|
-
elif op == "popitem":
|
|
994
|
-
result = JacValue(self, value=list(atom_res.value.popitem()))
|
|
995
|
-
self.candidate_writethrough()
|
|
996
|
-
elif op == "values":
|
|
997
|
-
result = JacValue(self, value=list(atom_res.value.values()))
|
|
998
|
-
if result:
|
|
999
|
-
if len(kid) > 1:
|
|
1000
|
-
self.rt_warn(f"{op} does not take parameters, ignoring", kid[2])
|
|
1001
|
-
return result
|
|
1002
|
-
if len(kid) > 1:
|
|
1003
|
-
args = self.run_expr_list(kid[2]).value
|
|
1004
|
-
if op == "pop":
|
|
1005
|
-
result = JacValue(self, value=atom_res.value.pop(*args))
|
|
1006
|
-
self.candidate_writethrough()
|
|
1007
|
-
elif op == "update":
|
|
1008
|
-
result = JacValue(self, value=atom_res.value.update(*args))
|
|
1009
|
-
self.candidate_writethrough()
|
|
1010
|
-
elif op == "get":
|
|
1011
|
-
result = JacValue(self, value=atom_res.value.get(*args))
|
|
1012
|
-
if result:
|
|
1013
|
-
return result
|
|
1014
|
-
except Exception as e:
|
|
1015
|
-
self.rt_error(e, jac_ast)
|
|
1016
|
-
self.rt_error(f"Call to {op} is invalid.", jac_ast)
|
|
1017
|
-
|
|
1018
|
-
return atom_res
|
|
1019
|
-
|
|
1020
|
-
def run_list_built_in(self, jac_ast, atom_res):
|
|
1021
|
-
"""
|
|
1022
|
-
list_built_in:
|
|
1023
|
-
KW_LENGTH
|
|
1024
|
-
| (TYP_LIST DBL_COLON | LIST_DBL_COLON) NAME (
|
|
1025
|
-
LPAREN expr_list RPAREN
|
|
1026
|
-
)?;
|
|
1027
|
-
"""
|
|
1028
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1029
|
-
if kid[0].name == "KW_LENGTH":
|
|
1030
|
-
if isinstance(atom_res.value, list):
|
|
1031
|
-
return JacValue(self, value=len(atom_res.value))
|
|
1032
|
-
else:
|
|
1033
|
-
self.rt_error(
|
|
1034
|
-
f"Cannot get length of {atom_res.value}. Not List!", kid[0]
|
|
1035
|
-
)
|
|
1036
|
-
else:
|
|
1037
|
-
if not self.rt_check_type(atom_res.value, [list], kid[0]):
|
|
1038
|
-
return atom_res
|
|
1039
|
-
kid = kid[1:]
|
|
1040
|
-
if kid[0].name == "DBL_COLON":
|
|
1041
|
-
kid = kid[1:]
|
|
1042
|
-
result = None
|
|
1043
|
-
op = kid[0].token_text()
|
|
1044
|
-
try:
|
|
1045
|
-
if op == "reverse":
|
|
1046
|
-
result = JacValue(self, value=atom_res.value.reverse())
|
|
1047
|
-
self.candidate_writethrough()
|
|
1048
|
-
elif op == "reversed":
|
|
1049
|
-
result = JacValue(self, value=list(reversed(atom_res.value)))
|
|
1050
|
-
elif op == "copy":
|
|
1051
|
-
result = JacValue(self, value=atom_res.value.copy())
|
|
1052
|
-
elif op == "deepcopy":
|
|
1053
|
-
result = JacValue(self, value=deepcopy(atom_res.value))
|
|
1054
|
-
elif op == "sort":
|
|
1055
|
-
result = JacValue(self, value=atom_res.value.sort())
|
|
1056
|
-
self.candidate_writethrough()
|
|
1057
|
-
elif op == "clear":
|
|
1058
|
-
result = JacValue(self, value=atom_res.value.clear())
|
|
1059
|
-
self.candidate_writethrough()
|
|
1060
|
-
elif op == "max":
|
|
1061
|
-
result = JacValue(self, value=max(atom_res.value))
|
|
1062
|
-
elif op == "min":
|
|
1063
|
-
result = JacValue(self, value=min(atom_res.value))
|
|
1064
|
-
elif op == "idx_of_max":
|
|
1065
|
-
result = JacValue(
|
|
1066
|
-
self, value=atom_res.value.index(max(atom_res.value))
|
|
1067
|
-
)
|
|
1068
|
-
elif op == "idx_of_min":
|
|
1069
|
-
result = JacValue(
|
|
1070
|
-
self, value=atom_res.value.index(min(atom_res.value))
|
|
1071
|
-
)
|
|
1072
|
-
elif op == "pairwise":
|
|
1073
|
-
result = JacValue(
|
|
1074
|
-
self, value=[list(s) for s in pairwise(atom_res.value)]
|
|
1075
|
-
)
|
|
1076
|
-
elif op == "unique":
|
|
1077
|
-
result = JacValue(self, value=list(set(atom_res.value)))
|
|
1078
|
-
|
|
1079
|
-
elif len(kid) < 2 and op == "pop":
|
|
1080
|
-
result = JacValue(self, value=atom_res.value.pop())
|
|
1081
|
-
self.candidate_writethrough()
|
|
1082
|
-
if result:
|
|
1083
|
-
if len(kid) > 1:
|
|
1084
|
-
self.rt_warn(f"{op} does not take parameters, ignoring", kid[2])
|
|
1085
|
-
return result
|
|
1086
|
-
if len(kid) > 1:
|
|
1087
|
-
args = self.run_expr_list(kid[2]).value
|
|
1088
|
-
if op == "index":
|
|
1089
|
-
result = JacValue(self, value=atom_res.value.index(*args))
|
|
1090
|
-
elif op == "append":
|
|
1091
|
-
result = JacValue(self, value=atom_res.value.append(*args))
|
|
1092
|
-
self.candidate_writethrough()
|
|
1093
|
-
elif op == "extend":
|
|
1094
|
-
result = JacValue(self, value=atom_res.value.extend(*args))
|
|
1095
|
-
self.candidate_writethrough()
|
|
1096
|
-
elif op == "insert":
|
|
1097
|
-
result = JacValue(self, value=atom_res.value.insert(*args))
|
|
1098
|
-
self.candidate_writethrough()
|
|
1099
|
-
elif op == "remove":
|
|
1100
|
-
result = JacValue(self, value=atom_res.value.remove(*args))
|
|
1101
|
-
self.candidate_writethrough()
|
|
1102
|
-
elif op == "count":
|
|
1103
|
-
result = JacValue(self, value=atom_res.value.count(*args))
|
|
1104
|
-
elif op == "pop":
|
|
1105
|
-
result = JacValue(self, value=atom_res.value.pop(*args))
|
|
1106
|
-
self.candidate_writethrough()
|
|
1107
|
-
if result:
|
|
1108
|
-
return result
|
|
1109
|
-
except Exception as e:
|
|
1110
|
-
self.rt_error(e, jac_ast)
|
|
1111
|
-
self.rt_error(f"Call to {op} is invalid.", jac_ast)
|
|
1112
|
-
return atom_res
|
|
1113
|
-
|
|
1114
|
-
def run_string_built_in(self, jac_ast, atom_res):
|
|
1115
|
-
"""
|
|
1116
|
-
string_built_in:
|
|
1117
|
-
(TYP_STRING DBL_COLON | STR_DBL_COLON) NAME (
|
|
1118
|
-
LPAREN expr_list RPAREN
|
|
1119
|
-
)?;
|
|
1120
|
-
"""
|
|
1121
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1122
|
-
if not self.rt_check_type(atom_res.value, [str], kid[0]):
|
|
1123
|
-
return atom_res
|
|
1124
|
-
kid = kid[1:]
|
|
1125
|
-
if kid[0].name == "DBL_COLON":
|
|
1126
|
-
kid = kid[1:]
|
|
1127
|
-
result = None
|
|
1128
|
-
str_op = kid[0].token_text()
|
|
1129
|
-
try:
|
|
1130
|
-
if str_op == "upper":
|
|
1131
|
-
result = JacValue(self, value=atom_res.value.upper())
|
|
1132
|
-
elif str_op == "lower":
|
|
1133
|
-
result = JacValue(self, value=atom_res.value.lower())
|
|
1134
|
-
elif str_op == "title":
|
|
1135
|
-
result = JacValue(self, value=atom_res.value.title())
|
|
1136
|
-
elif str_op == "capitalize":
|
|
1137
|
-
result = JacValue(self, value=atom_res.value.capitalize())
|
|
1138
|
-
elif str_op == "swap_case":
|
|
1139
|
-
result = JacValue(self, value=atom_res.value.swapcase())
|
|
1140
|
-
elif str_op == "is_alnum":
|
|
1141
|
-
result = JacValue(self, value=atom_res.value.isalnum())
|
|
1142
|
-
elif str_op == "is_alpha":
|
|
1143
|
-
result = JacValue(self, value=atom_res.value.isalpha())
|
|
1144
|
-
elif str_op == "is_digit":
|
|
1145
|
-
result = JacValue(self, value=atom_res.value.isdigit())
|
|
1146
|
-
elif str_op == "is_title":
|
|
1147
|
-
result = JacValue(self, value=atom_res.value.istitle())
|
|
1148
|
-
elif str_op == "is_upper":
|
|
1149
|
-
result = JacValue(self, value=atom_res.value.isupper())
|
|
1150
|
-
elif str_op == "is_lower":
|
|
1151
|
-
result = JacValue(self, value=atom_res.value.islower())
|
|
1152
|
-
elif str_op == "is_space":
|
|
1153
|
-
result = JacValue(self, value=atom_res.value.isspace())
|
|
1154
|
-
elif str_op == "load_json":
|
|
1155
|
-
import json
|
|
1156
|
-
|
|
1157
|
-
result = JacValue(self, value=json.loads(atom_res.value))
|
|
1158
|
-
elif len(kid) < 2 and str_op == "split":
|
|
1159
|
-
result = JacValue(self, value=atom_res.value.split())
|
|
1160
|
-
elif len(kid) < 2 and str_op == "strip":
|
|
1161
|
-
result = JacValue(self, value=atom_res.value.strip())
|
|
1162
|
-
elif len(kid) < 2 and str_op == "lstrip":
|
|
1163
|
-
result = JacValue(self, value=atom_res.value.lstrip())
|
|
1164
|
-
elif len(kid) < 2 and str_op == "rstrip":
|
|
1165
|
-
result = JacValue(self, value=atom_res.value.rstrip())
|
|
1166
|
-
if result:
|
|
1167
|
-
if len(kid) > 1:
|
|
1168
|
-
self.rt_warn(f"{str_op} does not take parameters, ignoring", kid[2])
|
|
1169
|
-
return result
|
|
1170
|
-
if len(kid) > 1:
|
|
1171
|
-
args = self.run_expr_list(kid[2]).value
|
|
1172
|
-
if str_op == "count":
|
|
1173
|
-
result = JacValue(self, value=atom_res.value.count(*args))
|
|
1174
|
-
elif str_op == "find":
|
|
1175
|
-
result = JacValue(self, value=atom_res.value.find(*args))
|
|
1176
|
-
elif str_op == "split":
|
|
1177
|
-
result = JacValue(self, value=atom_res.value.split(*args))
|
|
1178
|
-
elif str_op == "join":
|
|
1179
|
-
if len(args) == 1 and type(args[0]) is list:
|
|
1180
|
-
args = args[0]
|
|
1181
|
-
|
|
1182
|
-
result = JacValue(
|
|
1183
|
-
self, value=atom_res.value.join([str(arg) for arg in args])
|
|
1184
|
-
)
|
|
1185
|
-
elif str_op == "startswith":
|
|
1186
|
-
result = JacValue(self, value=atom_res.value.startswith(*args))
|
|
1187
|
-
elif str_op == "endswith":
|
|
1188
|
-
result = JacValue(self, value=atom_res.value.endswith(*args))
|
|
1189
|
-
elif str_op == "replace":
|
|
1190
|
-
result = JacValue(self, value=atom_res.value.replace(*args))
|
|
1191
|
-
elif str_op == "strip":
|
|
1192
|
-
result = JacValue(self, value=atom_res.value.strip(*args))
|
|
1193
|
-
elif str_op == "lstrip":
|
|
1194
|
-
result = JacValue(self, value=atom_res.value.lstrip(*args))
|
|
1195
|
-
elif str_op == "rstrip":
|
|
1196
|
-
result = JacValue(self, value=atom_res.value.rstrip(*args))
|
|
1197
|
-
if result:
|
|
1198
|
-
return result
|
|
1199
|
-
except Exception as e:
|
|
1200
|
-
self.rt_error(e, jac_ast)
|
|
1201
|
-
self.rt_error(f"Call to {str_op} is invalid.", jac_ast)
|
|
1202
|
-
return atom_res
|
|
1203
|
-
|
|
1204
|
-
def run_node_edge_ref(self, jac_ast, viable_nodes=None):
|
|
1205
|
-
"""
|
|
1206
|
-
node_edge_ref:
|
|
1207
|
-
node_ref filter_ctx? node_edge_ref?
|
|
1208
|
-
| edge_ref node_edge_ref?;
|
|
1209
|
-
"""
|
|
1210
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1211
|
-
result = JacSet()
|
|
1212
|
-
if kid[0].name == "node_ref":
|
|
1213
|
-
result = self.run_node_ref(kid[0], viable_nodes=viable_nodes)
|
|
1214
|
-
kid = kid[1:]
|
|
1215
|
-
if len(kid) and kid[0].name == "filter_ctx":
|
|
1216
|
-
result = self.run_filter_ctx(kid[0], result)
|
|
1217
|
-
kid = kid[1:]
|
|
1218
|
-
if len(kid):
|
|
1219
|
-
result = self.run_node_edge_ref(kid[0], viable_nodes=result).value
|
|
1220
|
-
|
|
1221
|
-
elif kid[0].name == "edge_ref":
|
|
1222
|
-
if not viable_nodes:
|
|
1223
|
-
viable_nodes = [None]
|
|
1224
|
-
self._relevant_edges = JacSet()
|
|
1225
|
-
for i in viable_nodes:
|
|
1226
|
-
relevant_edges = self.run_edge_ref(kid[0], location=i)
|
|
1227
|
-
result += self.visibility_prune(
|
|
1228
|
-
self.edge_to_node_jac_set(relevant_edges, location=i)
|
|
1229
|
-
)
|
|
1230
|
-
kid = kid[1:]
|
|
1231
|
-
if len(kid):
|
|
1232
|
-
result = self.run_node_edge_ref(kid[0], viable_nodes=result).value
|
|
1233
|
-
|
|
1234
|
-
relevant_edges = self.edges_filter_on_nodes(relevant_edges, result)
|
|
1235
|
-
self._relevant_edges += relevant_edges
|
|
1236
|
-
return JacValue(self, value=result)
|
|
1237
|
-
|
|
1238
|
-
def run_node_ref(self, jac_ast, is_spawn=False, viable_nodes=None):
|
|
1239
|
-
"""
|
|
1240
|
-
node_ref: NODE_DBL_COLON NAME;
|
|
1241
|
-
"""
|
|
1242
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1243
|
-
if not is_spawn:
|
|
1244
|
-
result = JacSet()
|
|
1245
|
-
viable_nodes = self.visibility_prune(viable_nodes)
|
|
1246
|
-
if len(kid) > 1:
|
|
1247
|
-
for i in viable_nodes.obj_list():
|
|
1248
|
-
try:
|
|
1249
|
-
if i.get_architype().is_instance(kid[-1].token_text()):
|
|
1250
|
-
result.add_obj(i)
|
|
1251
|
-
except:
|
|
1252
|
-
self.rt_warn(
|
|
1253
|
-
f"Error occured while getting architype {i.name}. Skipping..."
|
|
1254
|
-
)
|
|
1255
|
-
else:
|
|
1256
|
-
result += viable_nodes
|
|
1257
|
-
else:
|
|
1258
|
-
result = self.parent().run_architype(
|
|
1259
|
-
kid[-1].token_text(), kind="node", caller=self
|
|
1260
|
-
)
|
|
1261
|
-
return result
|
|
1262
|
-
|
|
1263
|
-
def run_walker_ref(self, jac_ast, to_await=False):
|
|
1264
|
-
"""
|
|
1265
|
-
walker_ref: WALKER_DBL_COLON NAME;
|
|
1266
|
-
"""
|
|
1267
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1268
|
-
name = kid[-1].token_text()
|
|
1269
|
-
wlk = self.yielded_walkers_ids.get_obj_by_name(name, silent=True)
|
|
1270
|
-
if wlk is None:
|
|
1271
|
-
wlk = self.parent().run_architype(name=name, kind="walker", caller=self)
|
|
1272
|
-
if wlk is None:
|
|
1273
|
-
self.rt_error(f"No walker {name} exists!", kid[-1])
|
|
1274
|
-
else:
|
|
1275
|
-
wlk._to_await = to_await
|
|
1276
|
-
return wlk
|
|
1277
|
-
|
|
1278
|
-
def run_graph_ref(self, jac_ast):
|
|
1279
|
-
"""
|
|
1280
|
-
graph_ref: GRAPH_DBL_COLON NAME;
|
|
1281
|
-
"""
|
|
1282
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1283
|
-
gph = self.parent().run_architype(
|
|
1284
|
-
kid[-1].token_text(), kind="graph", caller=self
|
|
1285
|
-
)
|
|
1286
|
-
return gph
|
|
1287
|
-
|
|
1288
|
-
def run_type_ref(self, jac_ast):
|
|
1289
|
-
"""
|
|
1290
|
-
type_ref: TYPE_DBL_COLON NAME;
|
|
1291
|
-
"""
|
|
1292
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1293
|
-
obj = self.parent().run_architype(
|
|
1294
|
-
kid[-1].token_text(), kind="type", caller=self
|
|
1295
|
-
)
|
|
1296
|
-
return JacValue(self, value=obj)
|
|
1297
|
-
|
|
1298
|
-
def run_edge_ref(self, jac_ast, location=None):
|
|
1299
|
-
"""
|
|
1300
|
-
edge_ref: edge_to | edge_from | edge_any;
|
|
1301
|
-
"""
|
|
1302
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1303
|
-
return self.run_rule(kid[0], location)
|
|
1304
|
-
|
|
1305
|
-
def run_edge_to(self, jac_ast, location=None):
|
|
1306
|
-
"""
|
|
1307
|
-
edge_to:
|
|
1308
|
-
'-->'
|
|
1309
|
-
| '-' ('[' NAME (spawn_ctx | filter_ctx)? ']')? '->';
|
|
1310
|
-
"""
|
|
1311
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1312
|
-
if not location:
|
|
1313
|
-
location = self.here()
|
|
1314
|
-
result = JacSet()
|
|
1315
|
-
for i in location.outbound_edges() + location.bidirected_edges():
|
|
1316
|
-
if len(kid) > 2 and not i.get_architype().is_instance(kid[2].token_text()):
|
|
1317
|
-
continue
|
|
1318
|
-
result.add_obj(i)
|
|
1319
|
-
if len(kid) > 2 and kid[3].name == "filter_ctx":
|
|
1320
|
-
result = self.run_filter_ctx(kid[3], result)
|
|
1321
|
-
elif len(kid) > 2 and kid[3].name == "spawn_ctx":
|
|
1322
|
-
self.rt_error("Assigning values not allowed here", kid[3])
|
|
1323
|
-
return result
|
|
1324
|
-
|
|
1325
|
-
def run_edge_from(self, jac_ast, location=None):
|
|
1326
|
-
"""
|
|
1327
|
-
edge_from:
|
|
1328
|
-
'<--'
|
|
1329
|
-
| '<-' ('[' NAME (spawn_ctx | filter_ctx)? ']')? '-';
|
|
1330
|
-
"""
|
|
1331
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1332
|
-
if not location:
|
|
1333
|
-
location = self.here()
|
|
1334
|
-
result = JacSet()
|
|
1335
|
-
for i in location.inbound_edges() + location.bidirected_edges():
|
|
1336
|
-
if len(kid) > 2 and not i.get_architype().is_instance(kid[2].token_text()):
|
|
1337
|
-
continue
|
|
1338
|
-
result.add_obj(i)
|
|
1339
|
-
if len(kid) > 2 and kid[3].name == "filter_ctx":
|
|
1340
|
-
result = self.run_filter_ctx(kid[3], result)
|
|
1341
|
-
elif len(kid) > 2 and kid[3].name == "spawn_ctx":
|
|
1342
|
-
self.rt_error("Assigning values not allowed here", kid[3])
|
|
1343
|
-
return result
|
|
1344
|
-
|
|
1345
|
-
def run_edge_any(self, jac_ast, location=None):
|
|
1346
|
-
"""
|
|
1347
|
-
edge_any:
|
|
1348
|
-
'<-->'
|
|
1349
|
-
| '<-' ('[' NAME (spawn_ctx | filter_ctx)? ']')? '->';
|
|
1350
|
-
NOTE: these do not use strict bidirected semantic but any edge
|
|
1351
|
-
"""
|
|
1352
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1353
|
-
if not location:
|
|
1354
|
-
location = self.here()
|
|
1355
|
-
result = JacSet()
|
|
1356
|
-
for i in location.attached_edges():
|
|
1357
|
-
if len(kid) > 2 and not i.get_architype().is_instance(kid[2].token_text()):
|
|
1358
|
-
continue
|
|
1359
|
-
result.add_obj(i)
|
|
1360
|
-
if len(kid) > 2 and kid[3].name == "filter_ctx":
|
|
1361
|
-
result = self.run_filter_ctx(kid[3], result)
|
|
1362
|
-
elif len(kid) > 2 and kid[3].name == "spawn_ctx":
|
|
1363
|
-
self.rt_error("Assigning values not allowed here", kid[3])
|
|
1364
|
-
return result
|
|
1365
|
-
|
|
1366
|
-
def run_connect_op(self, jac_ast):
|
|
1367
|
-
"""
|
|
1368
|
-
connect_op: connect_to | connect_from | connect_any;
|
|
1369
|
-
"""
|
|
1370
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1371
|
-
if len(kid[0].kid) > 2:
|
|
1372
|
-
result = self.parent().run_architype(
|
|
1373
|
-
kid[0].kid[2].token_text(), kind="edge", caller=self
|
|
1374
|
-
)
|
|
1375
|
-
if kid[0].kid[3].name == "spawn_ctx":
|
|
1376
|
-
self.run_spawn_ctx(kid[0].kid[3], result)
|
|
1377
|
-
else:
|
|
1378
|
-
result = Edge(
|
|
1379
|
-
m_id=self._m_id,
|
|
1380
|
-
h=self._h,
|
|
1381
|
-
kind="edge",
|
|
1382
|
-
name="generic",
|
|
1383
|
-
)
|
|
1384
|
-
return result
|
|
1385
|
-
|
|
1386
|
-
def run_list_val(self, jac_ast):
|
|
1387
|
-
"""
|
|
1388
|
-
list_val: LSQUARE expr_list? RSQUARE;
|
|
1389
|
-
"""
|
|
1390
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1391
|
-
if kid[1].name == "expr_list":
|
|
1392
|
-
return self.run_expr_list(kid[1])
|
|
1393
|
-
return JacValue(self, value=[])
|
|
1394
|
-
|
|
1395
|
-
def run_index_slice(self, jac_ast, atom_res):
|
|
1396
|
-
"""
|
|
1397
|
-
index_slice:
|
|
1398
|
-
LSQUARE expression RSQUARE
|
|
1399
|
-
| LSQUARE expression COLON expression RSQUARE;
|
|
1400
|
-
"""
|
|
1401
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1402
|
-
self.run_expression(kid[1])
|
|
1403
|
-
idx = self.pop().value
|
|
1404
|
-
if kid[2].name == "RSQUARE":
|
|
1405
|
-
if not self.rt_check_type(idx, [int, str], kid[1]):
|
|
1406
|
-
self.rt_error(
|
|
1407
|
-
f"Index of type {type(idx)} not valid. "
|
|
1408
|
-
f"Indicies must be an integer or string!",
|
|
1409
|
-
kid[1],
|
|
1410
|
-
)
|
|
1411
|
-
try:
|
|
1412
|
-
return JacValue(self, ctx=atom_res.value, name=idx)
|
|
1413
|
-
except Exception as e:
|
|
1414
|
-
self.rt_error(e, jac_ast, isinstance(e, (IndexError, AttributeError)))
|
|
1415
|
-
else:
|
|
1416
|
-
self.run_expression(kid[3])
|
|
1417
|
-
end = self.pop().value
|
|
1418
|
-
if not self.rt_check_type(idx, [int], kid[1]) or not self.rt_check_type(
|
|
1419
|
-
end, [int], kid[3]
|
|
1420
|
-
):
|
|
1421
|
-
self.rt_error(
|
|
1422
|
-
"List slice range not valid. Indicies must be an integers!",
|
|
1423
|
-
kid[1],
|
|
1424
|
-
)
|
|
1425
|
-
try:
|
|
1426
|
-
return JacValue(self, ctx=atom_res.value, name=idx, end=end)
|
|
1427
|
-
except Exception as e:
|
|
1428
|
-
self.rt_error(e, jac_ast, isinstance(e, (IndexError, AttributeError)))
|
|
1429
|
-
|
|
1430
|
-
def run_dict_val(self, jac_ast):
|
|
1431
|
-
"""
|
|
1432
|
-
dict_val: LBRACE (kv_pair (COMMA kv_pair)*)? RBRACE;
|
|
1433
|
-
"""
|
|
1434
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1435
|
-
dict_res = {}
|
|
1436
|
-
for i in kid:
|
|
1437
|
-
if i.name == "kv_pair":
|
|
1438
|
-
self.run_kv_pair(i, dict_res)
|
|
1439
|
-
return JacValue(self, value=dict_res)
|
|
1440
|
-
|
|
1441
|
-
def run_kv_pair(self, jac_ast, obj):
|
|
1442
|
-
"""
|
|
1443
|
-
kv_pair: STRING COLON expression;
|
|
1444
|
-
"""
|
|
1445
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1446
|
-
self.run_expression(kid[0])
|
|
1447
|
-
key = self.pop().value
|
|
1448
|
-
if isinstance(key, str):
|
|
1449
|
-
self.run_expression(kid[2])
|
|
1450
|
-
obj[key] = self.pop().value
|
|
1451
|
-
else:
|
|
1452
|
-
self.rt_error(f"Key is not str type : {type(key)}!", kid[0])
|
|
1453
|
-
|
|
1454
|
-
def run_spawn(self, jac_ast):
|
|
1455
|
-
"""
|
|
1456
|
-
spawn: KW_SPAWN spawn_object;
|
|
1457
|
-
|
|
1458
|
-
NOTE: spawn statements support locations that are either nodes or
|
|
1459
|
-
jac_sets
|
|
1460
|
-
"""
|
|
1461
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1462
|
-
return self.run_spawn_object(kid[1])
|
|
1463
|
-
|
|
1464
|
-
def run_spawn_object(self, jac_ast):
|
|
1465
|
-
"""
|
|
1466
|
-
spawn_object:
|
|
1467
|
-
node_spawn
|
|
1468
|
-
| walker_spawn
|
|
1469
|
-
| graph_spawn
|
|
1470
|
-
| type_spawn;
|
|
1471
|
-
"""
|
|
1472
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1473
|
-
return self.run_rule(kid[0])
|
|
1474
|
-
|
|
1475
|
-
def run_spawn_edge(self, jac_ast):
|
|
1476
|
-
"""
|
|
1477
|
-
spawn_edge: expression connect_op;
|
|
1478
|
-
"""
|
|
1479
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1480
|
-
self.run_expression(kid[0])
|
|
1481
|
-
loc = self.pop().value
|
|
1482
|
-
if isinstance(loc, JacSet):
|
|
1483
|
-
edge_set = [self.run_connect_op(kid[1]) for _ in loc]
|
|
1484
|
-
loc = loc.obj_list()
|
|
1485
|
-
else:
|
|
1486
|
-
edge_set = self.run_connect_op(kid[1])
|
|
1487
|
-
return {
|
|
1488
|
-
"location": loc,
|
|
1489
|
-
"use_edge": edge_set,
|
|
1490
|
-
"direction": kid[1].kid[0].name,
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
def run_node_spawn(self, jac_ast):
|
|
1494
|
-
"""
|
|
1495
|
-
node_spawn: spawn_edge? node_ref spawn_ctx?;
|
|
1496
|
-
"""
|
|
1497
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1498
|
-
if kid[0].name == "node_ref":
|
|
1499
|
-
ret_node = self.run_node_ref(kid[0], is_spawn=True)
|
|
1500
|
-
if kid[-1].name == "spawn_ctx":
|
|
1501
|
-
self.run_spawn_ctx(kid[-1], ret_node)
|
|
1502
|
-
return JacValue(self, value=ret_node)
|
|
1503
|
-
else:
|
|
1504
|
-
sp = self.run_spawn_edge(kid[0])
|
|
1505
|
-
if isinstance(sp["location"], Node):
|
|
1506
|
-
ret_node = self.run_node_ref(kid[1], is_spawn=True)
|
|
1507
|
-
if sp["direction"] == "connect_from":
|
|
1508
|
-
sp["location"].attach_inbound(ret_node, [sp["use_edge"]])
|
|
1509
|
-
elif sp["direction"] == "connect_to":
|
|
1510
|
-
sp["location"].attach_outbound(ret_node, [sp["use_edge"]])
|
|
1511
|
-
else:
|
|
1512
|
-
sp["location"].attach_bidirected(ret_node, [sp["use_edge"]])
|
|
1513
|
-
if kid[-1].name == "spawn_ctx":
|
|
1514
|
-
self.run_spawn_ctx(kid[-1], ret_node)
|
|
1515
|
-
return JacValue(self, value=ret_node)
|
|
1516
|
-
elif isinstance(sp["location"], JacSet):
|
|
1517
|
-
res = []
|
|
1518
|
-
sp["location"] = sp["location"].obj_list()
|
|
1519
|
-
for i in range(len(sp["location"])):
|
|
1520
|
-
ret_node = self.run_node_ref(kid[1], is_spawn=True)
|
|
1521
|
-
if sp["direction"] == "connect_from":
|
|
1522
|
-
sp["location"][i].attach_inbound(ret_node, [sp["use_edge"][i]])
|
|
1523
|
-
elif sp["direction"] == "connect_to":
|
|
1524
|
-
sp["location"][i].attach_outbound(ret_node, [sp["use_edge"][i]])
|
|
1525
|
-
else:
|
|
1526
|
-
sp["location"][i].attach_bidirected(
|
|
1527
|
-
ret_node, [sp["use_edge"][i]]
|
|
1528
|
-
)
|
|
1529
|
-
if kid[-1].name == "spawn_ctx":
|
|
1530
|
-
self.run_spawn_ctx(kid[-1], ret_node)
|
|
1531
|
-
res.append(ret_node)
|
|
1532
|
-
return JacValue(self, value=res)
|
|
1533
|
-
else:
|
|
1534
|
-
self.rt_error(f'Spawn can not occur on {type(sp["location"])}!', kid[1])
|
|
1535
|
-
|
|
1536
|
-
def run_graph_spawn(self, jac_ast):
|
|
1537
|
-
"""
|
|
1538
|
-
graph_spawn: spawn_edge? graph_ref;
|
|
1539
|
-
"""
|
|
1540
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1541
|
-
if kid[0].name == "graph_ref":
|
|
1542
|
-
result = self.run_graph_ref(kid[0])
|
|
1543
|
-
return JacValue(self, value=result)
|
|
1544
|
-
else:
|
|
1545
|
-
sp = self.run_spawn_edge(kid[0])
|
|
1546
|
-
if isinstance(sp["location"], Node):
|
|
1547
|
-
ret_node = self.run_graph_ref(kid[1])
|
|
1548
|
-
if sp["direction"] == "connect_from":
|
|
1549
|
-
sp["location"].attach_inbound(ret_node, [sp["use_edge"]])
|
|
1550
|
-
elif sp["direction"] == "connect_to":
|
|
1551
|
-
sp["location"].attach_outbound(ret_node, [sp["use_edge"]])
|
|
1552
|
-
else:
|
|
1553
|
-
sp["location"].attach_bidirected(ret_node, [sp["use_edge"]])
|
|
1554
|
-
return JacValue(self, value=ret_node)
|
|
1555
|
-
elif isinstance(sp["location"], JacSet):
|
|
1556
|
-
res = []
|
|
1557
|
-
sp["location"] = sp["location"].obj_list()
|
|
1558
|
-
for i in range(len(sp["location"])):
|
|
1559
|
-
ret_node = self.run_graph_ref(kid[1])
|
|
1560
|
-
if sp["direction"] == "connect_from":
|
|
1561
|
-
sp["location"][i].attach_inbound(ret_node, [sp["use_edge"][i]])
|
|
1562
|
-
elif sp["direction"] == "connect_to":
|
|
1563
|
-
sp["location"][i].attach_outbound(ret_node, [sp["use_edge"][i]])
|
|
1564
|
-
else:
|
|
1565
|
-
sp["location"][i].attach_bidirected(
|
|
1566
|
-
ret_node, [sp["use_edge"][i]]
|
|
1567
|
-
)
|
|
1568
|
-
res.append(ret_node)
|
|
1569
|
-
return JacValue(self, value=res)
|
|
1570
|
-
else:
|
|
1571
|
-
self.rt_error(f'Spawn can not occur on {type(sp["location"])}!', kid[1])
|
|
1572
|
-
|
|
1573
|
-
def run_walker_spawn(self, jac_ast):
|
|
1574
|
-
"""
|
|
1575
|
-
walker_spawn: expression KW_SYNC? walker_ref spawn_ctx?;
|
|
1576
|
-
"""
|
|
1577
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1578
|
-
is_await = kid[1].name == "KW_SYNC" and bool(kid.pop(1))
|
|
1579
|
-
self.run_expression(kid[0])
|
|
1580
|
-
location = self.pop().value
|
|
1581
|
-
if isinstance(location, Node):
|
|
1582
|
-
location = JacSet(in_list=[location])
|
|
1583
|
-
ret = []
|
|
1584
|
-
for i in location.obj_list():
|
|
1585
|
-
walk = self.run_walker_ref(kid[1], is_await)
|
|
1586
|
-
walk.prime(i, request_ctx=getattr(self, "request_context", {}))
|
|
1587
|
-
if len(kid) > 2:
|
|
1588
|
-
self.run_spawn_ctx(kid[2], walk)
|
|
1589
|
-
|
|
1590
|
-
res = walk.run()
|
|
1591
|
-
|
|
1592
|
-
if walk.for_queue() and not res["is_queued"]:
|
|
1593
|
-
res["result"] = walk.anchor_value()
|
|
1594
|
-
|
|
1595
|
-
tr = JacValue(self, value=res if walk.for_queue() else walk.anchor_value())
|
|
1596
|
-
ret.append(tr.value)
|
|
1597
|
-
self.inherit_runtime_state(walk)
|
|
1598
|
-
walk.register_yield_or_destroy(self.yielded_walkers_ids)
|
|
1599
|
-
return JacValue(self, value=ret[0] if len(ret) == 1 else ret)
|
|
1600
|
-
|
|
1601
|
-
def run_type_spawn(self, jac_ast):
|
|
1602
|
-
"""
|
|
1603
|
-
type_spawn: type_ref spawn_ctx?;
|
|
1604
|
-
"""
|
|
1605
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1606
|
-
ret = self.run_type_ref(kid[0])
|
|
1607
|
-
if kid[-1].name == "spawn_ctx":
|
|
1608
|
-
self.run_spawn_ctx(kid[-1], ret.value)
|
|
1609
|
-
return ret
|
|
1610
|
-
|
|
1611
|
-
def run_spawn_ctx(self, jac_ast, obj):
|
|
1612
|
-
"""
|
|
1613
|
-
spawn_ctx: LPAREN (spawn_assign (COMMA spawn_assign)*)? RPAREN;
|
|
1614
|
-
"""
|
|
1615
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1616
|
-
for i in kid:
|
|
1617
|
-
if i.name == "spawn_assign":
|
|
1618
|
-
self.run_spawn_assign(i, obj)
|
|
1619
|
-
|
|
1620
|
-
def run_filter_ctx(self, jac_ast, obj):
|
|
1621
|
-
"""
|
|
1622
|
-
filter_ctx:
|
|
1623
|
-
LPAREN (filter_compare (COMMA filter_compare)*)? RPAREN;
|
|
1624
|
-
"""
|
|
1625
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1626
|
-
ret = JacSet()
|
|
1627
|
-
for i in obj.obj_list():
|
|
1628
|
-
for j in kid:
|
|
1629
|
-
if j.name == "filter_compare":
|
|
1630
|
-
if self.run_filter_compare(j, i):
|
|
1631
|
-
ret.add_obj(i)
|
|
1632
|
-
return ret
|
|
1633
|
-
|
|
1634
|
-
def run_spawn_assign(self, jac_ast, obj):
|
|
1635
|
-
"""
|
|
1636
|
-
spawn_assign: NAME EQ expression;
|
|
1637
|
-
"""
|
|
1638
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1639
|
-
name = kid[0].token_text()
|
|
1640
|
-
self.run_expression(kid[-1])
|
|
1641
|
-
result = self.pop().value
|
|
1642
|
-
if isinstance(obj, dict):
|
|
1643
|
-
obj[name] = result
|
|
1644
|
-
return
|
|
1645
|
-
dest = JacValue(self, ctx=obj, name=name, value=result)
|
|
1646
|
-
if obj.j_type == "walker":
|
|
1647
|
-
dest.write(kid[0], force=True)
|
|
1648
|
-
else:
|
|
1649
|
-
dest.write(kid[0])
|
|
1650
|
-
|
|
1651
|
-
def run_filter_compare(self, jac_ast, obj):
|
|
1652
|
-
"""
|
|
1653
|
-
filter_compare: NAME cmp_op expression;
|
|
1654
|
-
"""
|
|
1655
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1656
|
-
name = kid[0].token_text()
|
|
1657
|
-
if name in obj.context.keys():
|
|
1658
|
-
self.run_expression(kid[-1])
|
|
1659
|
-
result = self.pop()
|
|
1660
|
-
self.run_cmp_op(kid[1], JacValue(self, ctx=obj, name=name), result)
|
|
1661
|
-
return self.pop().value
|
|
1662
|
-
else:
|
|
1663
|
-
self.rt_error(f"{name} not present in object", kid[0])
|
|
1664
|
-
|
|
1665
|
-
def run_any_type(self, jac_ast):
|
|
1666
|
-
"""
|
|
1667
|
-
any_type:
|
|
1668
|
-
TYP_STRING
|
|
1669
|
-
| TYP_INT
|
|
1670
|
-
| TYP_FLOAT
|
|
1671
|
-
| TYP_LIST
|
|
1672
|
-
| TYP_DICT
|
|
1673
|
-
| TYP_BOOL
|
|
1674
|
-
| KW_NODE
|
|
1675
|
-
| KW_EDGE
|
|
1676
|
-
| KW_TYPE;
|
|
1677
|
-
"""
|
|
1678
|
-
if self.attempt_bytecode(jac_ast):
|
|
1679
|
-
return
|
|
1680
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1681
|
-
if kid[0].name == "TYP_STRING":
|
|
1682
|
-
self.push(JacValue(self, value=str))
|
|
1683
|
-
elif kid[0].name == "TYP_INT":
|
|
1684
|
-
self.push(JacValue(self, value=int))
|
|
1685
|
-
elif kid[0].name == "TYP_FLOAT":
|
|
1686
|
-
self.push(JacValue(self, value=float))
|
|
1687
|
-
elif kid[0].name == "TYP_LIST":
|
|
1688
|
-
self.push(JacValue(self, value=list))
|
|
1689
|
-
elif kid[0].name == "TYP_DICT":
|
|
1690
|
-
self.push(JacValue(self, value=dict))
|
|
1691
|
-
elif kid[0].name == "TYP_BOOL":
|
|
1692
|
-
self.push(JacValue(self, value=bool))
|
|
1693
|
-
elif kid[0].name == "KW_NODE":
|
|
1694
|
-
self.push(JacValue(self, value=Node))
|
|
1695
|
-
elif kid[0].name == "KW_EDGE":
|
|
1696
|
-
self.push(JacValue(self, value=Edge))
|
|
1697
|
-
elif kid[0].name == "KW_TYPE":
|
|
1698
|
-
self.push(JacValue(self, value=type))
|
|
1699
|
-
else:
|
|
1700
|
-
self.rt_error("Unrecognized type", kid[0])
|
|
1701
|
-
|
|
1702
|
-
def run_multistring(self, jac_ast):
|
|
1703
|
-
"""
|
|
1704
|
-
multistring: STRING+;
|
|
1705
|
-
"""
|
|
1706
|
-
if self.attempt_bytecode(jac_ast):
|
|
1707
|
-
return
|
|
1708
|
-
kid = self.set_cur_ast(jac_ast)
|
|
1709
|
-
ret = ""
|
|
1710
|
-
for i in kid:
|
|
1711
|
-
ret += parse_str_token(i.token_text())
|
|
1712
|
-
self.push(JacValue(self, value=ret))
|
|
1713
|
-
|
|
1714
|
-
def destroy(self):
|
|
1715
|
-
"""
|
|
1716
|
-
Destroys self from memory and persistent storage
|
|
1717
|
-
"""
|
|
1718
|
-
super().destroy()
|
|
1719
|
-
|
|
1720
|
-
# Helper Functions ##################
|
|
1721
|
-
def attempt_bytecode(self, jac_ast):
|
|
1722
|
-
if hasattr(jac_ast, "bytecode") and jac_ast.bytecode:
|
|
1723
|
-
self.run_bytecode(b64decode(jac_ast.bytecode.encode()))
|
|
1724
|
-
return True
|
|
1725
|
-
return False
|
|
1726
|
-
|
|
1727
|
-
def call_ability(self, nd, name, act_list):
|
|
1728
|
-
ability = act_list.get_obj_by_name(name)
|
|
1729
|
-
try:
|
|
1730
|
-
ability.j_master = self.j_master
|
|
1731
|
-
ability._mast = self._mast
|
|
1732
|
-
ability.run_ability(here=nd, visitor=self._jac_scope.visitor())
|
|
1733
|
-
except Exception as e:
|
|
1734
|
-
self.rt_error(f"Internal Exception: {e}", ability._cur_jac_ast)
|
|
1735
|
-
self.inherit_runtime_state(ability)
|
|
1736
|
-
|
|
1737
|
-
def visibility_prune(self, node_set=None):
|
|
1738
|
-
"""Returns all nodes that shouldnt be ignored"""
|
|
1739
|
-
ret = JacSet()
|
|
1740
|
-
if node_set is None:
|
|
1741
|
-
node_set = self.here().attached_nodes()
|
|
1742
|
-
for i in node_set:
|
|
1743
|
-
if i not in self.ignore_node_ids.obj_list():
|
|
1744
|
-
ret.add_obj(i)
|
|
1745
|
-
return ret
|
|
1746
|
-
|
|
1747
|
-
def run_rule(self, jac_ast, *args):
|
|
1748
|
-
"""Helper to run rule if exists in execution context"""
|
|
1749
|
-
try:
|
|
1750
|
-
val = getattr(self, f"run_{jac_ast.name}")(jac_ast, *args)
|
|
1751
|
-
# TODO: Rewrite after stack integration
|
|
1752
|
-
if jac_ast.name in [
|
|
1753
|
-
"any_type",
|
|
1754
|
-
"atom",
|
|
1755
|
-
"arithmetic",
|
|
1756
|
-
"term",
|
|
1757
|
-
"factor",
|
|
1758
|
-
"power",
|
|
1759
|
-
"cmp_op",
|
|
1760
|
-
"compare",
|
|
1761
|
-
"logical",
|
|
1762
|
-
"expression",
|
|
1763
|
-
"assignment",
|
|
1764
|
-
"copy_assign",
|
|
1765
|
-
"inc_assign",
|
|
1766
|
-
"multistring",
|
|
1767
|
-
]:
|
|
1768
|
-
return self.pop()
|
|
1769
|
-
else:
|
|
1770
|
-
return val
|
|
1771
|
-
# return getattr(self, f"run_{jac_ast.name}")(jac_ast, *args)
|
|
1772
|
-
except AttributeError as e:
|
|
1773
|
-
if not hasattr(self, f"run_{jac_ast.name}"):
|
|
1774
|
-
self.rt_error(
|
|
1775
|
-
f"This scope cannot execute the statement "
|
|
1776
|
-
f'"{jac_ast.get_text()}" of type {jac_ast.name}',
|
|
1777
|
-
jac_ast,
|
|
1778
|
-
)
|
|
1779
|
-
else:
|
|
1780
|
-
self.rt_error(e, jac_ast)
|
|
1781
|
-
return
|
|
1782
|
-
except Exception as e:
|
|
1783
|
-
self.rt_error(e, jac_ast)
|