jaclang 0.7.23__py3-none-any.whl → 0.7.26__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 (68) hide show
  1. jaclang/cli/cli.py +46 -29
  2. jaclang/compiler/__init__.py +2 -2
  3. jaclang/compiler/absyntree.py +114 -66
  4. jaclang/compiler/codeloc.py +7 -2
  5. jaclang/compiler/compile.py +10 -3
  6. jaclang/compiler/jac.lark +4 -1
  7. jaclang/compiler/parser.py +63 -43
  8. jaclang/compiler/passes/ir_pass.py +2 -2
  9. jaclang/compiler/passes/main/def_impl_match_pass.py +83 -0
  10. jaclang/compiler/passes/main/def_use_pass.py +1 -2
  11. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +146 -123
  12. jaclang/compiler/passes/main/import_pass.py +6 -2
  13. jaclang/compiler/passes/main/pyast_gen_pass.py +46 -20
  14. jaclang/compiler/passes/main/pyast_load_pass.py +56 -41
  15. jaclang/compiler/passes/main/pyjac_ast_link_pass.py +7 -7
  16. jaclang/compiler/passes/main/registry_pass.py +3 -12
  17. jaclang/compiler/passes/main/sym_tab_build_pass.py +1 -2
  18. jaclang/compiler/passes/main/tests/fixtures/defn_decl_mismatch.jac +19 -0
  19. jaclang/compiler/passes/main/tests/fixtures/fstrings.jac +2 -0
  20. jaclang/compiler/passes/main/tests/fixtures/uninitialized_hasvars.jac +26 -0
  21. jaclang/compiler/passes/main/tests/test_decl_def_match_pass.py +66 -0
  22. jaclang/compiler/passes/main/tests/test_def_use_pass.py +3 -3
  23. jaclang/compiler/passes/main/tests/test_registry_pass.py +2 -10
  24. jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
  25. jaclang/compiler/passes/tool/jac_formatter_pass.py +2 -2
  26. jaclang/compiler/passes/tool/tests/fixtures/corelib.jac +3 -3
  27. jaclang/compiler/passes/tool/tests/fixtures/corelib_fmt.jac +3 -3
  28. jaclang/compiler/passes/transform.py +27 -3
  29. jaclang/compiler/passes/utils/mypy_ast_build.py +246 -26
  30. jaclang/compiler/symtable.py +6 -0
  31. jaclang/compiler/tests/test_importer.py +2 -2
  32. jaclang/compiler/tests/test_parser.py +7 -1
  33. jaclang/langserve/engine.py +14 -12
  34. jaclang/langserve/server.py +7 -2
  35. jaclang/langserve/tests/test_server.py +1 -1
  36. jaclang/langserve/utils.py +17 -3
  37. jaclang/plugin/default.py +80 -43
  38. jaclang/plugin/feature.py +12 -2
  39. jaclang/plugin/plugin.md +471 -0
  40. jaclang/plugin/spec.py +14 -1
  41. jaclang/plugin/tests/fixtures/graph_purger.jac +101 -0
  42. jaclang/plugin/tests/fixtures/other_root_access.jac +9 -0
  43. jaclang/plugin/tests/test_jaseci.py +126 -6
  44. jaclang/runtimelib/architype.py +12 -1
  45. jaclang/runtimelib/context.py +2 -0
  46. jaclang/runtimelib/importer.py +7 -2
  47. jaclang/runtimelib/machine.py +21 -6
  48. jaclang/runtimelib/memory.py +5 -1
  49. jaclang/settings.py +3 -0
  50. jaclang/tests/fixtures/architype_def_bug.jac +17 -0
  51. jaclang/tests/fixtures/builtin_dotgen.jac +6 -6
  52. jaclang/tests/fixtures/decl_defn_param_name.jac +19 -0
  53. jaclang/tests/fixtures/enum_inside_archtype.jac +16 -11
  54. jaclang/tests/fixtures/expr_type.jac +54 -0
  55. jaclang/tests/fixtures/glob_multivar_statement.jac +15 -0
  56. jaclang/tests/fixtures/multi_dim_array_split.jac +19 -0
  57. jaclang/tests/fixtures/registry.jac +20 -8
  58. jaclang/tests/foo/__init__.jac +0 -0
  59. jaclang/tests/main.jac +2 -0
  60. jaclang/tests/test_cli.py +86 -4
  61. jaclang/tests/test_language.py +104 -27
  62. jaclang/utils/helpers.py +92 -14
  63. jaclang/utils/lang_tools.py +6 -2
  64. jaclang/utils/treeprinter.py +4 -2
  65. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/METADATA +2 -1
  66. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/RECORD +68 -57
  67. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/WHEEL +1 -1
  68. {jaclang-0.7.23.dist-info → jaclang-0.7.26.dist-info}/entry_points.txt +0 -0
@@ -5,6 +5,7 @@ from __future__ import annotations
5
5
  import ast as ast3
6
6
  import builtins
7
7
  import os
8
+ from dataclasses import dataclass
8
9
  from hashlib import md5
9
10
  from types import EllipsisType
10
11
  from typing import (
@@ -139,7 +140,7 @@ class AstNode:
139
140
  return Token(
140
141
  name=name,
141
142
  value=value,
142
- file_path=self.loc.mod_path,
143
+ orig_src=self.loc.orig_src,
143
144
  col_start=self.loc.col_start,
144
145
  col_end=0,
145
146
  line=self.loc.first_line,
@@ -248,9 +249,9 @@ class AstSymbolNode(AstNode):
248
249
  return self.name_spec.py_ctx_func
249
250
 
250
251
  @property
251
- def sym_type(self) -> str:
252
+ def expr_type(self) -> str:
252
253
  """Get symbol type."""
253
- return self.name_spec.sym_type
254
+ return self.name_spec.expr_type
254
255
 
255
256
  @property
256
257
  def type_sym_tab(self) -> Optional[SymbolTable]:
@@ -346,6 +347,32 @@ class WalkerStmtOnlyNode(AstNode):
346
347
  class Expr(AstNode):
347
348
  """Expr node type for Jac Ast."""
348
349
 
350
+ def __init__(self, type_src: Optional[Expr] = None) -> None:
351
+ """Initialize expression node."""
352
+ self.type_src = type_src or self # Only used for ArchRef
353
+ self._sym_type: str = "NoType"
354
+ self._type_sym_tab: Optional[SymbolTable] = None
355
+
356
+ @property
357
+ def expr_type(self) -> str:
358
+ """Get symbol type."""
359
+ return self.type_src._sym_type
360
+
361
+ @expr_type.setter
362
+ def expr_type(self, sym_type: str) -> None:
363
+ """Set symbol type."""
364
+ self.type_src._sym_type = sym_type
365
+
366
+ @property
367
+ def type_sym_tab(self) -> Optional[SymbolTable]:
368
+ """Get type symbol table."""
369
+ return self.type_src._type_sym_tab
370
+
371
+ @type_sym_tab.setter
372
+ def type_sym_tab(self, type_sym_tab: SymbolTable) -> None:
373
+ """Set type symbol table."""
374
+ self.type_src._type_sym_tab = type_sym_tab
375
+
349
376
 
350
377
  class AtomExpr(Expr, AstSymbolStubNode):
351
378
  """AtomExpr node type for Jac Ast."""
@@ -398,7 +425,7 @@ class AstImplOnlyNode(CodeBlockStmt, ElementStmt, AstSymbolNode):
398
425
  def create_impl_name_node(self) -> Name:
399
426
  """Create impl name."""
400
427
  ret = Name(
401
- file_path=self.target.archs[-1].loc.mod_path,
428
+ orig_src=self.target.archs[-1].loc.orig_src,
402
429
  name=Tok.NAME.value,
403
430
  value=self.target.py_resolve_name(),
404
431
  col_start=self.target.archs[0].loc.col_start,
@@ -435,8 +462,7 @@ class NameAtom(AtomExpr, EnumBlockStmt):
435
462
  self._sym_name: str = ""
436
463
  self._sym_category: SymbolType = SymbolType.UNKNOWN
437
464
  self._py_ctx_func: Type[ast3.AST] = ast3.Load
438
- self._sym_type: str = "NoType"
439
- self._type_sym_tab: Optional[SymbolTable] = None
465
+ AtomExpr.__init__(self)
440
466
 
441
467
  @property
442
468
  def sym(self) -> Optional[Symbol]:
@@ -461,7 +487,7 @@ class NameAtom(AtomExpr, EnumBlockStmt):
461
487
  @property
462
488
  def clean_type(self) -> str:
463
489
  """Get clean type."""
464
- ret_type = self.sym_type.replace("builtins.", "").replace("NoType", "")
490
+ ret_type = self.expr_type.replace("builtins.", "").replace("NoType", "")
465
491
  return ret_type
466
492
 
467
493
  @property
@@ -474,26 +500,6 @@ class NameAtom(AtomExpr, EnumBlockStmt):
474
500
  """Set python context function."""
475
501
  self._py_ctx_func = py_ctx_func
476
502
 
477
- @property
478
- def sym_type(self) -> str:
479
- """Get symbol type."""
480
- return self._sym_type
481
-
482
- @sym_type.setter
483
- def sym_type(self, sym_type: str) -> None:
484
- """Set symbol type."""
485
- self._sym_type = sym_type
486
-
487
- @property
488
- def type_sym_tab(self) -> Optional[SymbolTable]:
489
- """Get type symbol table."""
490
- return self._type_sym_tab
491
-
492
- @type_sym_tab.setter
493
- def type_sym_tab(self, type_sym_tab: SymbolTable) -> None:
494
- """Set type symbol table."""
495
- self._type_sym_tab = type_sym_tab
496
-
497
503
  @property
498
504
  def sem_token(self) -> Optional[tuple[SemTokType, SemTokMod]]:
499
505
  """Resolve semantic token."""
@@ -745,7 +751,7 @@ class Test(AstSymbolNode, ElementStmt):
745
751
  name
746
752
  if isinstance(name, Name)
747
753
  else Name(
748
- file_path=name.file_path,
754
+ orig_src=name.orig_src,
749
755
  name=Tok.NAME.value,
750
756
  value=f"_jac_gen_{Test.TEST_COUNT}",
751
757
  col_start=name.loc.col_start,
@@ -1261,6 +1267,9 @@ class Enum(ArchSpec, AstAccessNode, AstImplNeedingNode, ArchBlockStmt):
1261
1267
  res = res and self.semstr.normalize(deep) if self.semstr else res
1262
1268
  res = res and self.decorators.normalize(deep) if self.decorators else res
1263
1269
  new_kid: list[AstNode] = []
1270
+ if self.decorators:
1271
+ new_kid.append(self.gen_token(Tok.DECOR_OP))
1272
+ new_kid.append(self.decorators)
1264
1273
  if self.doc:
1265
1274
  new_kid.append(self.doc)
1266
1275
  new_kid.append(self.gen_token(Tok.KW_ENUM))
@@ -2527,6 +2536,7 @@ class AwaitExpr(Expr):
2527
2536
  """Initialize sync statement node."""
2528
2537
  self.target = target
2529
2538
  AstNode.__init__(self, kid=kid)
2539
+ Expr.__init__(self)
2530
2540
 
2531
2541
  def normalize(self, deep: bool = False) -> bool:
2532
2542
  """Normalize sync statement node."""
@@ -2655,6 +2665,7 @@ class BinaryExpr(Expr):
2655
2665
  self.right = right
2656
2666
  self.op = op
2657
2667
  AstNode.__init__(self, kid=kid)
2668
+ Expr.__init__(self)
2658
2669
 
2659
2670
  def normalize(self, deep: bool = False) -> bool:
2660
2671
  """Normalize ast node."""
@@ -2689,6 +2700,7 @@ class CompareExpr(Expr):
2689
2700
  self.rights = rights
2690
2701
  self.ops = ops
2691
2702
  AstNode.__init__(self, kid=kid)
2703
+ Expr.__init__(self)
2692
2704
 
2693
2705
  def normalize(self, deep: bool = False) -> bool:
2694
2706
  """Normalize ast node."""
@@ -2720,6 +2732,7 @@ class BoolExpr(Expr):
2720
2732
  self.values = values
2721
2733
  self.op = op
2722
2734
  AstNode.__init__(self, kid=kid)
2735
+ Expr.__init__(self)
2723
2736
 
2724
2737
  def normalize(self, deep: bool = False) -> bool:
2725
2738
  """Normalize ast node."""
@@ -2750,6 +2763,7 @@ class LambdaExpr(Expr):
2750
2763
  self.signature = signature
2751
2764
  self.body = body
2752
2765
  AstNode.__init__(self, kid=kid)
2766
+ Expr.__init__(self)
2753
2767
 
2754
2768
  def normalize(self, deep: bool = False) -> bool:
2755
2769
  """Normalize ast node."""
@@ -2782,6 +2796,7 @@ class UnaryExpr(Expr):
2782
2796
  self.operand = operand
2783
2797
  self.op = op
2784
2798
  AstNode.__init__(self, kid=kid)
2799
+ Expr.__init__(self)
2785
2800
 
2786
2801
  def normalize(self, deep: bool = False) -> bool:
2787
2802
  """Normalize ast node."""
@@ -2809,6 +2824,7 @@ class IfElseExpr(Expr):
2809
2824
  self.value = value
2810
2825
  self.else_value = else_value
2811
2826
  AstNode.__init__(self, kid=kid)
2827
+ Expr.__init__(self)
2812
2828
 
2813
2829
  def normalize(self, deep: bool = False) -> bool:
2814
2830
  """Normalize ast node."""
@@ -2839,6 +2855,7 @@ class MultiString(AtomExpr):
2839
2855
  """Initialize multi string expression node."""
2840
2856
  self.strings = strings
2841
2857
  AstNode.__init__(self, kid=kid)
2858
+ Expr.__init__(self)
2842
2859
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.STRING)
2843
2860
 
2844
2861
  def normalize(self, deep: bool = False) -> bool:
@@ -2865,6 +2882,7 @@ class FString(AtomExpr):
2865
2882
  """Initialize fstring expression node."""
2866
2883
  self.parts = parts
2867
2884
  AstNode.__init__(self, kid=kid)
2885
+ Expr.__init__(self)
2868
2886
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.STRING)
2869
2887
 
2870
2888
  def normalize(self, deep: bool = False) -> bool:
@@ -2906,6 +2924,7 @@ class ListVal(AtomExpr):
2906
2924
  """Initialize value node."""
2907
2925
  self.values = values
2908
2926
  AstNode.__init__(self, kid=kid)
2927
+ Expr.__init__(self)
2909
2928
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2910
2929
 
2911
2930
  def normalize(self, deep: bool = False) -> bool:
@@ -2934,6 +2953,7 @@ class SetVal(AtomExpr):
2934
2953
  """Initialize value node."""
2935
2954
  self.values = values
2936
2955
  AstNode.__init__(self, kid=kid)
2956
+ Expr.__init__(self)
2937
2957
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2938
2958
 
2939
2959
  def normalize(self, deep: bool = False) -> bool:
@@ -2962,6 +2982,7 @@ class TupleVal(AtomExpr):
2962
2982
  """Initialize tuple value node."""
2963
2983
  self.values = values
2964
2984
  AstNode.__init__(self, kid=kid)
2985
+ Expr.__init__(self)
2965
2986
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
2966
2987
 
2967
2988
  def normalize(self, deep: bool = False) -> bool:
@@ -3005,6 +3026,7 @@ class DictVal(AtomExpr):
3005
3026
  """Initialize dict expression node."""
3006
3027
  self.kv_pairs = kv_pairs
3007
3028
  AstNode.__init__(self, kid=kid)
3029
+ Expr.__init__(self)
3008
3030
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3009
3031
 
3010
3032
  def normalize(self, deep: bool = False) -> bool:
@@ -3138,6 +3160,7 @@ class ListCompr(AtomExpr):
3138
3160
  self.out_expr = out_expr
3139
3161
  self.compr = compr
3140
3162
  AstNode.__init__(self, kid=kid)
3163
+ Expr.__init__(self)
3141
3164
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3142
3165
 
3143
3166
  def normalize(self, deep: bool = False) -> bool:
@@ -3213,6 +3236,7 @@ class DictCompr(AtomExpr):
3213
3236
  self.kv_pair = kv_pair
3214
3237
  self.compr = compr
3215
3238
  AstNode.__init__(self, kid=kid)
3239
+ Expr.__init__(self)
3216
3240
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3217
3241
 
3218
3242
  def normalize(self, deep: bool = False) -> bool:
@@ -3251,6 +3275,7 @@ class AtomTrailer(Expr):
3251
3275
  self.is_null_ok = is_null_ok
3252
3276
  self.is_genai = is_genai
3253
3277
  AstNode.__init__(self, kid=kid)
3278
+ Expr.__init__(self)
3254
3279
 
3255
3280
  def normalize(self, deep: bool = True) -> bool:
3256
3281
  """Normalize ast node."""
@@ -3296,6 +3321,7 @@ class AtomUnit(Expr):
3296
3321
  """Initialize atom unit expression node."""
3297
3322
  self.value = value
3298
3323
  AstNode.__init__(self, kid=kid)
3324
+ Expr.__init__(self)
3299
3325
 
3300
3326
  def normalize(self, deep: bool = True) -> bool:
3301
3327
  """Normalize ast node."""
@@ -3323,6 +3349,7 @@ class YieldExpr(Expr):
3323
3349
  self.expr = expr
3324
3350
  self.with_from = with_from
3325
3351
  AstNode.__init__(self, kid=kid)
3352
+ Expr.__init__(self)
3326
3353
 
3327
3354
  def normalize(self, deep: bool = False) -> bool:
3328
3355
  """Normalize yield statement node."""
@@ -3354,6 +3381,7 @@ class FuncCall(Expr):
3354
3381
  self.params = params
3355
3382
  self.genai_call = genai_call
3356
3383
  AstNode.__init__(self, kid=kid)
3384
+ Expr.__init__(self)
3357
3385
 
3358
3386
  def normalize(self, deep: bool = True) -> bool:
3359
3387
  """Normalize ast node."""
@@ -3374,42 +3402,51 @@ class FuncCall(Expr):
3374
3402
  class IndexSlice(AtomExpr):
3375
3403
  """IndexSlice node type for Jac Ast."""
3376
3404
 
3405
+ @dataclass
3406
+ class Slice:
3407
+ """Slice node for index slice."""
3408
+
3409
+ start: Optional[Expr]
3410
+ stop: Optional[Expr]
3411
+ step: Optional[Expr]
3412
+
3377
3413
  def __init__(
3378
3414
  self,
3379
- start: Optional[Expr],
3380
- stop: Optional[Expr],
3381
- step: Optional[Expr],
3415
+ slices: list[Slice],
3382
3416
  is_range: bool,
3383
3417
  kid: Sequence[AstNode],
3384
3418
  ) -> None:
3385
3419
  """Initialize index slice expression node."""
3386
- self.start = start
3387
- self.stop = stop
3388
- self.step = step
3420
+ self.slices = slices
3389
3421
  self.is_range = is_range
3390
3422
  AstNode.__init__(self, kid=kid)
3423
+ Expr.__init__(self)
3391
3424
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3392
3425
 
3393
3426
  def normalize(self, deep: bool = True) -> bool:
3394
3427
  """Normalize ast node."""
3395
3428
  res = True
3396
3429
  if deep:
3397
- res = self.start.normalize(deep) if self.start else res
3398
- res = res and self.stop.normalize(deep) if self.stop else res
3399
- res = res and self.step.normalize(deep) if self.step else res
3430
+ for slice in self.slices:
3431
+ res = slice.start.normalize(deep) if slice.start else res
3432
+ res = res and slice.stop.normalize(deep) if slice.stop else res
3433
+ res = res and slice.step.normalize(deep) if slice.step else res
3400
3434
  new_kid: list[AstNode] = []
3401
3435
  new_kid.append(self.gen_token(Tok.LSQUARE))
3402
3436
  if self.is_range:
3403
- if self.start:
3404
- new_kid.append(self.start)
3405
- if self.stop:
3406
- new_kid.append(self.gen_token(Tok.COLON))
3407
- new_kid.append(self.stop)
3408
- if self.step:
3437
+ for i, slice in enumerate(self.slices):
3438
+ if i > 0:
3439
+ new_kid.append(self.gen_token(Tok.COMMA))
3440
+ if slice.start:
3441
+ new_kid.append(slice.start)
3409
3442
  new_kid.append(self.gen_token(Tok.COLON))
3410
- new_kid.append(self.step)
3411
- elif self.start:
3412
- new_kid.append(self.start)
3443
+ if slice.stop:
3444
+ new_kid.append(slice.stop)
3445
+ if slice.step:
3446
+ new_kid.append(self.gen_token(Tok.COLON))
3447
+ new_kid.append(slice.step)
3448
+ elif len(self.slices) == 1 and self.slices[0].start:
3449
+ new_kid.append(self.slices[0].start)
3413
3450
  else:
3414
3451
  res = False
3415
3452
  new_kid.append(self.gen_token(Tok.RSQUARE))
@@ -3430,6 +3467,7 @@ class ArchRef(AtomExpr):
3430
3467
  self.arch_name = arch_name
3431
3468
  self.arch_type = arch_type
3432
3469
  AstNode.__init__(self, kid=kid)
3470
+ Expr.__init__(self, type_src=arch_name)
3433
3471
  AstSymbolNode.__init__(
3434
3472
  self,
3435
3473
  sym_name=arch_name.sym_name,
@@ -3460,6 +3498,7 @@ class EdgeRefTrailer(Expr):
3460
3498
  self.chain = chain
3461
3499
  self.edges_only = edges_only
3462
3500
  AstNode.__init__(self, kid=kid)
3501
+ Expr.__init__(self)
3463
3502
 
3464
3503
  def normalize(self, deep: bool = True) -> bool:
3465
3504
  """Normalize ast node."""
@@ -3489,6 +3528,7 @@ class EdgeOpRef(WalkerStmtOnlyNode, AtomExpr):
3489
3528
  self.filter_cond = filter_cond
3490
3529
  self.edge_dir = edge_dir
3491
3530
  AstNode.__init__(self, kid=kid)
3531
+ Expr.__init__(self)
3492
3532
  WalkerStmtOnlyNode.__init__(self)
3493
3533
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3494
3534
 
@@ -3619,6 +3659,7 @@ class FilterCompr(AtomExpr):
3619
3659
  self.f_type = f_type
3620
3660
  self.compares = compares
3621
3661
  AstNode.__init__(self, kid=kid)
3662
+ Expr.__init__(self)
3622
3663
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3623
3664
 
3624
3665
  def normalize(self, deep: bool = False) -> bool:
@@ -3656,6 +3697,7 @@ class AssignCompr(AtomExpr):
3656
3697
  """Initialize assign compr expression node."""
3657
3698
  self.assigns = assigns
3658
3699
  AstNode.__init__(self, kid=kid)
3700
+ Expr.__init__(self)
3659
3701
  AstSymbolStubNode.__init__(self, sym_type=SymbolType.SEQUENCE)
3660
3702
 
3661
3703
  def normalize(self, deep: bool = False) -> bool:
@@ -3813,7 +3855,7 @@ class MatchWild(MatchPattern):
3813
3855
  self,
3814
3856
  nodes=[
3815
3857
  Name(
3816
- file_path=self.loc.mod_path,
3858
+ orig_src=self.loc.orig_src,
3817
3859
  name=Tok.NAME,
3818
3860
  value="_",
3819
3861
  col_start=self.loc.col_start,
@@ -4023,7 +4065,7 @@ class Token(AstNode):
4023
4065
 
4024
4066
  def __init__(
4025
4067
  self,
4026
- file_path: str,
4068
+ orig_src: JacSource,
4027
4069
  name: str,
4028
4070
  value: str,
4029
4071
  line: int,
@@ -4034,7 +4076,7 @@ class Token(AstNode):
4034
4076
  pos_end: int,
4035
4077
  ) -> None:
4036
4078
  """Initialize token."""
4037
- self.file_path = file_path
4079
+ self.orig_src = orig_src
4038
4080
  self.name = name
4039
4081
  self.value = value
4040
4082
  self.line_no = line
@@ -4059,7 +4101,7 @@ class Name(Token, NameAtom):
4059
4101
 
4060
4102
  def __init__(
4061
4103
  self,
4062
- file_path: str,
4104
+ orig_src: JacSource,
4063
4105
  name: str,
4064
4106
  value: str,
4065
4107
  line: int,
@@ -4076,7 +4118,7 @@ class Name(Token, NameAtom):
4076
4118
  self.is_kwesc = is_kwesc
4077
4119
  Token.__init__(
4078
4120
  self,
4079
- file_path=file_path,
4121
+ orig_src=orig_src,
4080
4122
  name=name,
4081
4123
  value=value,
4082
4124
  line=line,
@@ -4107,7 +4149,7 @@ class Name(Token, NameAtom):
4107
4149
  ) -> Name:
4108
4150
  """Generate name from node."""
4109
4151
  ret = Name(
4110
- file_path=node.loc.mod_path,
4152
+ orig_src=node.loc.orig_src,
4111
4153
  name=Tok.NAME.value,
4112
4154
  value=name_str,
4113
4155
  col_start=node.loc.col_start,
@@ -4134,7 +4176,7 @@ class SpecialVarRef(Name):
4134
4176
  self.orig = var
4135
4177
  Name.__init__(
4136
4178
  self,
4137
- file_path=var.file_path,
4179
+ orig_src=var.orig_src,
4138
4180
  name=var.name,
4139
4181
  value=self.py_resolve_name(), # TODO: This shouldnt be necessary
4140
4182
  line=var.line_no,
@@ -4190,7 +4232,7 @@ class Literal(Token, AtomExpr):
4190
4232
 
4191
4233
  def __init__(
4192
4234
  self,
4193
- file_path: str,
4235
+ orig_src: JacSource,
4194
4236
  name: str,
4195
4237
  value: str,
4196
4238
  line: int,
@@ -4203,7 +4245,7 @@ class Literal(Token, AtomExpr):
4203
4245
  """Initialize token."""
4204
4246
  Token.__init__(
4205
4247
  self,
4206
- file_path=file_path,
4248
+ orig_src=orig_src,
4207
4249
  name=name,
4208
4250
  value=value,
4209
4251
  line=line,
@@ -4214,6 +4256,7 @@ class Literal(Token, AtomExpr):
4214
4256
  pos_end=pos_end,
4215
4257
  )
4216
4258
  AstSymbolStubNode.__init__(self, sym_type=self.SYMBOL_TYPE)
4259
+ Expr.__init__(self)
4217
4260
 
4218
4261
  @property
4219
4262
  def lit_value(
@@ -4278,10 +4321,9 @@ class String(Literal):
4278
4321
  elif self.value.startswith(("'", '"')):
4279
4322
  repr_str = self.value.encode().decode("unicode_escape")
4280
4323
  if (
4281
- self.value.startswith('"""')
4282
- and self.value.endswith('"""')
4283
- and not self.find_parent_of_type(FString)
4284
- ):
4324
+ (self.value.startswith('"""') and self.value.endswith('"""'))
4325
+ or (self.value.startswith("'''") and self.value.endswith("'''"))
4326
+ ) and not self.find_parent_of_type(FString):
4285
4327
  return repr_str[3:-3]
4286
4328
  if (not self.find_parent_of_type(FString)) or (
4287
4329
  not (
@@ -4343,11 +4385,11 @@ class Ellipsis(Literal):
4343
4385
  class EmptyToken(Token):
4344
4386
  """EmptyToken node type for Jac Ast."""
4345
4387
 
4346
- def __init__(self, file_path: str = "") -> None:
4388
+ def __init__(self, orig_src: JacSource | None = None) -> None:
4347
4389
  """Initialize empty token."""
4348
4390
  super().__init__(
4349
4391
  name="EmptyToken",
4350
- file_path=file_path,
4392
+ orig_src=orig_src or JacSource("", ""),
4351
4393
  value="",
4352
4394
  line=0,
4353
4395
  end_line=0,
@@ -4367,7 +4409,7 @@ class CommentToken(Token):
4367
4409
 
4368
4410
  def __init__(
4369
4411
  self,
4370
- file_path: str,
4412
+ orig_src: JacSource,
4371
4413
  name: str,
4372
4414
  value: str,
4373
4415
  line: int,
@@ -4384,7 +4426,7 @@ class CommentToken(Token):
4384
4426
 
4385
4427
  Token.__init__(
4386
4428
  self,
4387
- file_path=file_path,
4429
+ orig_src=orig_src,
4388
4430
  name=name,
4389
4431
  value=value,
4390
4432
  line=line,
@@ -4404,7 +4446,7 @@ class JacSource(EmptyToken):
4404
4446
 
4405
4447
  def __init__(self, source: str, mod_path: str) -> None:
4406
4448
  """Initialize source string."""
4407
- super().__init__()
4449
+ super().__init__(self)
4408
4450
  self.value = source
4409
4451
  self.hash = md5(source.encode()).hexdigest()
4410
4452
  self.file_path = mod_path
@@ -4419,8 +4461,14 @@ class JacSource(EmptyToken):
4419
4461
  class PythonModuleAst(EmptyToken):
4420
4462
  """SourceString node type for Jac Ast."""
4421
4463
 
4422
- def __init__(self, ast: ast3.Module, mod_path: str) -> None:
4464
+ def __init__(self, ast: ast3.Module, orig_src: JacSource) -> None:
4423
4465
  """Initialize source string."""
4424
4466
  super().__init__()
4425
4467
  self.ast = ast
4426
- self.file_path = mod_path
4468
+ self.orig_src = orig_src
4469
+
4470
+ # This bellow attribute is un-necessary since it already exists in the orig_src
4471
+ # however I'm keeping it here not to break existing code trying to access file_path.
4472
+ # We can remove this in the future once we safley remove all references to it and
4473
+ # use orig_src.
4474
+ self.file_path = orig_src.file_path
@@ -9,7 +9,7 @@ from typing import Optional, TYPE_CHECKING
9
9
  from jaclang.vendor.mypy.nodes import Node as MypyNode
10
10
 
11
11
  if TYPE_CHECKING:
12
- from jaclang.compiler.absyntree import Token
12
+ from jaclang.compiler.absyntree import JacSource, Token
13
13
 
14
14
 
15
15
  @dataclass
@@ -42,10 +42,15 @@ class CodeLocInfo:
42
42
  self.first_tok = first_tok
43
43
  self.last_tok = last_tok
44
44
 
45
+ @property
46
+ def orig_src(self) -> JacSource:
47
+ """Get file source."""
48
+ return self.first_tok.orig_src
49
+
45
50
  @property
46
51
  def mod_path(self) -> str:
47
52
  """Get line number."""
48
- return self.first_tok.file_path
53
+ return self.first_tok.orig_src.file_path
49
54
 
50
55
  @property
51
56
  def first_line(self) -> int:
@@ -16,11 +16,13 @@ def compile_jac(file_path: str, cache_result: bool = False) -> Pass:
16
16
  file_path=file_path,
17
17
  schedule=pass_schedule,
18
18
  )
19
- if cache_result and isinstance(code.ir, ast.Module):
19
+ # If there is syntax error, the code will be an instance of JacParser as there is
20
+ # no more passes were processed, in that case we can ignore it.
21
+ had_syntax_error = isinstance(code, JacParser) and len(code.errors_had) != 0
22
+ if cache_result and (not had_syntax_error) and isinstance(code.ir, ast.Module):
20
23
  print_pass = PyOutPass(input_ir=code.ir, prior=code)
21
24
  return print_pass
22
- else:
23
- return code
25
+ return code
24
26
 
25
27
 
26
28
  def jac_file_to_pass(
@@ -49,6 +51,11 @@ def jac_str_to_pass(
49
51
  target = schedule[-1] if schedule else None
50
52
  source = ast.JacSource(jac_str, mod_path=file_path)
51
53
  ast_ret: Pass = JacParser(input_ir=source)
54
+
55
+ # If there is syntax error, no point in processing in further passes.
56
+ if len(ast_ret.errors_had) != 0:
57
+ return ast_ret
58
+
52
59
  for i in schedule:
53
60
  if i == target:
54
61
  break
jaclang/compiler/jac.lark CHANGED
@@ -358,7 +358,10 @@ atomic_chain: atomic_chain NULL_OK? (filter_compr | assign_compr | index_slice)
358
358
  | atomic_chain NULL_OK? (DOT_BKWD | DOT_FWD | DOT) named_ref
359
359
  | (atomic_call | atom | edge_ref_chain)
360
360
 
361
- index_slice: LSQUARE expression? COLON expression? (COLON expression?)? RSQUARE
361
+ index_slice: LSQUARE \
362
+ expression? COLON expression? (COLON expression?)? \
363
+ (COMMA expression? COLON expression? (COLON expression?)?)* \
364
+ RSQUARE
362
365
  | list_val
363
366
 
364
367
  // Function calls