jaclang 0.7.23__py3-none-any.whl → 0.7.25__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 jaclang might be problematic. Click here for more details.

Files changed (50) hide show
  1. jaclang/cli/cli.py +46 -29
  2. jaclang/compiler/__init__.py +2 -2
  3. jaclang/compiler/absyntree.py +87 -48
  4. jaclang/compiler/codeloc.py +7 -2
  5. jaclang/compiler/compile.py +10 -3
  6. jaclang/compiler/parser.py +26 -23
  7. jaclang/compiler/passes/ir_pass.py +2 -2
  8. jaclang/compiler/passes/main/def_impl_match_pass.py +46 -0
  9. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
  10. jaclang/compiler/passes/main/import_pass.py +6 -2
  11. jaclang/compiler/passes/main/pyast_load_pass.py +36 -35
  12. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
  13. jaclang/compiler/passes/main/registry_pass.py +3 -12
  14. jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
  15. jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
  16. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +59 -0
  17. jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
  18. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  19. jaclang/compiler/passes/transform.py +27 -3
  20. jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
  21. jaclang/compiler/symtable.py +6 -0
  22. jaclang/compiler/tests/test_importer.py +2 -2
  23. jaclang/langserve/engine.py +14 -12
  24. jaclang/langserve/server.py +7 -2
  25. jaclang/langserve/tests/test_server.py +1 -1
  26. jaclang/langserve/utils.py +17 -3
  27. jaclang/plugin/default.py +32 -32
  28. jaclang/plugin/feature.py +2 -2
  29. jaclang/plugin/plugin.md +471 -0
  30. jaclang/plugin/spec.py +2 -1
  31. jaclang/runtimelib/context.py +2 -0
  32. jaclang/runtimelib/importer.py +7 -2
  33. jaclang/runtimelib/machine.py +21 -6
  34. jaclang/settings.py +3 -0
  35. jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
  36. jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
  37. jaclang/tests/fixtures/expr_type.jac +54 -0
  38. jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
  39. jaclang/tests/fixtures/registry.jac +20 -8
  40. jaclang/tests/foo/__init__.jac +0 -0
  41. jaclang/tests/main.jac +2 -0
  42. jaclang/tests/test_cli.py +68 -4
  43. jaclang/tests/test_language.py +60 -27
  44. jaclang/utils/helpers.py +92 -14
  45. jaclang/utils/lang_tools.py +6 -2
  46. jaclang/utils/treeprinter.py +4 -2
  47. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/METADATA +2 -1
  48. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/RECORD +50 -44
  49. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/WHEEL +1 -1
  50. {jaclang-0.7.23.dist-info → jaclang-0.7.25.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,471 @@
1
+ # **Override Plugin Implementations**
2
+
3
+
4
+ ## AccessValidation Related Methods
5
+ ### **`allow_root`**
6
+ ```python
7
+ def allow_root(
8
+ architype: Architype,
9
+ root_id: UUID,
10
+ level: AccessLevel | int | str
11
+ ) -> None:
12
+ """Allow all access from target root graph to current Architype."""
13
+ ```
14
+ ### **`disallow_root`**
15
+ ```python
16
+ def disallow_root(
17
+ architype: Architype,
18
+ root_id: UUID,
19
+ level: AccessLevel | int | str
20
+ ) -> None:
21
+ """Disallow all access from target root graph to current Architype."""
22
+ ```
23
+ ### **`unrestrict`**
24
+ ```python
25
+ def unrestrict(
26
+ architype: Architype,
27
+ level: AccessLevel | int | str
28
+ ) -> None:
29
+ """Allow everyone to access current Architype."""
30
+ ```
31
+ ### **`restrict`**
32
+ ```python
33
+ def restrict(
34
+ architype: Architype
35
+ ) -> None:
36
+ """Disallow others to access current Architype."""
37
+ ```
38
+ ### **`check_read_access`**
39
+ ```python
40
+ def check_read_access(
41
+ to: Anchor
42
+ ) -> bool:
43
+ """Read Access Validation."""
44
+ ```
45
+ ### **`check_connect_access`**
46
+ ```python
47
+ def check_connect_access(
48
+ to: Anchor
49
+ ) -> bool:
50
+ """Connect Access Validation."""
51
+ ```
52
+ ### **`check_write_access`**
53
+ ```python
54
+ def check_write_access(
55
+ to: Anchor
56
+ ) -> bool:
57
+ """Write Access Validation."""
58
+ ```
59
+ ### **`check_access_level`**
60
+ ```python
61
+ def check_access_level(
62
+ to: Anchor
63
+ ) -> AccessLevel:
64
+ """Access validation."""
65
+ ```
66
+
67
+
68
+ ## Node Related Methods
69
+ ### **`node_dot`**
70
+ ```python
71
+ def node_dot(
72
+ node: NodeArchitype,
73
+ dot_file: Optional[str]
74
+ ) -> str:
75
+ """Generate Dot file for visualizing nodes and edges."""
76
+ ```
77
+ ### **`get_edges`**
78
+ ```python
79
+ def get_edges(
80
+ node: NodeAnchor,
81
+ dir: EdgeDir,
82
+ filter_func: Optional[Callable[[list[EdgeArchitype]], list[EdgeArchitype]]],
83
+ target_obj: Optional[list[NodeArchitype]],
84
+ ) -> list[EdgeArchitype]:
85
+ """Get edges connected to this node."""
86
+ ```
87
+ ### **`edges_to_nodes`**
88
+ ```python
89
+ def edges_to_nodes(
90
+ node: NodeAnchor,
91
+ dir: EdgeDir,
92
+ filter_func: Optional[Callable[[list[EdgeArchitype]], list[EdgeArchitype]]],
93
+ target_obj: Optional[list[NodeArchitype]],
94
+ ) -> list[NodeArchitype]:
95
+ """Get set of nodes connected to this node."""
96
+ ```
97
+ ### **`remove_edge`**
98
+ ```python
99
+ def remove_edge(
100
+ node: NodeAnchor,
101
+ edge: EdgeAnchor
102
+ ) -> None:
103
+ """Remove reference without checking sync status."""
104
+ ```
105
+
106
+
107
+ ## Edge Related Methods
108
+ ### **`detach`**
109
+ ```python
110
+ def detach(
111
+ edge: EdgeAnchor
112
+ ) -> None:
113
+ """Detach edge from nodes."""
114
+ ```
115
+
116
+
117
+ ## Walker Related Methods
118
+ ### **`visit_node`**
119
+ ```python
120
+ def visit_node(
121
+ walker: WalkerArchitype,
122
+ expr: (
123
+ list[NodeArchitype | EdgeArchitype]
124
+ | list[NodeArchitype]
125
+ | list[EdgeArchitype]
126
+ | NodeArchitype
127
+ | EdgeArchitype
128
+ ),
129
+ ) -> bool:
130
+ """Include target node/edge to current walker's visit queue."""
131
+ ```
132
+ ### **`ignore`**
133
+ ```python
134
+ def ignore(
135
+ walker: WalkerArchitype,
136
+ expr: (
137
+ list[NodeArchitype | EdgeArchitype]
138
+ | list[NodeArchitype]
139
+ | list[EdgeArchitype]
140
+ | NodeArchitype
141
+ | EdgeArchitype
142
+ ),
143
+ ) -> bool:
144
+ """Include target node/edge to current walker's ignored architype."""
145
+ ```
146
+ ### **`spawn_call`**
147
+ ```python
148
+ def spawn_call(
149
+ op1: Architype,
150
+ op2: Architype
151
+ ) -> WalkerArchitype:
152
+ """Invoke data spatial call."""
153
+ ```
154
+ ### **`disengage`**
155
+ ```python
156
+ def disengage(
157
+ walker: WalkerArchitype
158
+ ) -> bool:
159
+ """Disengaged current walker."""
160
+ ```
161
+
162
+
163
+ ## Builtin Related Methods
164
+ ### **`dotgen`**
165
+ ```python
166
+ def dotgen(
167
+ node: NodeArchitype,
168
+ depth: int,
169
+ traverse: bool,
170
+ edge_type: Optional[list[str]],
171
+ bfs: bool,
172
+ edge_limit: int,
173
+ node_limit: int,
174
+ dot_file: Optional[str],
175
+ ) -> str:
176
+ """Print the dot graph."""
177
+ ```
178
+
179
+
180
+ ## Cmd Related Methods
181
+ ### **`create_cmd`**
182
+ ```python
183
+ def create_cmd(
184
+ ) -> None:
185
+ """Create Jac CLI cmds."""
186
+ ```
187
+
188
+
189
+ ## Feature Related Methods
190
+ ### **`setup`**
191
+ ```python
192
+ def setup(
193
+ ) -> None:
194
+ """Set Class References to Jac."""
195
+ ```
196
+ ### **`get_context`**
197
+ ```python
198
+ def get_context(
199
+ ) -> ExecutionContext:
200
+ """Get current execution context."""
201
+ ```
202
+ ### **`get_object`**
203
+ ```python
204
+ def get_object(
205
+ id: str
206
+ ) -> Architype | None:
207
+ """Get object by id."""
208
+ ```
209
+ ### **`object_ref`**
210
+ ```python
211
+ def object_ref(
212
+ obj: Architype
213
+ ) -> str:
214
+ """Get object's id."""
215
+ ```
216
+ ### **`make_architype`**
217
+ ```python
218
+ def make_architype(
219
+ cls: type,
220
+ arch_base: Type[Architype],
221
+ on_entry: list[DSFunc],
222
+ on_exit: list[DSFunc],
223
+ ) -> Type[Architype]:
224
+ """Create a obj architype."""
225
+ ```
226
+ ### **`make_obj`**
227
+ ```python
228
+ def make_obj(
229
+ on_entry: list[DSFunc],
230
+ on_exit: list[DSFunc]
231
+ ) -> Callable[[type], type]:
232
+ """Create a obj architype."""
233
+ ```
234
+ ### **`make_node`**
235
+ ```python
236
+ def make_node(
237
+ on_entry: list[DSFunc],
238
+ on_exit: list[DSFunc]
239
+ ) -> Callable[[type], type]:
240
+ """Create a node architype."""
241
+ ```
242
+ ### **`make_edge`**
243
+ ```python
244
+ def make_edge(
245
+ on_entry: list[DSFunc],
246
+ on_exit: list[DSFunc]
247
+ ) -> Callable[[type], type]:
248
+ """Create a edge architype."""
249
+ ```
250
+ ### **`make_walker`**
251
+ ```python
252
+ def make_walker(
253
+ on_entry: list[DSFunc],
254
+ on_exit: list[DSFunc]
255
+ ) -> Callable[[type], type]:
256
+ """Create a walker architype."""
257
+ ```
258
+ ### **`impl_patch_filename`**
259
+ ```python
260
+ def impl_patch_filename(
261
+ file_loc: str,
262
+ ) -> Callable[[Callable[P, T]], Callable[P, T]]:
263
+ """Update impl file location."""
264
+ ```
265
+ ### **`jac_import`**
266
+ ```python
267
+ def jac_import(
268
+ target: str,
269
+ base_path: str,
270
+ absorb: bool,
271
+ cachable: bool,
272
+ mdl_alias: Optional[str],
273
+ override_name: Optional[str],
274
+ lng: Optional[str],
275
+ items: Optional[dict[str, Union[str, Optional[str]]]],
276
+ reload_module: Optional[bool],
277
+ ) -> tuple[types.ModuleType, ...]:
278
+ """Core Import Process."""
279
+ ```
280
+ ### **`create_test`**
281
+ ```python
282
+ def create_test(
283
+ test_fun: Callable
284
+ ) -> Callable:
285
+ """Create a new test."""
286
+ ```
287
+ ### **`run_test`**
288
+ ```python
289
+ def run_test(
290
+ filepath: str,
291
+ filter: Optional[str],
292
+ xit: bool,
293
+ maxfail: Optional[int],
294
+ directory: Optional[str],
295
+ verbose: bool,
296
+ ) -> int:
297
+ """Run the test suite in the specified .jac file."""
298
+ ```
299
+ ### **`elvis`**
300
+ ```python
301
+ def elvis(
302
+ op1: Optional[T],
303
+ op2: T
304
+ ) -> T:
305
+ """Jac's elvis operator feature."""
306
+ ```
307
+ ### **`has_instance_default`**
308
+ ```python
309
+ def has_instance_default(
310
+ gen_func: Callable[[], T]
311
+ ) -> T:
312
+ """Jac's has container default feature."""
313
+ ```
314
+ ### **`report`**
315
+ ```python
316
+ def report(
317
+ expr: Any
318
+ ) -> Any:
319
+ """Jac's report stmt feature."""
320
+ ```
321
+ ### **`edge_ref`**
322
+ ```python
323
+ def edge_ref(
324
+ node_obj: NodeArchitype | list[NodeArchitype],
325
+ target_obj: Optional[NodeArchitype | list[NodeArchitype]],
326
+ dir: EdgeDir,
327
+ filter_func: Optional[Callable[[list[EdgeArchitype]], list[EdgeArchitype]]],
328
+ edges_only: bool,
329
+ ) -> list[NodeArchitype] | list[EdgeArchitype]:
330
+ """Jac's apply_dir stmt feature."""
331
+ ```
332
+ ### **`connect`**
333
+ ```python
334
+ def connect(
335
+ left: NodeArchitype | list[NodeArchitype],
336
+ right: NodeArchitype | list[NodeArchitype],
337
+ edge_spec: Callable[[NodeAnchor, NodeAnchor], EdgeArchitype],
338
+ edges_only: bool,
339
+ ) -> list[NodeArchitype] | list[EdgeArchitype]:
340
+ """Jac's connect operator feature.
341
+
342
+ Note: connect needs to call assign compr with tuple in op
343
+ """
344
+ ```
345
+ ### **`disconnect`**
346
+ ```python
347
+ def disconnect(
348
+ left: NodeArchitype | list[NodeArchitype],
349
+ right: NodeArchitype | list[NodeArchitype],
350
+ dir: EdgeDir,
351
+ filter_func: Optional[Callable[[list[EdgeArchitype]], list[EdgeArchitype]]],
352
+ ) -> bool:
353
+ """Jac's disconnect operator feature."""
354
+ ```
355
+ ### **`assign_compr`**
356
+ ```python
357
+ def assign_compr(
358
+ target: list[T],
359
+ attr_val: tuple[tuple[str], tuple[Any]]
360
+ ) -> list[T]:
361
+ """Jac's assign comprehension feature."""
362
+ ```
363
+ ### **`get_root`**
364
+ ```python
365
+ def get_root(
366
+ ) -> Root:
367
+ """Get current root."""
368
+ ```
369
+ ### **`get_root_type`**
370
+ ```python
371
+ def get_root_type(
372
+ ) -> Type[Root]:
373
+ """Get root type."""
374
+ ```
375
+ ### **`build_edge`**
376
+ ```python
377
+ def build_edge(
378
+ is_undirected: bool,
379
+ conn_type: Optional[Type[EdgeArchitype] | EdgeArchitype],
380
+ conn_assign: Optional[tuple[tuple, tuple]],
381
+ ) -> Callable[[NodeAnchor, NodeAnchor], EdgeArchitype]:
382
+ """Build edge operator."""
383
+ ```
384
+ ### **`save`**
385
+ ```python
386
+ def save(
387
+ obj: Architype | Anchor,
388
+ ) -> None:
389
+ """Save object."""
390
+ ```
391
+ ### **`destroy`**
392
+ ```python
393
+ def destroy(
394
+ obj: Architype | Anchor,
395
+ ) -> None:
396
+ """Destroy object."""
397
+ ```
398
+ ### **`get_semstr_type`**
399
+ ```python
400
+ def get_semstr_type(
401
+ file_loc: str,
402
+ scope: str,
403
+ attr: str,
404
+ return_semstr: bool
405
+ ) -> Optional[str]:
406
+ """Jac's get_semstr_type stmt feature."""
407
+ ```
408
+ ### **`obj_scope`**
409
+ ```python
410
+ def obj_scope(
411
+ file_loc: str,
412
+ attr: str
413
+ ) -> str:
414
+ """Jac's get_semstr_type feature."""
415
+ ```
416
+ ### **`get_sem_type`**
417
+ ```python
418
+ def get_sem_type(
419
+ file_loc: str,
420
+ attr: str
421
+ ) -> tuple[str | None, str | None]:
422
+ """Jac's get_semstr_type feature."""
423
+ ```
424
+ ### **`with_llm`**
425
+ ```python
426
+ def with_llm(
427
+ file_loc: str,
428
+ model: Any,
429
+ model_params: dict[str, Any],
430
+ scope: str,
431
+ incl_info: list[tuple[str, str]],
432
+ excl_info: list[tuple[str, str]],
433
+ inputs: list[tuple[str, str, str, Any]],
434
+ outputs: tuple,
435
+ action: str,
436
+ _globals: dict,
437
+ _locals: Mapping,
438
+ ) -> Any:
439
+ """Jac's with_llm stmt feature."""
440
+ ```
441
+ ### **`gen_llm_body`**
442
+ ```python
443
+ def gen_llm_body(
444
+ _pass: PyastGenPass,
445
+ node: ast.Ability
446
+ ) -> list[ast3.AST]:
447
+ """Generate the by LLM body."""
448
+ ```
449
+ ### **`by_llm_call`**
450
+ ```python
451
+ def by_llm_call(
452
+ _pass: PyastGenPass,
453
+ model: ast3.AST,
454
+ model_params: dict[str, ast.Expr],
455
+ scope: ast3.AST,
456
+ inputs: Sequence[Optional[ast3.AST]],
457
+ outputs: Sequence[Optional[ast3.AST]] | ast3.Call,
458
+ action: Optional[ast3.AST],
459
+ include_info: list[tuple[str, ast3.AST]],
460
+ exclude_info: list[tuple[str, ast3.AST]],
461
+ ) -> ast3.Call:
462
+ """Return the LLM Call, e.g. _Jac.with_llm()."""
463
+ ```
464
+ ### **`get_by_llm_call_args`**
465
+ ```python
466
+ def get_by_llm_call_args(
467
+ _pass: PyastGenPass,
468
+ node: ast.FuncCall
469
+ ) -> dict:
470
+ """Get the by LLM call args."""
471
+ ```
jaclang/plugin/spec.py CHANGED
@@ -356,7 +356,7 @@ class JacFeatureSpec(
356
356
 
357
357
  @staticmethod
358
358
  @hookspec(firstresult=True)
359
- def report(expr: Any) -> Any: # noqa: ANN401
359
+ def report(expr: Any, custom: bool) -> None: # noqa: ANN401
360
360
  """Jac's report stmt feature."""
361
361
  raise NotImplementedError
362
362
 
@@ -458,6 +458,7 @@ class JacFeatureSpec(
458
458
  raise NotImplementedError
459
459
 
460
460
  @staticmethod
461
+ @hookspec(firstresult=True)
461
462
  def get_sem_type(file_loc: str, attr: str) -> tuple[str | None, str | None]:
462
463
  """Jac's get_semstr_type feature."""
463
464
  raise NotImplementedError
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import unittest
6
6
  from contextvars import ContextVar
7
+ from dataclasses import MISSING
7
8
  from typing import Any, Callable, Optional, cast
8
9
  from uuid import UUID
9
10
 
@@ -26,6 +27,7 @@ class ExecutionContext:
26
27
 
27
28
  mem: Memory
28
29
  reports: list[Any]
30
+ custom: Any = MISSING
29
31
  system_root: NodeAnchor
30
32
  root: NodeAnchor
31
33
  entry_node: NodeAnchor
@@ -344,14 +344,19 @@ class JacImporter(Importer):
344
344
  cachable=spec.cachable,
345
345
  reload=reload if reload else False,
346
346
  )
347
+
348
+ # Since this is a compile time error, we can safely raise an exception here.
349
+ if not codeobj:
350
+ raise ImportError(f"No bytecode found for {spec.full_target}")
351
+
347
352
  try:
348
- if not codeobj:
349
- raise ImportError(f"No bytecode found for {spec.full_target}")
350
353
  with sys_path_context(spec.caller_dir):
351
354
  exec(codeobj, module.__dict__)
352
355
  except Exception as e:
356
+ logger.error(e)
353
357
  logger.error(dump_traceback(e))
354
358
  raise e
359
+
355
360
  import_return = ImportReturn(module, unique_loaded_items, self)
356
361
  if spec.items:
357
362
  import_return.process_items(
@@ -1,5 +1,7 @@
1
1
  """Jac Machine module."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import inspect
4
6
  import marshal
5
7
  import os
@@ -12,6 +14,7 @@ from typing import Optional, Union
12
14
  from jaclang.compiler.absyntree import Module
13
15
  from jaclang.compiler.compile import compile_jac
14
16
  from jaclang.compiler.constant import Constants as Con
17
+ from jaclang.compiler.semtable import SemRegistry
15
18
  from jaclang.runtimelib.architype import (
16
19
  Architype,
17
20
  EdgeArchitype,
@@ -70,6 +73,14 @@ class JacMachine:
70
73
  )
71
74
  return None
72
75
 
76
+ def get_sem_ir(self, mod_sem_ir: SemRegistry | None) -> None:
77
+ """Update semtable on the attached JacProgram."""
78
+ if self.jac_program and mod_sem_ir:
79
+ if self.jac_program.sem_ir:
80
+ self.jac_program.sem_ir.registry.update(mod_sem_ir.registry)
81
+ else:
82
+ self.jac_program.sem_ir = mod_sem_ir
83
+
73
84
  def load_module(self, module_name: str, module: types.ModuleType) -> None:
74
85
  """Load a module into the machine."""
75
86
  self.loaded_modules[module_name] = module
@@ -263,14 +274,18 @@ class JacMachine:
263
274
 
264
275
 
265
276
  class JacProgram:
266
- """Class to hold the mod_bundle and bytecode for Jac modules."""
277
+ """Class to hold the mod_bundle bytecode and sem_ir for Jac modules."""
267
278
 
268
279
  def __init__(
269
- self, mod_bundle: Optional[Module], bytecode: Optional[dict[str, bytes]]
280
+ self,
281
+ mod_bundle: Optional[Module],
282
+ bytecode: Optional[dict[str, bytes]],
283
+ sem_ir: Optional[SemRegistry],
270
284
  ) -> None:
271
285
  """Initialize the JacProgram object."""
272
286
  self.mod_bundle = mod_bundle
273
287
  self.bytecode = bytecode or {}
288
+ self.sem_ir = sem_ir if sem_ir else SemRegistry()
274
289
 
275
290
  def get_bytecode(
276
291
  self,
@@ -292,10 +307,10 @@ class JacProgram:
292
307
 
293
308
  result = compile_jac(full_target, cache_result=cachable)
294
309
  if result.errors_had or not result.ir.gen.py_bytecode:
295
- logger.error(
296
- f"While importing {len(result.errors_had)} errors"
297
- f" found in {full_target}"
298
- )
310
+ for alrt in result.errors_had:
311
+ # We're not logging here, it already gets logged as the errors were added to the errors_had list.
312
+ # Regardless of the logging, this needs to be sent to the end user, so we'll printing it to stderr.
313
+ logger.error(alrt.pretty_print())
299
314
  return None
300
315
  if result.ir.gen.py_bytecode is not None:
301
316
  return marshal.loads(result.ir.gen.py_bytecode)
jaclang/settings.py CHANGED
@@ -58,6 +58,9 @@ class Settings:
58
58
  """Override settings from environment variables if available."""
59
59
  for key in [f.name for f in fields(self)]:
60
60
  env_value = os.getenv("JACLANG_" + key.upper())
61
+ env_value = (
62
+ env_value if env_value is not None else os.getenv("JAC_" + key.upper())
63
+ )
61
64
  if env_value is not None:
62
65
  setattr(self, key, self.convert_type(env_value))
63
66
 
@@ -27,11 +27,11 @@ with entry{
27
27
  d3=dotgen(b[2],edge_limit=5,depth=5);l3=d3|>len; #generate dot for all connected with b[1] node
28
28
  d4=dotgen(b[1],bfs=True,edge_type= ["Edge1"],node_limit=100,edge_limit=900,depth=300);l4=d4|>len; #generate dot from nodes with depth 3 connected with b[1] node
29
29
  d5=dotgen(b[1],node_limit=10,edge_limit=90);l5:=d5|>len; #generate dot from nodes with depth 3 connected with b[1] node
30
- print(d1.count('a(val')==12,d1.count('#FFFFE0')==3,'Root' in d1,d1.count('GenericEdge')==30);
31
- print(d2.count('a(val')==19,d2.count('#F5E5FF')==2 ,'Edge1' not in d2,d2.count('GenericEdge')==42);
32
- print(d3.count('a(val')==6,d3.count("GenericEdge")==5,d3.count('#F5E5FF')==1);
33
- print(d4.count("a(val")==25,d4.count("GenericEdge")==66,d4.count('#FFF0F')==3);
34
- print(d5.count("Edge1(val=6)")==2, d5.count("GenericEdge()")==24);
30
+ print(d1.count('a(val')==12,d1.count('#FFFFE0')==3,'Root' in d1,d1.count('label=""')==30);
31
+ print(d2.count('a(val')==19,d2.count('#F5E5FF')==2 ,'Edge1' not in d2,d2.count('label=""')==42);
32
+ print(d3.count('a(val')==6,d3.count('label=""')==5,d3.count('#F5E5FF')==1);
33
+ print(d4.count("a(val")==25,d4.count('label=""')==66,d4.count('#FFF0F')==3);
34
+ print(d5.count("Edge1(val=6)")==2, d5.count('label=""')==24);
35
35
  # print(l3<l2);
36
36
  # print(d1);
37
37
  # print(d2);
@@ -39,4 +39,4 @@ with entry{
39
39
  # print(d4);
40
40
  # print(dotgen(node=b[2],bfs=True,depth=3.96,edge_limit=12,node_limit=12.96));
41
41
 
42
- }
42
+ }
@@ -1,20 +1,25 @@
1
- obj outer{
2
- has o1:int=9;
1
+ obj outer {
2
+ has o1: int = 9;
3
3
 
4
- obj inner{
5
- has i1:int=8;
4
+ obj inner {
5
+ has i1: int = 8;
6
6
  }
7
- can foo(){
7
+ can foo() {
8
8
  return 'foo';
9
9
  }
10
- enum color{
10
+ enum color {
11
11
  red,
12
12
  green,
13
- blue
13
+ blue,
14
+ with entry {
15
+ print('Initializing role system..');
16
+ },
17
+ can foo -> str {
18
+ return 'Accessing privileged Data';
14
19
  }
15
-
20
+ }
16
21
  }
17
22
 
18
- with entry{
19
- print(outer.color.green.value);
20
- }
23
+ with entry {
24
+ print(outer.color.green.value, outer.color.foo());
25
+ }