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.

Files changed (42) hide show
  1. jaseci/VERSION +1 -1
  2. jaseci/cli_tools/jsctl.py +41 -2
  3. jaseci/cli_tools/tests/test_jsctl.py +11 -0
  4. jaseci/extens/act_lib/internal.py +2 -1
  5. jaseci/extens/act_lib/std.py +7 -0
  6. jaseci/extens/act_lib/tests/test_std_lib.py +3 -1
  7. jaseci/extens/api/jsorc_api.py +41 -1
  8. jaseci/extens/api/walker_api.py +9 -0
  9. jaseci/jac/interpreter/architype_interp.py +63 -28
  10. jaseci/jac/interpreter/interp.py +54 -158
  11. jaseci/jac/interpreter/sentinel_interp.py +73 -5
  12. jaseci/jac/interpreter/walker_interp.py +27 -38
  13. jaseci/jac/ir/ast.py +9 -1
  14. jaseci/jac/jac.g4 +5 -4
  15. jaseci/jac/jac_parse/jacListener.py +8 -8
  16. jaseci/jac/jac_parse/jacParser.py +1167 -1154
  17. jaseci/jac/machine/jac_scope.py +23 -30
  18. jaseci/jac/machine/machine_state.py +76 -12
  19. jaseci/jsorc/jsorc.py +92 -79
  20. jaseci/jsorc/live_actions.py +29 -24
  21. jaseci/jsorc/redis.py +7 -5
  22. jaseci/prim/{action.py → ability.py} +44 -31
  23. jaseci/prim/architype.py +26 -8
  24. jaseci/prim/obj_mixins.py +5 -0
  25. jaseci/prim/sentinel.py +3 -1
  26. jaseci/prim/walker.py +7 -5
  27. jaseci/tests/jac_test_progs.py +9 -0
  28. jaseci/tests/test_jac.py +3 -3
  29. jaseci/tests/test_node.py +9 -12
  30. jaseci/tests/test_progs.py +16 -1
  31. jaseci/tests/test_stack.py +22 -0
  32. jaseci/utils/actions/actions_optimizer.py +23 -8
  33. jaseci/utils/gprof2dot.py +3786 -0
  34. jaseci/utils/json_handler.py +5 -1
  35. jaseci/utils/utils.py +52 -21
  36. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/METADATA +2 -2
  37. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/RECORD +41 -41
  38. jaseci/prim/item.py +0 -29
  39. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/LICENSE +0 -0
  40. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/WHEEL +0 -0
  41. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/entry_points.txt +0 -0
  42. {jaseci-1.4.0.18.dist-info → jaseci-1.4.0.20.dist-info}/top_level.txt +0 -0
@@ -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(self.run_atom_trailer(jac_ast, None))
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
- | LPAREN param_list? RPAREN
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 == "LPAREN":
861
- param_list = {"args": [], "kwargs": {}}
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.current_node.attached_edges(atom_res.value)
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 = typ.value(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.current_node
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.current_node
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.current_node
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
- m = Interp(parent_override=self.parent(), caller=self)
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
- m.run_code_block(jac_ir_to_ast(act_list.get_obj_by_name(name).value))
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}", m._cur_jac_ast)
1828
- self.inherit_runtime_state(m)
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.current_node.attached_nodes()
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(JacScope(parent=self, has_obj=self, action_sets=[]))
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 kid[0].name == "graph_block_spawn":
133
- kid = kid[0].kid[2].kid
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
- if self.current_step == 0:
40
- for i in kid:
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
- # self.trigger_activity_actions()
58
- archs = self.current_node.get_architype().arch_with_supers()
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, obj, act):
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
- m = Interp(parent_override=self.parent(), caller=self)
204
- arch = obj.get_architype()
205
- m.push_scope(
206
- JacScope(parent=self, has_obj=obj, action_sets=[arch.activity_action_ids])
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 = m.run_param_list(kid[1]).value
203
+ param_list = self.run_param_list(kid[1]).value
212
204
  try:
213
- result = act.trigger(param_list, self._jac_scope, self)
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}", m._cur_jac_ast)
207
+ self.rt_error(f"Internal Exception: {e}", self._cur_jac_ast)
216
208
  result = None
217
209
  if kid[-1].name == "expression":
218
- m.run_expression(kid[-1])
219
- dest = m.pop()
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, nd, act_list):
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), nd, i)
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
- action_sets=[
252
- walk_arch.activity_action_ids,
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 = [0, 0, mod_name if mod_name is not None else "@default", {}]
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: graph_block_spawn;
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
- | LPAREN param_list? RPAREN
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