jaseci 1.4.0.18__py3-none-any.whl → 1.4.0.20__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/VERSION +1 -1
- jaseci/cli_tools/jsctl.py +41 -2
- jaseci/cli_tools/tests/test_jsctl.py +11 -0
- jaseci/extens/act_lib/internal.py +2 -1
- jaseci/extens/act_lib/std.py +7 -0
- jaseci/extens/act_lib/tests/test_std_lib.py +3 -1
- jaseci/extens/api/jsorc_api.py +41 -1
- jaseci/extens/api/walker_api.py +9 -0
- jaseci/jac/interpreter/architype_interp.py +63 -28
- jaseci/jac/interpreter/interp.py +54 -158
- jaseci/jac/interpreter/sentinel_interp.py +73 -5
- jaseci/jac/interpreter/walker_interp.py +27 -38
- jaseci/jac/ir/ast.py +9 -1
- jaseci/jac/jac.g4 +5 -4
- jaseci/jac/jac_parse/jacListener.py +8 -8
- jaseci/jac/jac_parse/jacParser.py +1167 -1154
- jaseci/jac/machine/jac_scope.py +23 -30
- jaseci/jac/machine/machine_state.py +76 -12
- jaseci/jsorc/jsorc.py +92 -79
- jaseci/jsorc/live_actions.py +29 -24
- jaseci/jsorc/redis.py +7 -5
- jaseci/prim/{action.py → ability.py} +44 -31
- jaseci/prim/architype.py +26 -8
- jaseci/prim/obj_mixins.py +5 -0
- jaseci/prim/sentinel.py +3 -1
- jaseci/prim/walker.py +7 -5
- jaseci/tests/jac_test_progs.py +9 -0
- jaseci/tests/test_jac.py +3 -3
- jaseci/tests/test_node.py +9 -12
- jaseci/tests/test_progs.py +16 -1
- jaseci/tests/test_stack.py +22 -0
- jaseci/utils/actions/actions_optimizer.py +23 -8
- jaseci/utils/gprof2dot.py +3786 -0
- jaseci/utils/json_handler.py +5 -1
- jaseci/utils/utils.py +52 -21
- {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/METADATA +2 -2
- {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/RECORD +41 -41
- jaseci/prim/item.py +0 -29
- {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/LICENSE +0 -0
- {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/WHEEL +0 -0
- {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/entry_points.txt +0 -0
- {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/top_level.txt +0 -0
jaseci/jac/interpreter/interp.py
CHANGED
|
@@ -10,7 +10,6 @@ from jaseci.utils.utils import is_jsonable, parse_str_token, uuid_re
|
|
|
10
10
|
from jaseci.prim.element import Element
|
|
11
11
|
from jaseci.prim.node import Node
|
|
12
12
|
from jaseci.prim.edge import Edge
|
|
13
|
-
from jaseci.prim.action import Action
|
|
14
13
|
from jaseci.jac.jac_set import JacSet
|
|
15
14
|
from jaseci.jac.ir.jac_code import jac_ast_to_ir, jac_ir_to_ast
|
|
16
15
|
from jaseci.jac.machine.jac_scope import JacScope
|
|
@@ -20,6 +19,7 @@ from jaseci.jac.machine.machine_state import TryException
|
|
|
20
19
|
from jaseci.jac.machine.jac_value import JacValue
|
|
21
20
|
from jaseci.jac.machine.jac_value import jac_elem_unwrap as jeu
|
|
22
21
|
from jaseci.jac.machine.jac_value import jac_wrap_value as jwv
|
|
22
|
+
from json import dumps, loads
|
|
23
23
|
from copy import copy, deepcopy
|
|
24
24
|
from base64 import b64decode
|
|
25
25
|
from itertools import pairwise
|
|
@@ -30,114 +30,6 @@ from jaseci.jac.jsci_vm.op_codes import JsCmp
|
|
|
30
30
|
class Interp(VirtualMachine):
|
|
31
31
|
"""Shared interpreter class across both sentinels and walkers"""
|
|
32
32
|
|
|
33
|
-
def run_attr_stmt(self, jac_ast, obj):
|
|
34
|
-
"""
|
|
35
|
-
attr_stmt: has_stmt | can_stmt;
|
|
36
|
-
"""
|
|
37
|
-
kid = self.set_cur_ast(jac_ast)
|
|
38
|
-
if kid[0].name == "has_stmt":
|
|
39
|
-
self.run_has_stmt(kid[0], obj)
|
|
40
|
-
# Can statements in architype handled in architype load
|
|
41
|
-
|
|
42
|
-
def run_has_stmt(self, jac_ast, obj):
|
|
43
|
-
"""
|
|
44
|
-
has_stmt: KW_HAS has_assign (COMMA has_assign)* SEMI;
|
|
45
|
-
"""
|
|
46
|
-
kid = self.set_cur_ast(jac_ast)
|
|
47
|
-
for i in kid:
|
|
48
|
-
if i.name == "has_assign":
|
|
49
|
-
self.run_has_assign(i, obj)
|
|
50
|
-
|
|
51
|
-
def run_has_assign(self, jac_ast, obj):
|
|
52
|
-
"""
|
|
53
|
-
has_assign: KW_PRIVATE? KW_ANCHOR? (NAME | NAME EQ expression);
|
|
54
|
-
"""
|
|
55
|
-
kid = self.set_cur_ast(jac_ast)
|
|
56
|
-
while kid[0].name in ["KW_PRIVATE", "KW_ANCHOR"]:
|
|
57
|
-
kid = kid[1:]
|
|
58
|
-
var_name = kid[0].token_text()
|
|
59
|
-
var_val = None # jac's null
|
|
60
|
-
if len(kid) > 1:
|
|
61
|
-
self.run_expression(kid[2])
|
|
62
|
-
var_val = self.pop().value
|
|
63
|
-
if isinstance(obj, dict):
|
|
64
|
-
obj[var_name] = var_val
|
|
65
|
-
# Runs only once for walkers
|
|
66
|
-
elif var_name not in obj.context.keys() or obj.j_type != "walker":
|
|
67
|
-
JacValue(
|
|
68
|
-
self, ctx=obj, name=var_name, value=var_val, create_mode=True
|
|
69
|
-
).write(kid[0], force=True)
|
|
70
|
-
|
|
71
|
-
def run_can_stmt(self, jac_ast, obj):
|
|
72
|
-
"""
|
|
73
|
-
can_stmt:
|
|
74
|
-
KW_CAN dotted_name (preset_in_out event_clause)? (
|
|
75
|
-
COMMA dotted_name (preset_in_out event_clause)?
|
|
76
|
-
)* SEMI
|
|
77
|
-
| KW_CAN NAME event_clause? code_block;
|
|
78
|
-
"""
|
|
79
|
-
kid = self.set_cur_ast(jac_ast)
|
|
80
|
-
kid = kid[1:]
|
|
81
|
-
while True:
|
|
82
|
-
action_type = "activity"
|
|
83
|
-
access_list = None
|
|
84
|
-
preset_in_out = None
|
|
85
|
-
if kid[0].name == "NAME":
|
|
86
|
-
action_name = kid[0].token_text()
|
|
87
|
-
else:
|
|
88
|
-
action_name = self.run_dotted_name(kid[0])
|
|
89
|
-
kid = kid[1:]
|
|
90
|
-
if len(kid) > 0 and kid[0].name == "preset_in_out":
|
|
91
|
-
preset_in_out = jac_ast_to_ir(kid[0])
|
|
92
|
-
kid = kid[1:]
|
|
93
|
-
if len(kid) > 0 and kid[0].name == "event_clause":
|
|
94
|
-
action_type, access_list = self.run_event_clause(kid[0])
|
|
95
|
-
kid = kid[1:]
|
|
96
|
-
# if (not isinstance(obj, node) and action_type != 'activity'):
|
|
97
|
-
# self.rt_warn(
|
|
98
|
-
# "Only nodes has on entry/exit, treating as activity",
|
|
99
|
-
# kid[0])
|
|
100
|
-
# action_type = 'activity'
|
|
101
|
-
if kid[0].name == "code_block":
|
|
102
|
-
act = Action(
|
|
103
|
-
m_id=self._m_id,
|
|
104
|
-
h=self._h,
|
|
105
|
-
name=action_name,
|
|
106
|
-
value=jac_ast_to_ir(kid[0]),
|
|
107
|
-
preset_in_out=preset_in_out,
|
|
108
|
-
access_list=access_list,
|
|
109
|
-
)
|
|
110
|
-
getattr(obj, f"{action_type}_action_ids").add_obj(act)
|
|
111
|
-
self._jac_scope.add_action(act)
|
|
112
|
-
break
|
|
113
|
-
else:
|
|
114
|
-
self.check_builtin_action(action_name, jac_ast)
|
|
115
|
-
act = Action(
|
|
116
|
-
m_id=self._m_id,
|
|
117
|
-
h=self._h,
|
|
118
|
-
name=action_name,
|
|
119
|
-
value=action_name,
|
|
120
|
-
preset_in_out=preset_in_out,
|
|
121
|
-
access_list=access_list,
|
|
122
|
-
)
|
|
123
|
-
getattr(obj, f"{action_type}_action_ids").add_obj(act)
|
|
124
|
-
self._jac_scope.add_action(act)
|
|
125
|
-
if not len(kid) or kid[0].name != "COMMA":
|
|
126
|
-
break
|
|
127
|
-
else:
|
|
128
|
-
kid = kid[1:]
|
|
129
|
-
|
|
130
|
-
def run_event_clause(self, jac_ast):
|
|
131
|
-
"""
|
|
132
|
-
event_clause:
|
|
133
|
-
KW_WITH name_list? (KW_ENTRY | KW_EXIT | KW_ACTIVITY);
|
|
134
|
-
"""
|
|
135
|
-
kid = self.set_cur_ast(jac_ast)
|
|
136
|
-
nl = []
|
|
137
|
-
if kid[1].name == "name_list":
|
|
138
|
-
nl = self.run_name_list(kid[1])
|
|
139
|
-
return kid[-1].token_text(), nl
|
|
140
|
-
|
|
141
33
|
def run_dotted_name(self, jac_ast):
|
|
142
34
|
"""
|
|
143
35
|
dotted_name: NAME (DOT NAME)*;
|
|
@@ -761,7 +653,7 @@ class Interp(VirtualMachine):
|
|
|
761
653
|
| dict_val
|
|
762
654
|
| LPAREN expression RPAREN
|
|
763
655
|
| ability_op NAME spawn_ctx?
|
|
764
|
-
| atom atom_trailer
|
|
656
|
+
| atom atom_trailer
|
|
765
657
|
| KW_SYNC atom
|
|
766
658
|
| spawn
|
|
767
659
|
| ref
|
|
@@ -787,7 +679,11 @@ class Interp(VirtualMachine):
|
|
|
787
679
|
elif kid[0].name == "LPAREN":
|
|
788
680
|
self.run_expression(kid[1])
|
|
789
681
|
elif kid[0].name == "ability_op":
|
|
790
|
-
self.push(
|
|
682
|
+
self.push(
|
|
683
|
+
self.run_ability_call(
|
|
684
|
+
jac_ast, atom_res=JacValue(self, value=self._jac_scope.has_obj)
|
|
685
|
+
)
|
|
686
|
+
)
|
|
791
687
|
elif kid[0].name == "atom":
|
|
792
688
|
self.run_atom(kid[0])
|
|
793
689
|
ret = self.pop()
|
|
@@ -819,13 +715,10 @@ class Interp(VirtualMachine):
|
|
|
819
715
|
DOT built_in
|
|
820
716
|
| DOT NAME
|
|
821
717
|
| index_slice
|
|
822
|
-
|
|
|
823
|
-
| ability_op NAME spawn_ctx?;
|
|
718
|
+
| ability_call;
|
|
824
719
|
"""
|
|
825
720
|
try:
|
|
826
721
|
kid = self.set_cur_ast(jac_ast)
|
|
827
|
-
if atom_res is None:
|
|
828
|
-
atom_res = JacValue(self, value=self._jac_scope.has_obj)
|
|
829
722
|
if isinstance(atom_res.value, Element):
|
|
830
723
|
self._write_candidate = atom_res.value
|
|
831
724
|
if kid[0].name == "DOT":
|
|
@@ -857,28 +750,40 @@ class Interp(VirtualMachine):
|
|
|
857
750
|
if not self.rt_check_type(atom_res.value, [list, str, dict], kid[0]):
|
|
858
751
|
return atom_res
|
|
859
752
|
return self.run_index_slice(kid[0], atom_res)
|
|
860
|
-
elif kid[0].name == "
|
|
861
|
-
|
|
862
|
-
if kid[1].name == "param_list":
|
|
863
|
-
param_list = self.run_param_list(kid[1]).value
|
|
864
|
-
if isinstance(atom_res.value, Action):
|
|
865
|
-
ret = atom_res.value.trigger(param_list, self._jac_scope, self)
|
|
866
|
-
return JacValue(self, value=ret)
|
|
867
|
-
else:
|
|
868
|
-
self.rt_error("Unable to execute ability", kid[0])
|
|
869
|
-
elif kid[0].name == "ability_op":
|
|
870
|
-
arch = self.run_ability_op(kid[0], atom_res)
|
|
871
|
-
if len(kid) > 2:
|
|
872
|
-
self.run_spawn_ctx(kid[2], atom_res.value)
|
|
873
|
-
self.call_ability(
|
|
874
|
-
nd=atom_res.value,
|
|
875
|
-
name=kid[1].token_text(),
|
|
876
|
-
act_list=arch.get_all_actions(),
|
|
877
|
-
)
|
|
878
|
-
return atom_res
|
|
753
|
+
elif kid[0].name == "ability_call":
|
|
754
|
+
return self.run_ability_call(kid[0], atom_res)
|
|
879
755
|
except Exception as e:
|
|
880
756
|
self.jac_try_exception(e, jac_ast)
|
|
881
757
|
|
|
758
|
+
def run_ability_call(self, jac_ast, atom_res):
|
|
759
|
+
"""
|
|
760
|
+
ability_call:
|
|
761
|
+
LPAREN param_list? RPAREN
|
|
762
|
+
| ability_op NAME spawn_ctx?;
|
|
763
|
+
"""
|
|
764
|
+
from jaseci.prim.ability import Ability
|
|
765
|
+
|
|
766
|
+
kid = self.set_cur_ast(jac_ast)
|
|
767
|
+
if kid[0].name == "LPAREN":
|
|
768
|
+
param_list = {"args": [], "kwargs": {}}
|
|
769
|
+
if kid[1].name == "param_list":
|
|
770
|
+
param_list = self.run_param_list(kid[1]).value
|
|
771
|
+
if isinstance(atom_res.value, Ability):
|
|
772
|
+
ret = atom_res.value.run_action(param_list, self._jac_scope, self)
|
|
773
|
+
return JacValue(self, value=ret)
|
|
774
|
+
else:
|
|
775
|
+
self.rt_error("Unable to execute ability", kid[0])
|
|
776
|
+
elif kid[0].name == "ability_op":
|
|
777
|
+
arch = self.run_ability_op(kid[0], atom_res)
|
|
778
|
+
if len(kid) > 2:
|
|
779
|
+
self.run_spawn_ctx(kid[2], atom_res.value)
|
|
780
|
+
self.call_ability(
|
|
781
|
+
nd=atom_res.value,
|
|
782
|
+
name=kid[1].token_text(),
|
|
783
|
+
act_list=arch.get_all_abilities(),
|
|
784
|
+
)
|
|
785
|
+
return atom_res
|
|
786
|
+
|
|
882
787
|
def run_ability_op(self, jac_ast, atom_res):
|
|
883
788
|
"""
|
|
884
789
|
ability_op: DBL_COLON | DBL_COLON NAME COLON;
|
|
@@ -952,21 +857,13 @@ class Interp(VirtualMachine):
|
|
|
952
857
|
return JacValue(
|
|
953
858
|
self,
|
|
954
859
|
value=self.obj_set_to_jac_set(
|
|
955
|
-
self.
|
|
860
|
+
self.here().attached_edges(atom_res.value)
|
|
956
861
|
),
|
|
957
862
|
)
|
|
958
863
|
elif isinstance(atom_res.value, Edge):
|
|
959
864
|
return atom_res
|
|
960
865
|
elif isinstance(atom_res.value, JacSet):
|
|
961
866
|
return JacValue(self, value=self._relevant_edges)
|
|
962
|
-
# res = jac_set()
|
|
963
|
-
# for i in atom_res.value.obj_list():
|
|
964
|
-
# if(isinstance(i, edge)):
|
|
965
|
-
# res.add_obj(i)
|
|
966
|
-
# elif(isinstance(i, node)):
|
|
967
|
-
# res += self.obj_set_to_jac_set(
|
|
968
|
-
# self.current_node.attached_edges(i))
|
|
969
|
-
# return jac_value(self, value=res)
|
|
970
867
|
else:
|
|
971
868
|
self.rt_error(
|
|
972
869
|
f"Cannot get edges from {atom_res.value}. "
|
|
@@ -996,7 +893,12 @@ class Interp(VirtualMachine):
|
|
|
996
893
|
)
|
|
997
894
|
else:
|
|
998
895
|
try:
|
|
999
|
-
atom_res.value
|
|
896
|
+
if isinstance(atom_res.value, str) and typ.value == dict:
|
|
897
|
+
atom_res.value = loads(atom_res.value)
|
|
898
|
+
elif isinstance(atom_res.value, dict) and typ.value == str:
|
|
899
|
+
atom_res.value = dumps(atom_res.value)
|
|
900
|
+
else:
|
|
901
|
+
atom_res.value = typ.value(atom_res.value)
|
|
1000
902
|
except Exception as e:
|
|
1001
903
|
self.rt_error(
|
|
1002
904
|
f"Invalid cast of {atom_res.jac_type()} "
|
|
@@ -1394,7 +1296,7 @@ class Interp(VirtualMachine):
|
|
|
1394
1296
|
"""
|
|
1395
1297
|
kid = self.set_cur_ast(jac_ast)
|
|
1396
1298
|
if not location:
|
|
1397
|
-
location = self.
|
|
1299
|
+
location = self.here()
|
|
1398
1300
|
result = JacSet()
|
|
1399
1301
|
for i in location.outbound_edges() + location.bidirected_edges():
|
|
1400
1302
|
if len(kid) > 2 and not i.get_architype().is_instance(kid[2].token_text()):
|
|
@@ -1414,7 +1316,7 @@ class Interp(VirtualMachine):
|
|
|
1414
1316
|
"""
|
|
1415
1317
|
kid = self.set_cur_ast(jac_ast)
|
|
1416
1318
|
if not location:
|
|
1417
|
-
location = self.
|
|
1319
|
+
location = self.here()
|
|
1418
1320
|
result = JacSet()
|
|
1419
1321
|
for i in location.inbound_edges() + location.bidirected_edges():
|
|
1420
1322
|
if len(kid) > 2 and not i.get_architype().is_instance(kid[2].token_text()):
|
|
@@ -1435,7 +1337,7 @@ class Interp(VirtualMachine):
|
|
|
1435
1337
|
"""
|
|
1436
1338
|
kid = self.set_cur_ast(jac_ast)
|
|
1437
1339
|
if not location:
|
|
1438
|
-
location = self.
|
|
1340
|
+
location = self.here()
|
|
1439
1341
|
result = JacSet()
|
|
1440
1342
|
for i in location.attached_edges():
|
|
1441
1343
|
if len(kid) > 2 and not i.get_architype().is_instance(kid[2].token_text()):
|
|
@@ -1814,24 +1716,18 @@ class Interp(VirtualMachine):
|
|
|
1814
1716
|
return False
|
|
1815
1717
|
|
|
1816
1718
|
def call_ability(self, nd, name, act_list):
|
|
1817
|
-
|
|
1818
|
-
m.current_node = nd
|
|
1819
|
-
arch = nd.get_architype()
|
|
1820
|
-
m.push_scope(
|
|
1821
|
-
JacScope(parent=self, has_obj=nd, action_sets=[arch.get_all_actions()])
|
|
1822
|
-
)
|
|
1823
|
-
m._jac_scope.inherit_agent_refs(self._jac_scope, nd)
|
|
1719
|
+
ability = act_list.get_obj_by_name(name)
|
|
1824
1720
|
try:
|
|
1825
|
-
|
|
1721
|
+
ability.run_ability(here=nd, visitor=self._jac_scope.visitor())
|
|
1826
1722
|
except Exception as e:
|
|
1827
|
-
self.rt_error(f"Internal Exception: {e}",
|
|
1828
|
-
self.inherit_runtime_state(
|
|
1723
|
+
self.rt_error(f"Internal Exception: {e}", ability._cur_jac_ast)
|
|
1724
|
+
self.inherit_runtime_state(ability)
|
|
1829
1725
|
|
|
1830
1726
|
def visibility_prune(self, node_set=None):
|
|
1831
1727
|
"""Returns all nodes that shouldnt be ignored"""
|
|
1832
1728
|
ret = JacSet()
|
|
1833
1729
|
if node_set is None:
|
|
1834
|
-
node_set = self.
|
|
1730
|
+
node_set = self.here().attached_nodes()
|
|
1835
1731
|
for i in node_set:
|
|
1836
1732
|
if i not in self.ignore_node_ids.obj_list():
|
|
1837
1733
|
ret.add_obj(i)
|
|
@@ -9,6 +9,7 @@ from jaseci.jac.interpreter.interp import Interp
|
|
|
9
9
|
from jaseci.utils.utils import parse_str_token
|
|
10
10
|
from jaseci.jac.ir.jac_code import jac_ast_to_ir
|
|
11
11
|
from jaseci.jac.machine.jac_scope import JacScope
|
|
12
|
+
from jaseci.prim.ability import Ability
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class SentinelInterp(Interp):
|
|
@@ -124,17 +125,84 @@ class SentinelInterp(Interp):
|
|
|
124
125
|
def arch_can_compile(self, jac_ast, arch):
|
|
125
126
|
"""Helper function to statically compile can stmts for arch"""
|
|
126
127
|
kid = self.set_cur_ast(jac_ast)
|
|
127
|
-
self.push_scope(
|
|
128
|
+
self.push_scope(
|
|
129
|
+
JacScope(parent=self, name=f"a_cgen:{jac_ast.loc_str()}", has_obj=None)
|
|
130
|
+
)
|
|
128
131
|
if jac_ast.name in ["attr_block", "walker_block"]:
|
|
129
132
|
for i in kid:
|
|
130
133
|
if i.name == "attr_stmt" and i.kid[0].name == "can_stmt":
|
|
131
134
|
self.run_can_stmt(i.kid[0], arch)
|
|
132
|
-
elif
|
|
133
|
-
|
|
134
|
-
for i in kid:
|
|
135
|
-
self.run_can_stmt(i, arch)
|
|
135
|
+
elif jac_ast.name == "graph_block":
|
|
136
|
+
self.run_can_block(jac_ast.kid[2], arch)
|
|
136
137
|
self.pop_scope()
|
|
137
138
|
|
|
139
|
+
def run_can_block(self, jac_ast, arch):
|
|
140
|
+
"""
|
|
141
|
+
can_block: (can_stmt)*;
|
|
142
|
+
"""
|
|
143
|
+
kid = self.set_cur_ast(jac_ast)
|
|
144
|
+
for i in kid:
|
|
145
|
+
if i.name == "can_stmt":
|
|
146
|
+
self.run_can_stmt(i, arch)
|
|
147
|
+
|
|
148
|
+
def run_can_stmt(self, jac_ast, obj):
|
|
149
|
+
"""
|
|
150
|
+
can_stmt:
|
|
151
|
+
KW_CAN dotted_name (preset_in_out event_clause)? (
|
|
152
|
+
COMMA dotted_name (preset_in_out event_clause)?
|
|
153
|
+
)* SEMI
|
|
154
|
+
| KW_CAN NAME event_clause? code_block;
|
|
155
|
+
"""
|
|
156
|
+
kid = self.set_cur_ast(jac_ast)
|
|
157
|
+
kid = kid[1:]
|
|
158
|
+
ir = None
|
|
159
|
+
while True:
|
|
160
|
+
action_type = "activity"
|
|
161
|
+
access_list = None
|
|
162
|
+
preset_in_out = None
|
|
163
|
+
if kid[0].name == "NAME":
|
|
164
|
+
action_name = kid[0].token_text()
|
|
165
|
+
else:
|
|
166
|
+
action_name = self.run_dotted_name(kid[0])
|
|
167
|
+
kid = kid[1:]
|
|
168
|
+
if len(kid) > 0 and kid[0].name == "preset_in_out":
|
|
169
|
+
preset_in_out = jac_ast_to_ir(kid[0])
|
|
170
|
+
kid = kid[1:]
|
|
171
|
+
if len(kid) > 0 and kid[0].name == "event_clause":
|
|
172
|
+
action_type, access_list = self.run_event_clause(kid[0])
|
|
173
|
+
kid = kid[1:]
|
|
174
|
+
if kid[0].name != "code_block":
|
|
175
|
+
self.check_builtin_action(action_name, jac_ast)
|
|
176
|
+
else:
|
|
177
|
+
ir = kid[0]
|
|
178
|
+
getattr(obj, f"{action_type}_ability_ids").add_obj(
|
|
179
|
+
Ability(
|
|
180
|
+
m_id=self._m_id,
|
|
181
|
+
h=self._h,
|
|
182
|
+
name=action_name,
|
|
183
|
+
kind="ability",
|
|
184
|
+
code_ir=ir,
|
|
185
|
+
preset_in_out=preset_in_out,
|
|
186
|
+
access_list=access_list,
|
|
187
|
+
parent=self,
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
if not len(kid) or kid[0].name != "COMMA":
|
|
191
|
+
break
|
|
192
|
+
else:
|
|
193
|
+
kid = kid[1:]
|
|
194
|
+
|
|
195
|
+
def run_event_clause(self, jac_ast):
|
|
196
|
+
"""
|
|
197
|
+
event_clause:
|
|
198
|
+
KW_WITH name_list? (KW_ENTRY | KW_EXIT | KW_ACTIVITY);
|
|
199
|
+
"""
|
|
200
|
+
kid = self.set_cur_ast(jac_ast)
|
|
201
|
+
nl = []
|
|
202
|
+
if kid[1].name == "name_list":
|
|
203
|
+
nl = self.run_name_list(kid[1])
|
|
204
|
+
return kid[-1].token_text(), nl
|
|
205
|
+
|
|
138
206
|
def load_test(self, jac_ast):
|
|
139
207
|
"""
|
|
140
208
|
test:
|
|
@@ -9,7 +9,6 @@ from jaseci.jac.interpreter.interp import Interp
|
|
|
9
9
|
from jaseci.jac.jac_set import JacSet
|
|
10
10
|
from jaseci.jac.machine.jac_scope import JacScope
|
|
11
11
|
from jaseci.jac.ir.jac_code import jac_ir_to_ast
|
|
12
|
-
from jaseci.utils.id_list import IdList
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
class WalkerInterp(Interp):
|
|
@@ -25,6 +24,7 @@ class WalkerInterp(Interp):
|
|
|
25
24
|
self.scope_and_run(
|
|
26
25
|
jac_ast if jac_ast.name == "walker_block" else kid[-1],
|
|
27
26
|
self.run_walker_block,
|
|
27
|
+
scope_name=f"w_run:{jac_ast.loc_str()}",
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
def run_walker_block(self, jac_ast):
|
|
@@ -36,15 +36,8 @@ class WalkerInterp(Interp):
|
|
|
36
36
|
)* walk_exit_block? RBRACE;
|
|
37
37
|
"""
|
|
38
38
|
kid = self.set_cur_ast(jac_ast)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if i.name == "attr_stmt":
|
|
42
|
-
self.run_attr_stmt(jac_ast=i, obj=self)
|
|
43
|
-
archs = self.current_node.get_architype().arch_with_supers()
|
|
44
|
-
act_list = IdList(self)
|
|
45
|
-
for i in archs:
|
|
46
|
-
act_list += i.entry_action_ids
|
|
47
|
-
self.auto_trigger_node_actions(nd=self.current_node, act_list=act_list)
|
|
39
|
+
act_list = self.current_node.get_architype().get_entry_abilities()
|
|
40
|
+
self.auto_trigger_node_actions(act_list=act_list)
|
|
48
41
|
|
|
49
42
|
for i in kid:
|
|
50
43
|
if i.name == "walk_entry_block":
|
|
@@ -54,12 +47,8 @@ class WalkerInterp(Interp):
|
|
|
54
47
|
if i.name == "walk_activity_block":
|
|
55
48
|
self.run_walk_activity_block(i)
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
act_list = IdList(self)
|
|
60
|
-
for i in archs:
|
|
61
|
-
act_list += i.exit_action_ids
|
|
62
|
-
self.auto_trigger_node_actions(nd=self.current_node, act_list=act_list)
|
|
50
|
+
act_list = self.current_node.get_architype().get_exit_abilities()
|
|
51
|
+
self.auto_trigger_node_actions(act_list=act_list)
|
|
63
52
|
|
|
64
53
|
if not self.yielded and kid[-2].name == "walk_exit_block":
|
|
65
54
|
self.run_walk_exit_block(kid[-2])
|
|
@@ -190,7 +179,7 @@ class WalkerInterp(Interp):
|
|
|
190
179
|
expr_func(kid[1])
|
|
191
180
|
self.yield_walk()
|
|
192
181
|
|
|
193
|
-
def run_preset_in_out(self, jac_ast,
|
|
182
|
+
def run_preset_in_out(self, jac_ast, act):
|
|
194
183
|
"""
|
|
195
184
|
preset_in_out:
|
|
196
185
|
DBL_COLON param_list? (DBL_COLON | COLON_OUT expression);
|
|
@@ -200,29 +189,34 @@ class WalkerInterp(Interp):
|
|
|
200
189
|
"""
|
|
201
190
|
kid = self.set_cur_ast(jac_ast)
|
|
202
191
|
param_list = {"args": [], "kwargs": []}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
192
|
+
self.push_scope(
|
|
193
|
+
JacScope(
|
|
194
|
+
parent=self,
|
|
195
|
+
name=f"p_in_out:{jac_ast.loc_str()}",
|
|
196
|
+
has_obj=self.current_node,
|
|
197
|
+
here=self.current_node,
|
|
198
|
+
visitor=self,
|
|
199
|
+
)
|
|
207
200
|
)
|
|
208
|
-
m._jac_scope.set_agent_refs(cur_node=self.current_node, cur_walker=self)
|
|
209
201
|
|
|
210
202
|
if kid[1].name == "param_list":
|
|
211
|
-
param_list =
|
|
203
|
+
param_list = self.run_param_list(kid[1]).value
|
|
212
204
|
try:
|
|
213
|
-
result = act.
|
|
205
|
+
result = act.run_action(param_list, self._jac_scope, self)
|
|
214
206
|
except Exception as e:
|
|
215
|
-
self.rt_error(f"Internal Exception: {e}",
|
|
207
|
+
self.rt_error(f"Internal Exception: {e}", self._cur_jac_ast)
|
|
216
208
|
result = None
|
|
217
209
|
if kid[-1].name == "expression":
|
|
218
|
-
|
|
219
|
-
dest =
|
|
210
|
+
self.run_expression(kid[-1])
|
|
211
|
+
dest = self.pop()
|
|
220
212
|
dest.value = result
|
|
221
213
|
dest.write(kid[-1])
|
|
214
|
+
self.pop_scope()
|
|
222
215
|
|
|
223
216
|
# Helper Functions ##################
|
|
224
|
-
def auto_trigger_node_actions(self,
|
|
217
|
+
def auto_trigger_node_actions(self, act_list):
|
|
225
218
|
already_executed = [] # handles inhereted duplicates, (overriding)
|
|
219
|
+
nd = self.current_node
|
|
226
220
|
for i in act_list.obj_list():
|
|
227
221
|
if (
|
|
228
222
|
i.access_list
|
|
@@ -231,30 +225,25 @@ class WalkerInterp(Interp):
|
|
|
231
225
|
):
|
|
232
226
|
continue
|
|
233
227
|
if i.preset_in_out:
|
|
234
|
-
self.run_preset_in_out(jac_ir_to_ast(i.preset_in_out),
|
|
228
|
+
self.run_preset_in_out(jac_ir_to_ast(i.preset_in_out), i)
|
|
235
229
|
else:
|
|
236
230
|
self.call_ability(nd=nd, name=i.name, act_list=act_list)
|
|
237
231
|
if not i.preset_in_out: # All preset in and outs get executed
|
|
238
232
|
already_executed.append(i.name)
|
|
239
233
|
|
|
240
|
-
def scope_and_run(self, jac_ast, run_func):
|
|
234
|
+
def scope_and_run(self, jac_ast, run_func, scope_name):
|
|
241
235
|
"""
|
|
242
236
|
Helper to run ast elements with execution scope added
|
|
243
237
|
(Useful for running arbitrary code blocks as one-offs)
|
|
244
238
|
"""
|
|
245
|
-
node_arch = self.current_node.get_architype()
|
|
246
|
-
walk_arch = self.get_architype()
|
|
247
239
|
self.push_scope(
|
|
248
240
|
JacScope(
|
|
249
241
|
parent=self,
|
|
242
|
+
name=scope_name,
|
|
250
243
|
has_obj=self,
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
node_arch.activity_action_ids,
|
|
254
|
-
],
|
|
244
|
+
here=self.current_node,
|
|
245
|
+
visitor=self,
|
|
255
246
|
)
|
|
256
247
|
)
|
|
257
|
-
self._jac_scope.set_agent_refs(cur_node=self.current_node, cur_walker=self)
|
|
258
|
-
|
|
259
248
|
run_func(jac_ast)
|
|
260
249
|
self.pop_scope()
|
jaseci/jac/ir/ast.py
CHANGED
|
@@ -16,7 +16,12 @@ class Ast:
|
|
|
16
16
|
):
|
|
17
17
|
self.name = "unparsed"
|
|
18
18
|
self.kid = []
|
|
19
|
-
self.loc = [
|
|
19
|
+
self.loc = [
|
|
20
|
+
0,
|
|
21
|
+
0,
|
|
22
|
+
mod_name if mod_name is not None else "@default",
|
|
23
|
+
{},
|
|
24
|
+
] # line, col, module, tokens
|
|
20
25
|
|
|
21
26
|
def is_terminal(self):
|
|
22
27
|
"""Returns true if node is a terminal"""
|
|
@@ -37,6 +42,9 @@ class Ast:
|
|
|
37
42
|
if self.is_terminal():
|
|
38
43
|
return self.token()["symbol"]
|
|
39
44
|
|
|
45
|
+
def loc_str(self):
|
|
46
|
+
return f"{self.loc[2]}:{self.loc[0]}"
|
|
47
|
+
|
|
40
48
|
def __str__(self):
|
|
41
49
|
res = f"{self.name}:{self.loc[2]}:{self.loc[0]}:{self.loc[1]}:"
|
|
42
50
|
if self.is_terminal():
|
jaseci/jac/jac.g4
CHANGED
|
@@ -72,9 +72,7 @@ struct_block: LBRACE (has_stmt)* RBRACE | COLON has_stmt | SEMI;
|
|
|
72
72
|
|
|
73
73
|
can_block: (can_stmt)*;
|
|
74
74
|
|
|
75
|
-
graph_block:
|
|
76
|
-
|
|
77
|
-
graph_block_spawn:
|
|
75
|
+
graph_block:
|
|
78
76
|
LBRACE has_root can_block KW_SPAWN code_block RBRACE
|
|
79
77
|
| COLON has_root can_block KW_SPAWN code_block SEMI;
|
|
80
78
|
|
|
@@ -228,7 +226,10 @@ atom_trailer:
|
|
|
228
226
|
DOT built_in
|
|
229
227
|
| DOT NAME
|
|
230
228
|
| index_slice
|
|
231
|
-
|
|
|
229
|
+
| ability_call;
|
|
230
|
+
|
|
231
|
+
ability_call:
|
|
232
|
+
LPAREN param_list? RPAREN
|
|
232
233
|
| ability_op NAME spawn_ctx?;
|
|
233
234
|
|
|
234
235
|
ability_op: DBL_COLON | DBL_COLON NAME COLON;
|
|
@@ -161,14 +161,6 @@ class jacListener(ParseTreeListener):
|
|
|
161
161
|
def exitGraph_block(self, ctx: jacParser.Graph_blockContext):
|
|
162
162
|
pass
|
|
163
163
|
|
|
164
|
-
# Enter a parse tree produced by jacParser#graph_block_spawn.
|
|
165
|
-
def enterGraph_block_spawn(self, ctx: jacParser.Graph_block_spawnContext):
|
|
166
|
-
pass
|
|
167
|
-
|
|
168
|
-
# Exit a parse tree produced by jacParser#graph_block_spawn.
|
|
169
|
-
def exitGraph_block_spawn(self, ctx: jacParser.Graph_block_spawnContext):
|
|
170
|
-
pass
|
|
171
|
-
|
|
172
164
|
# Enter a parse tree produced by jacParser#has_root.
|
|
173
165
|
def enterHas_root(self, ctx: jacParser.Has_rootContext):
|
|
174
166
|
pass
|
|
@@ -537,6 +529,14 @@ class jacListener(ParseTreeListener):
|
|
|
537
529
|
def exitAtom_trailer(self, ctx: jacParser.Atom_trailerContext):
|
|
538
530
|
pass
|
|
539
531
|
|
|
532
|
+
# Enter a parse tree produced by jacParser#ability_call.
|
|
533
|
+
def enterAbility_call(self, ctx: jacParser.Ability_callContext):
|
|
534
|
+
pass
|
|
535
|
+
|
|
536
|
+
# Exit a parse tree produced by jacParser#ability_call.
|
|
537
|
+
def exitAbility_call(self, ctx: jacParser.Ability_callContext):
|
|
538
|
+
pass
|
|
539
|
+
|
|
540
540
|
# Enter a parse tree produced by jacParser#ability_op.
|
|
541
541
|
def enterAbility_op(self, ctx: jacParser.Ability_opContext):
|
|
542
542
|
pass
|