jaclang 0.7.17__py3-none-any.whl → 0.7.21__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.
- jaclang/cli/cli.py +5 -7
- jaclang/compiler/absyntree.py +1 -1
- jaclang/compiler/jac.lark +14 -14
- jaclang/compiler/parser.py +71 -59
- jaclang/compiler/passes/ir_pass.py +2 -0
- jaclang/compiler/passes/main/__init__.py +1 -1
- jaclang/compiler/passes/main/fuse_typeinfo_pass.py +50 -13
- jaclang/compiler/passes/main/import_pass.py +29 -1
- jaclang/compiler/passes/main/py_collect_dep_pass.py +8 -0
- jaclang/compiler/passes/main/pyast_gen_pass.py +25 -0
- jaclang/compiler/passes/main/registry_pass.py +4 -0
- jaclang/compiler/passes/main/sym_tab_build_pass.py +0 -18
- jaclang/compiler/passes/main/tests/fixtures/mod_type_assign.jac +7 -0
- jaclang/compiler/passes/main/tests/fixtures/pygame_mock/__init__.pyi +3 -0
- jaclang/compiler/passes/main/tests/test_import_pass.py +10 -10
- jaclang/compiler/passes/main/tests/test_type_check_pass.py +1 -1
- jaclang/compiler/passes/main/tests/test_typeinfo_pass.py +23 -1
- jaclang/compiler/passes/main/type_check_pass.py +4 -4
- jaclang/compiler/passes/tool/jac_formatter_pass.py +63 -31
- jaclang/compiler/passes/tool/tests/fixtures/general_format_checks/line_spacing.jac +57 -0
- jaclang/compiler/semtable.py +4 -4
- jaclang/compiler/symtable.py +5 -0
- jaclang/langserve/engine.py +92 -22
- jaclang/langserve/tests/fixtures/import_include_statements.jac +3 -3
- jaclang/langserve/tests/test_server.py +11 -7
- jaclang/langserve/utils.py +11 -213
- jaclang/plugin/builtin.py +8 -4
- jaclang/plugin/default.py +17 -3
- jaclang/plugin/feature.py +10 -0
- jaclang/plugin/spec.py +12 -0
- jaclang/plugin/tests/test_jaseci.py +23 -4
- jaclang/runtimelib/architype.py +20 -2
- jaclang/runtimelib/importer.py +4 -0
- jaclang/runtimelib/machine.py +92 -4
- jaclang/runtimelib/memory.py +7 -7
- jaclang/settings.py +4 -0
- jaclang/tests/fixtures/bar.jac +1 -1
- jaclang/tests/fixtures/builtin_dotgen.jac +1 -0
- jaclang/tests/fixtures/builtins_test.jac +16 -0
- jaclang/tests/fixtures/dynamic_architype.jac +34 -0
- jaclang/tests/fixtures/entry_exit.jac +36 -0
- jaclang/tests/fixtures/foo.jac +0 -1
- jaclang/tests/fixtures/match_multi_ex.jac +12 -0
- jaclang/tests/fixtures/objref.jac +12 -0
- jaclang/tests/fixtures/trailing_comma.jac +88 -0
- jaclang/tests/fixtures/walker_update.jac +19 -0
- jaclang/tests/test_cli.py +29 -2
- jaclang/tests/test_language.py +144 -4
- jaclang/utils/treeprinter.py +1 -1
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/METADATA +6 -2
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/RECORD +53 -43
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/WHEEL +0 -0
- {jaclang-0.7.17.dist-info → jaclang-0.7.21.dist-info}/entry_points.txt +0 -0
jaclang/cli/cli.py
CHANGED
|
@@ -8,7 +8,6 @@ import pickle
|
|
|
8
8
|
import shutil
|
|
9
9
|
import types
|
|
10
10
|
from typing import Optional
|
|
11
|
-
from uuid import UUID
|
|
12
11
|
|
|
13
12
|
import jaclang.compiler.absyntree as ast
|
|
14
13
|
from jaclang import jac_import
|
|
@@ -159,10 +158,9 @@ def get_object(
|
|
|
159
158
|
raise ValueError("Not a valid file!\nOnly supports `.jac` and `.jir`")
|
|
160
159
|
|
|
161
160
|
data = {}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
data = obj.__getstate__()
|
|
161
|
+
obj = Jac.get_object(id)
|
|
162
|
+
if obj:
|
|
163
|
+
data = obj.__jac__.__getstate__()
|
|
166
164
|
else:
|
|
167
165
|
print(f"Object with id {id} not found.")
|
|
168
166
|
|
|
@@ -431,8 +429,8 @@ def dot(
|
|
|
431
429
|
|
|
432
430
|
if filename.endswith(".jac"):
|
|
433
431
|
jac_machine = JacMachine(base)
|
|
434
|
-
jac_import(target=mod, base_path=base)
|
|
435
|
-
module = jac_machine.loaded_modules.get(
|
|
432
|
+
jac_import(target=mod, base_path=base, override_name="__main__")
|
|
433
|
+
module = jac_machine.loaded_modules.get("__main__")
|
|
436
434
|
globals().update(vars(module))
|
|
437
435
|
try:
|
|
438
436
|
node = globals().get(initial, eval(initial)) if initial else None
|
jaclang/compiler/absyntree.py
CHANGED
jaclang/compiler/jac.lark
CHANGED
|
@@ -25,7 +25,7 @@ from_path: (DOT | ELLIPSIS)* import_path
|
|
|
25
25
|
| (DOT | ELLIPSIS)+
|
|
26
26
|
|
|
27
27
|
import_path: named_ref (DOT named_ref)* (KW_AS NAME)?
|
|
28
|
-
import_items: (import_item COMMA)* import_item
|
|
28
|
+
import_items: (import_item COMMA)* import_item COMMA?
|
|
29
29
|
import_item: named_ref (KW_AS NAME)?
|
|
30
30
|
sub_name: COLON NAME
|
|
31
31
|
include_stmt: KW_INCLUDE sub_name? import_path SEMI
|
|
@@ -63,7 +63,7 @@ enum: decorators? enum_decl
|
|
|
63
63
|
|
|
64
64
|
enum_decl: KW_ENUM access_tag? STRING? NAME inherited_archs? (enum_block | SEMI)
|
|
65
65
|
enum_def: arch_to_enum_chain enum_block
|
|
66
|
-
enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt)? RBRACE
|
|
66
|
+
enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt COMMA?)? RBRACE
|
|
67
67
|
|
|
68
68
|
enum_stmt: NAME (COLON STRING)? EQ expression
|
|
69
69
|
| NAME (COLON STRING)?
|
|
@@ -83,7 +83,7 @@ abstract_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING? named_ref (
|
|
|
83
83
|
genai_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING? named_ref (func_decl) KW_BY atomic_call SEMI
|
|
84
84
|
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY) (STRING? RETURN_HINT expression)?
|
|
85
85
|
func_decl: (LPAREN func_decl_params? RPAREN)? (RETURN_HINT (STRING COLON)? expression)?
|
|
86
|
-
func_decl_params: (param_var COMMA)* param_var
|
|
86
|
+
func_decl_params: (param_var COMMA)* param_var COMMA?
|
|
87
87
|
param_var: (STAR_POW | STAR_MUL)? NAME (COLON STRING)? type_tag (EQ expression)?
|
|
88
88
|
|
|
89
89
|
// Global variables
|
|
@@ -364,9 +364,9 @@ index_slice: LSQUARE expression? COLON expression? (COLON expression?)? RSQUARE
|
|
|
364
364
|
// Function calls
|
|
365
365
|
atomic_call: atomic_chain LPAREN param_list? (KW_BY atomic_call)? RPAREN
|
|
366
366
|
|
|
367
|
-
param_list: expr_list COMMA kw_expr_list
|
|
368
|
-
| kw_expr_list
|
|
369
|
-
| expr_list
|
|
367
|
+
param_list: expr_list COMMA kw_expr_list COMMA?
|
|
368
|
+
| kw_expr_list COMMA?
|
|
369
|
+
| expr_list COMMA?
|
|
370
370
|
|
|
371
371
|
// Atom
|
|
372
372
|
atom: named_ref
|
|
@@ -412,20 +412,20 @@ set_compr: LBRACE expression inner_compr+ RBRACE
|
|
|
412
412
|
dict_compr: LBRACE kv_pair inner_compr+ RBRACE
|
|
413
413
|
inner_compr: KW_ASYNC? KW_FOR atomic_chain KW_IN pipe_call (KW_IF walrus_assign)*
|
|
414
414
|
|
|
415
|
-
dict_val: LBRACE ((kv_pair COMMA)* kv_pair)? RBRACE
|
|
416
|
-
list_val: LSQUARE expr_list? RSQUARE
|
|
415
|
+
dict_val: LBRACE ((kv_pair COMMA)* kv_pair COMMA?)? RBRACE
|
|
416
|
+
list_val: LSQUARE (expr_list COMMA?)? RSQUARE
|
|
417
417
|
tuple_val: LPAREN tuple_list? RPAREN
|
|
418
|
-
set_val: LBRACE expr_list RBRACE
|
|
418
|
+
set_val: LBRACE expr_list COMMA? RBRACE
|
|
419
419
|
|
|
420
420
|
kv_pair: expression COLON expression | STAR_POW expression
|
|
421
421
|
expr_list: (expr_list COMMA)? expression
|
|
422
422
|
|
|
423
423
|
// Tuples and Jac Tuples
|
|
424
|
-
tuple_list: expression COMMA expr_list COMMA kw_expr_list
|
|
425
|
-
| expression COMMA kw_expr_list
|
|
426
|
-
| expression COMMA expr_list
|
|
424
|
+
tuple_list: expression COMMA expr_list COMMA kw_expr_list COMMA?
|
|
425
|
+
| expression COMMA kw_expr_list COMMA?
|
|
426
|
+
| expression COMMA expr_list COMMA?
|
|
427
427
|
| expression COMMA
|
|
428
|
-
| kw_expr_list
|
|
428
|
+
| kw_expr_list COMMA?
|
|
429
429
|
|
|
430
430
|
kw_expr_list: (kw_expr_list COMMA)? kw_expr
|
|
431
431
|
kw_expr: named_ref EQ expression | STAR_POW expression
|
|
@@ -662,4 +662,4 @@ FSTR_BESC.1: /{{|}}/
|
|
|
662
662
|
COMMENT: /#\*(.|\n|\r)*?\*#|#.*/
|
|
663
663
|
WS.-2: /[ \t\f\r\n]/+
|
|
664
664
|
%ignore COMMENT
|
|
665
|
-
%ignore WS
|
|
665
|
+
%ignore WS
|
jaclang/compiler/parser.py
CHANGED
|
@@ -429,7 +429,7 @@ class JacParser(Pass):
|
|
|
429
429
|
) -> ast.SubNodeList[ast.ModuleItem]:
|
|
430
430
|
"""Grammar rule.
|
|
431
431
|
|
|
432
|
-
import_items: (import_item COMMA)* import_item
|
|
432
|
+
import_items: (import_item COMMA)* import_item COMMA?
|
|
433
433
|
"""
|
|
434
434
|
ret = ast.SubNodeList[ast.ModuleItem](
|
|
435
435
|
items=[i for i in kid if isinstance(i, ast.ModuleItem)],
|
|
@@ -693,7 +693,7 @@ class JacParser(Pass):
|
|
|
693
693
|
) -> ast.SubNodeList[ast.EnumBlockStmt]:
|
|
694
694
|
"""Grammar rule.
|
|
695
695
|
|
|
696
|
-
enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt)? RBRACE
|
|
696
|
+
enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt COMMA?)? RBRACE
|
|
697
697
|
"""
|
|
698
698
|
ret = ast.SubNodeList[ast.EnumBlockStmt](items=[], delim=Tok.COMMA, kid=kid)
|
|
699
699
|
ret.items = [i for i in kid if isinstance(i, ast.EnumBlockStmt)]
|
|
@@ -1022,7 +1022,7 @@ class JacParser(Pass):
|
|
|
1022
1022
|
) -> ast.SubNodeList[ast.ParamVar]:
|
|
1023
1023
|
"""Grammar rule.
|
|
1024
1024
|
|
|
1025
|
-
func_decl_params: (param_var COMMA)* param_var
|
|
1025
|
+
func_decl_params: (param_var COMMA)* param_var COMMA?
|
|
1026
1026
|
"""
|
|
1027
1027
|
ret = ast.SubNodeList[ast.ParamVar](
|
|
1028
1028
|
items=[i for i in kid if isinstance(i, ast.ParamVar)],
|
|
@@ -1267,29 +1267,30 @@ class JacParser(Pass):
|
|
|
1267
1267
|
def statement(self, kid: list[ast.AstNode]) -> ast.CodeBlockStmt:
|
|
1268
1268
|
"""Grammar rule.
|
|
1269
1269
|
|
|
1270
|
-
statement:
|
|
1271
|
-
|
|
|
1272
|
-
|
|
|
1273
|
-
|
|
|
1274
|
-
| delete_stmt SEMI
|
|
1275
|
-
| ctrl_stmt SEMI
|
|
1276
|
-
| assert_stmt SEMI
|
|
1277
|
-
| raise_stmt SEMI
|
|
1278
|
-
| with_stmt
|
|
1270
|
+
statement: import_stmt
|
|
1271
|
+
| ability
|
|
1272
|
+
| architype
|
|
1273
|
+
| if_stmt
|
|
1279
1274
|
| while_stmt
|
|
1280
1275
|
| for_stmt
|
|
1281
1276
|
| try_stmt
|
|
1282
|
-
|
|
|
1283
|
-
|
|
|
1284
|
-
| (yield_expr | KW_YIELD) SEMI
|
|
1285
|
-
| static_assignment
|
|
1286
|
-
| assignment SEMI
|
|
1277
|
+
| match_stmt
|
|
1278
|
+
| with_stmt
|
|
1287
1279
|
| global_ref SEMI
|
|
1288
1280
|
| nonlocal_ref SEMI
|
|
1289
1281
|
| typed_ctx_block
|
|
1290
|
-
|
|
|
1291
|
-
|
|
|
1292
|
-
|
|
|
1282
|
+
| return_stmt SEMI
|
|
1283
|
+
| (yield_expr | KW_YIELD) SEMI
|
|
1284
|
+
| raise_stmt SEMI
|
|
1285
|
+
| assert_stmt SEMI
|
|
1286
|
+
| check_stmt SEMI
|
|
1287
|
+
| assignment SEMI
|
|
1288
|
+
| delete_stmt SEMI
|
|
1289
|
+
| report_stmt SEMI
|
|
1290
|
+
| expression SEMI
|
|
1291
|
+
| ctrl_stmt SEMI
|
|
1292
|
+
| py_code_block
|
|
1293
|
+
| walker_stmt
|
|
1293
1294
|
| SEMI
|
|
1294
1295
|
"""
|
|
1295
1296
|
if isinstance(kid[0], ast.CodeBlockStmt) and len(kid) < 2:
|
|
@@ -2180,30 +2181,21 @@ class JacParser(Pass):
|
|
|
2180
2181
|
def arithmetic(self, kid: list[ast.AstNode]) -> ast.Expr:
|
|
2181
2182
|
"""Grammar rule.
|
|
2182
2183
|
|
|
2183
|
-
arithmetic:
|
|
2184
|
-
| term PLUS arithmetic
|
|
2185
|
-
| term
|
|
2184
|
+
arithmetic: (arithmetic (MINUS | PLUS))? term
|
|
2186
2185
|
"""
|
|
2187
2186
|
return self.binary_expr_unwind(kid)
|
|
2188
2187
|
|
|
2189
2188
|
def term(self, kid: list[ast.AstNode]) -> ast.Expr:
|
|
2190
2189
|
"""Grammar rule.
|
|
2191
2190
|
|
|
2192
|
-
term:
|
|
2193
|
-
| factor DIV term
|
|
2194
|
-
| factor FLOOR_DIV term
|
|
2195
|
-
| factor STAR_MUL term
|
|
2196
|
-
| factor
|
|
2191
|
+
term: (term (MOD | DIV | FLOOR_DIV | STAR_MUL | DECOR_OP))? power
|
|
2197
2192
|
"""
|
|
2198
2193
|
return self.binary_expr_unwind(kid)
|
|
2199
2194
|
|
|
2200
2195
|
def factor(self, kid: list[ast.AstNode]) -> ast.Expr:
|
|
2201
2196
|
"""Grammar rule.
|
|
2202
2197
|
|
|
2203
|
-
factor:
|
|
2204
|
-
| BW_NOT factor
|
|
2205
|
-
| MINUS factor
|
|
2206
|
-
| PLUS factor
|
|
2198
|
+
factor: (BW_NOT | MINUS | PLUS) factor | connect
|
|
2207
2199
|
"""
|
|
2208
2200
|
if len(kid) == 2:
|
|
2209
2201
|
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.Expr):
|
|
@@ -2221,8 +2213,7 @@ class JacParser(Pass):
|
|
|
2221
2213
|
def power(self, kid: list[ast.AstNode]) -> ast.Expr:
|
|
2222
2214
|
"""Grammar rule.
|
|
2223
2215
|
|
|
2224
|
-
power:
|
|
2225
|
-
| connect
|
|
2216
|
+
power: (power STAR_POW)? factor
|
|
2226
2217
|
"""
|
|
2227
2218
|
return self.binary_expr_unwind(kid)
|
|
2228
2219
|
|
|
@@ -2513,8 +2504,7 @@ class JacParser(Pass):
|
|
|
2513
2504
|
def yield_expr(self, kid: list[ast.AstNode]) -> ast.YieldExpr:
|
|
2514
2505
|
"""Grammar rule.
|
|
2515
2506
|
|
|
2516
|
-
yield_expr:
|
|
2517
|
-
| KW_YIELD KW_FROM? expression
|
|
2507
|
+
yield_expr: KW_YIELD KW_FROM? expression
|
|
2518
2508
|
"""
|
|
2519
2509
|
if isinstance(kid[-1], ast.Expr):
|
|
2520
2510
|
return self.nu(
|
|
@@ -2565,7 +2555,7 @@ class JacParser(Pass):
|
|
|
2565
2555
|
def multistring(self, kid: list[ast.AstNode]) -> ast.AtomExpr:
|
|
2566
2556
|
"""Grammar rule.
|
|
2567
2557
|
|
|
2568
|
-
multistring: (fstring | STRING)+
|
|
2558
|
+
multistring: (fstring | STRING | DOC_STRING)+
|
|
2569
2559
|
"""
|
|
2570
2560
|
valid_strs = [i for i in kid if isinstance(i, (ast.String, ast.FString))]
|
|
2571
2561
|
if len(valid_strs) == len(kid):
|
|
@@ -2582,6 +2572,7 @@ class JacParser(Pass):
|
|
|
2582
2572
|
"""Grammar rule.
|
|
2583
2573
|
|
|
2584
2574
|
fstring: FSTR_START fstr_parts FSTR_END
|
|
2575
|
+
| FSTR_SQ_START fstr_sq_parts FSTR_SQ_END
|
|
2585
2576
|
"""
|
|
2586
2577
|
if len(kid) == 2:
|
|
2587
2578
|
return self.nu(
|
|
@@ -2605,7 +2596,7 @@ class JacParser(Pass):
|
|
|
2605
2596
|
) -> ast.SubNodeList[ast.String | ast.ExprStmt]:
|
|
2606
2597
|
"""Grammar rule.
|
|
2607
2598
|
|
|
2608
|
-
fstr_parts: (FSTR_PIECE | FSTR_BESC | LBRACE expression RBRACE
|
|
2599
|
+
fstr_parts: (FSTR_PIECE | FSTR_BESC | LBRACE expression RBRACE )*
|
|
2609
2600
|
"""
|
|
2610
2601
|
valid_parts: list[ast.String | ast.ExprStmt] = [
|
|
2611
2602
|
(
|
|
@@ -2651,7 +2642,7 @@ class JacParser(Pass):
|
|
|
2651
2642
|
def list_val(self, kid: list[ast.AstNode]) -> ast.ListVal:
|
|
2652
2643
|
"""Grammar rule.
|
|
2653
2644
|
|
|
2654
|
-
list_val: LSQUARE expr_list? RSQUARE
|
|
2645
|
+
list_val: LSQUARE (expr_list COMMA?)? RSQUARE
|
|
2655
2646
|
"""
|
|
2656
2647
|
if len(kid) == 2:
|
|
2657
2648
|
return self.nu(
|
|
@@ -2695,7 +2686,7 @@ class JacParser(Pass):
|
|
|
2695
2686
|
def set_val(self, kid: list[ast.AstNode]) -> ast.SetVal:
|
|
2696
2687
|
"""Grammar rule.
|
|
2697
2688
|
|
|
2698
|
-
set_val: LBRACE expr_list RBRACE
|
|
2689
|
+
set_val: LBRACE expr_list COMMA? RBRACE
|
|
2699
2690
|
"""
|
|
2700
2691
|
if len(kid) == 2:
|
|
2701
2692
|
return self.nu(
|
|
@@ -2822,25 +2813,37 @@ class JacParser(Pass):
|
|
|
2822
2813
|
) -> ast.SubNodeList[ast.Expr | ast.KWPair]:
|
|
2823
2814
|
"""Grammar rule.
|
|
2824
2815
|
|
|
2825
|
-
tuple_list: expression COMMA expr_list
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2816
|
+
tuple_list: expression COMMA expr_list COMMA kw_expr_list COMMA?
|
|
2817
|
+
| expression COMMA kw_expr_list COMMA?
|
|
2818
|
+
| expression COMMA expr_list COMMA?
|
|
2819
|
+
| expression COMMA
|
|
2820
|
+
| kw_expr_list COMMA?
|
|
2830
2821
|
"""
|
|
2831
2822
|
chomp = [*kid]
|
|
2832
2823
|
first_expr = None
|
|
2833
2824
|
if isinstance(chomp[0], ast.SubNodeList):
|
|
2825
|
+
# The chomp will be like this:
|
|
2826
|
+
# kw_expr_list, [COMMA]
|
|
2827
|
+
if len(chomp) > 1:
|
|
2828
|
+
# Add the comma to the subnode list if it exists, otherwise the last comma will not be a part of
|
|
2829
|
+
# the ast, we need it for formatting.
|
|
2830
|
+
chomp[0].kid.append(chomp[1])
|
|
2834
2831
|
return self.nu(chomp[0])
|
|
2835
2832
|
else:
|
|
2836
|
-
|
|
2837
|
-
|
|
2833
|
+
# The chomp will be like this:
|
|
2834
|
+
# expression, COMMA, [subnode_list, [COMMA, [kw_expr_list, [COMMA]]]]
|
|
2835
|
+
# Pop the first expression from chomp.
|
|
2836
|
+
first_expr = chomp[0] # Get the first expression.
|
|
2837
|
+
chomp = chomp[2:] # Get rid of expr and comma.
|
|
2838
|
+
|
|
2839
|
+
# The chomp will be like this:
|
|
2840
|
+
# [subnode_list, [COMMA, [kw_expr_list, [COMMA]]]]
|
|
2838
2841
|
expr_list = []
|
|
2839
2842
|
if len(chomp):
|
|
2840
|
-
expr_list = chomp[0].kid
|
|
2841
|
-
chomp = chomp[
|
|
2843
|
+
expr_list = chomp[0].kid # Get the kids subnode list.
|
|
2844
|
+
chomp = chomp[2:] # Get rid of the subnode list and a comma if exists.
|
|
2842
2845
|
if len(chomp):
|
|
2843
|
-
chomp
|
|
2846
|
+
# The chomp will be like this: [kw_expr_list, [COMMA]]
|
|
2844
2847
|
expr_list = [*expr_list, *chomp[0].kid]
|
|
2845
2848
|
expr_list = [first_expr, *expr_list]
|
|
2846
2849
|
valid_kid = [i for i in expr_list if isinstance(i, (ast.Expr, ast.KWPair))]
|
|
@@ -2855,7 +2858,7 @@ class JacParser(Pass):
|
|
|
2855
2858
|
def dict_val(self, kid: list[ast.AstNode]) -> ast.DictVal:
|
|
2856
2859
|
"""Grammar rule.
|
|
2857
2860
|
|
|
2858
|
-
dict_val: LBRACE ((kv_pair COMMA)* kv_pair)? RBRACE
|
|
2861
|
+
dict_val: LBRACE ((kv_pair COMMA)* kv_pair COMMA?)? RBRACE
|
|
2859
2862
|
"""
|
|
2860
2863
|
ret = ast.DictVal(
|
|
2861
2864
|
kv_pairs=[],
|
|
@@ -2912,7 +2915,7 @@ class JacParser(Pass):
|
|
|
2912
2915
|
def gen_compr(self, kid: list[ast.AstNode]) -> ast.GenCompr:
|
|
2913
2916
|
"""Grammar rule.
|
|
2914
2917
|
|
|
2915
|
-
gen_compr:
|
|
2918
|
+
gen_compr: LPAREN expression inner_compr+ RPAREN
|
|
2916
2919
|
"""
|
|
2917
2920
|
comprs = [i for i in kid if isinstance(i, ast.InnerCompr)]
|
|
2918
2921
|
if isinstance(kid[1], ast.Expr):
|
|
@@ -2929,7 +2932,7 @@ class JacParser(Pass):
|
|
|
2929
2932
|
def set_compr(self, kid: list[ast.AstNode]) -> ast.SetCompr:
|
|
2930
2933
|
"""Grammar rule.
|
|
2931
2934
|
|
|
2932
|
-
set_compr:
|
|
2935
|
+
set_compr: LBRACE expression inner_compr+ RBRACE
|
|
2933
2936
|
"""
|
|
2934
2937
|
comprs = [i for i in kid if isinstance(i, ast.InnerCompr)]
|
|
2935
2938
|
if isinstance(kid[1], ast.Expr) and isinstance(kid[2], ast.InnerCompr):
|
|
@@ -2993,12 +2996,21 @@ class JacParser(Pass):
|
|
|
2993
2996
|
) -> ast.SubNodeList[ast.Expr | ast.KWPair]:
|
|
2994
2997
|
"""Grammar rule.
|
|
2995
2998
|
|
|
2996
|
-
param_list: expr_list
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
+
param_list: expr_list COMMA kw_expr_list COMMA?
|
|
3000
|
+
| kw_expr_list COMMA?
|
|
3001
|
+
| expr_list COMMA?
|
|
2999
3002
|
"""
|
|
3000
|
-
|
|
3003
|
+
ends_with_comma = (
|
|
3004
|
+
len(kid) > 1
|
|
3005
|
+
and isinstance(kid[-1], ast.Token)
|
|
3006
|
+
and kid[-1].name == "COMMA"
|
|
3007
|
+
)
|
|
3008
|
+
if len(kid) == 1 or (len(kid) == 2 and ends_with_comma):
|
|
3001
3009
|
if isinstance(kid[0], ast.SubNodeList):
|
|
3010
|
+
if (
|
|
3011
|
+
ends_with_comma
|
|
3012
|
+
): # Append the trailing comma to the subnode list.
|
|
3013
|
+
kid[0].kid.append(kid[1])
|
|
3002
3014
|
return self.nu(kid[0])
|
|
3003
3015
|
else:
|
|
3004
3016
|
raise self.ice()
|
|
@@ -3146,7 +3158,7 @@ class JacParser(Pass):
|
|
|
3146
3158
|
def type_ref(self, kid: list[ast.AstNode]) -> ast.ArchRef:
|
|
3147
3159
|
"""Grammar rule.
|
|
3148
3160
|
|
|
3149
|
-
type_ref: TYPE_OP
|
|
3161
|
+
type_ref: TYPE_OP (named_ref | builtin_type)
|
|
3150
3162
|
"""
|
|
3151
3163
|
if isinstance(kid[0], ast.Token) and isinstance(kid[1], ast.NameAtom):
|
|
3152
3164
|
return self.nu(
|
|
@@ -3587,7 +3599,7 @@ class JacParser(Pass):
|
|
|
3587
3599
|
match_case_block: KW_CASE pattern_seq (KW_IF expression)? COLON statement_list
|
|
3588
3600
|
"""
|
|
3589
3601
|
pattern = kid[1]
|
|
3590
|
-
guard = kid[3] if
|
|
3602
|
+
guard = kid[3] if isinstance(kid[3], ast.Expr) else None
|
|
3591
3603
|
stmts = [i for i in kid if isinstance(i, ast.CodeBlockStmt)]
|
|
3592
3604
|
if isinstance(pattern, ast.MatchPattern) and isinstance(
|
|
3593
3605
|
guard, (ast.Expr, type(None))
|
|
@@ -6,6 +6,7 @@ mypy apis into Jac and use jac py ast in it.
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import re
|
|
9
10
|
from typing import Callable, Optional, TypeVar
|
|
10
11
|
|
|
11
12
|
import jaclang.compiler.absyntree as ast
|
|
@@ -46,24 +47,24 @@ class FuseTypeInfoPass(Pass):
|
|
|
46
47
|
)
|
|
47
48
|
|
|
48
49
|
def __set_sym_table_link(self, node: ast.AstSymbolNode) -> None:
|
|
49
|
-
typ = node.sym_type.split(".")
|
|
50
50
|
typ_sym_table = self.ir.sym_tab
|
|
51
|
+
assert isinstance(self.ir, ast.Module)
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
sym_type = node.sym_type
|
|
54
|
+
if re.match(r"builtins.(list|dict|tuple)", sym_type):
|
|
55
|
+
sym_type = re.sub(r"\[.*\]", "", sym_type)
|
|
56
|
+
|
|
57
|
+
typ = sym_type.split(".")
|
|
54
58
|
|
|
55
59
|
if node.sym_type == "types.ModuleType" and node.sym:
|
|
56
60
|
node.name_spec.type_sym_tab = node.sym.parent_tab.find_scope(node.sym_name)
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
f = typ_sym_table.find_scope(i)
|
|
65
|
-
if f:
|
|
66
|
-
typ_sym_table = f
|
|
62
|
+
for i in typ:
|
|
63
|
+
if i == self.ir.name:
|
|
64
|
+
continue
|
|
65
|
+
f = typ_sym_table.find_scope(i)
|
|
66
|
+
if f:
|
|
67
|
+
typ_sym_table = f
|
|
67
68
|
|
|
68
69
|
if typ_sym_table != self.ir.sym_tab:
|
|
69
70
|
node.name_spec.type_sym_tab = typ_sym_table
|
|
@@ -144,6 +145,11 @@ class FuseTypeInfoPass(Pass):
|
|
|
144
145
|
self.__set_sym_table_link(node)
|
|
145
146
|
self.__collect_python_dependencies(node)
|
|
146
147
|
|
|
148
|
+
# Special handing for BuiltinType
|
|
149
|
+
elif isinstance(node, ast.BuiltinType):
|
|
150
|
+
func(self, node) # type: ignore
|
|
151
|
+
self.__set_sym_table_link(node)
|
|
152
|
+
|
|
147
153
|
# Jac node doesn't have mypy nodes linked to it
|
|
148
154
|
else:
|
|
149
155
|
self.__debug_print(
|
|
@@ -209,10 +215,21 @@ class FuseTypeInfoPass(Pass):
|
|
|
209
215
|
f"{type(mypy_node)}"
|
|
210
216
|
)
|
|
211
217
|
|
|
218
|
+
def __check_builltin_symbol(self, node: ast.NameAtom) -> None:
|
|
219
|
+
if isinstance(node.parent, ast.AtomTrailer) and node is node.parent.right:
|
|
220
|
+
return
|
|
221
|
+
builtins_sym_tab = self.ir.sym_tab.find_scope("builtins")
|
|
222
|
+
assert builtins_sym_tab is not None
|
|
223
|
+
builtins_sym = builtins_sym_tab.lookup(node.sym_name)
|
|
224
|
+
if builtins_sym:
|
|
225
|
+
node.name_spec._sym = builtins_sym
|
|
226
|
+
|
|
212
227
|
@__handle_node
|
|
213
228
|
def enter_name(self, node: ast.NameAtom) -> None:
|
|
214
229
|
"""Pass handler for name nodes."""
|
|
215
230
|
self.__collect_type_from_symbol(node)
|
|
231
|
+
if node.sym is None:
|
|
232
|
+
self.__check_builltin_symbol(node)
|
|
216
233
|
|
|
217
234
|
@__handle_node
|
|
218
235
|
def enter_module_path(self, node: ast.ModulePath) -> None:
|
|
@@ -423,7 +440,8 @@ class FuseTypeInfoPass(Pass):
|
|
|
423
440
|
@__handle_node
|
|
424
441
|
def enter_builtin_type(self, node: ast.BuiltinType) -> None:
|
|
425
442
|
"""Pass handler for BuiltinType nodes."""
|
|
426
|
-
self.
|
|
443
|
+
self.__check_builltin_symbol(node)
|
|
444
|
+
node.name_spec.sym_type = f"builtins.{node.sym_name}"
|
|
427
445
|
|
|
428
446
|
def get_type_from_instance(
|
|
429
447
|
self, node: ast.AstSymbolNode, mypy_type: MypyTypes.Instance
|
|
@@ -483,6 +501,21 @@ class FuseTypeInfoPass(Pass):
|
|
|
483
501
|
if self_obj.type_sym_tab and isinstance(right_obj, ast.AstSymbolNode):
|
|
484
502
|
self_obj.type_sym_tab.def_insert(right_obj)
|
|
485
503
|
|
|
504
|
+
# Support adding the correct type symbol table in case of ModuleType
|
|
505
|
+
# This will only work for target=Val & target1=target2=val and
|
|
506
|
+
# target is a moduleType
|
|
507
|
+
# it won't work in case of
|
|
508
|
+
# - target1, target2 = Val1, Val2 <-- tuples need more attention
|
|
509
|
+
# - target = a.b.c <-- will be fixed after thakee's PR
|
|
510
|
+
# - a.b.c = val <-- will be fixed after thakee's PR
|
|
511
|
+
for target in node.target.items:
|
|
512
|
+
if (
|
|
513
|
+
isinstance(target, ast.Name)
|
|
514
|
+
and target.sym_type == "types.ModuleType"
|
|
515
|
+
and isinstance(node.value, ast.Name)
|
|
516
|
+
):
|
|
517
|
+
target.type_sym_tab = node.value.type_sym_tab
|
|
518
|
+
|
|
486
519
|
def expand_atom_trailer(self, node_list: list[ast.AstNode]) -> list[ast.AstNode]:
|
|
487
520
|
"""Expand the atom trailer object in a list of AstNode."""
|
|
488
521
|
out: list[ast.AstNode] = []
|
|
@@ -552,6 +585,10 @@ class FuseTypeInfoPass(Pass):
|
|
|
552
585
|
type_symtab: Optional[SymbolTable] = self.ir.sym_tab
|
|
553
586
|
assert isinstance(self.ir, ast.Module)
|
|
554
587
|
assert isinstance(type_symtab, SymbolTable)
|
|
588
|
+
|
|
589
|
+
if re.match(r"builtins.(list|dict|tuple)", node_type):
|
|
590
|
+
node_type = re.sub(r"\[.*\]", "", node_type)
|
|
591
|
+
|
|
555
592
|
for j in node_type.split("."):
|
|
556
593
|
if j == self.ir.name:
|
|
557
594
|
continue
|
|
@@ -7,12 +7,14 @@ symbols are available for matching.
|
|
|
7
7
|
|
|
8
8
|
import ast as py_ast
|
|
9
9
|
import os
|
|
10
|
+
import pathlib
|
|
10
11
|
from typing import Optional
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
import jaclang.compiler.absyntree as ast
|
|
14
15
|
from jaclang.compiler.passes import Pass
|
|
15
16
|
from jaclang.compiler.passes.main import SubNodeTabPass, SymTabBuildPass
|
|
17
|
+
from jaclang.settings import settings
|
|
16
18
|
from jaclang.utils.log import logging
|
|
17
19
|
|
|
18
20
|
|
|
@@ -105,7 +107,7 @@ class JacImportPass(Pass):
|
|
|
105
107
|
or test_folder == os.path.dirname(cur_file)
|
|
106
108
|
) and cur_file.endswith(".test.jac"):
|
|
107
109
|
mod = self.import_jac_mod_from_file(cur_file)
|
|
108
|
-
if mod:
|
|
110
|
+
if mod and not settings.ignore_test_annex:
|
|
109
111
|
node.test_mod.append(mod)
|
|
110
112
|
node.add_kids_right([mod], pos_update=False)
|
|
111
113
|
mod.parent = node
|
|
@@ -199,6 +201,7 @@ class PyImportPass(JacImportPass):
|
|
|
199
201
|
def before_pass(self) -> None:
|
|
200
202
|
"""Only run pass if settings are set to raise python."""
|
|
201
203
|
super().before_pass()
|
|
204
|
+
self.__load_builtins()
|
|
202
205
|
|
|
203
206
|
def __get_current_module(self, node: ast.AstNode) -> str:
|
|
204
207
|
parent = node.find_parent_of_type(ast.Module)
|
|
@@ -295,6 +298,31 @@ class PyImportPass(JacImportPass):
|
|
|
295
298
|
raise e
|
|
296
299
|
return None
|
|
297
300
|
|
|
301
|
+
def __load_builtins(self) -> None:
|
|
302
|
+
"""Pyraise builtins to help with builtins auto complete."""
|
|
303
|
+
from jaclang.compiler.passes.main import PyastBuildPass
|
|
304
|
+
|
|
305
|
+
assert isinstance(self.ir, ast.Module)
|
|
306
|
+
|
|
307
|
+
file_to_raise = str(
|
|
308
|
+
pathlib.Path(os.path.dirname(__file__)).parent.parent.parent
|
|
309
|
+
/ "vendor"
|
|
310
|
+
/ "mypy"
|
|
311
|
+
/ "typeshed"
|
|
312
|
+
/ "stdlib"
|
|
313
|
+
/ "builtins.pyi"
|
|
314
|
+
)
|
|
315
|
+
with open(file_to_raise, "r", encoding="utf-8") as f:
|
|
316
|
+
mod = PyastBuildPass(
|
|
317
|
+
input_ir=ast.PythonModuleAst(
|
|
318
|
+
py_ast.parse(f.read()), mod_path=file_to_raise
|
|
319
|
+
),
|
|
320
|
+
).ir
|
|
321
|
+
mod.parent = self.ir
|
|
322
|
+
SubNodeTabPass(input_ir=mod, prior=self)
|
|
323
|
+
SymTabBuildPass(input_ir=mod, prior=self)
|
|
324
|
+
mod.parent = None
|
|
325
|
+
|
|
298
326
|
def annex_impl(self, node: ast.Module) -> None:
|
|
299
327
|
"""Annex impl and test modules."""
|
|
300
328
|
return None
|
|
@@ -7,6 +7,8 @@ that are only relevant to actual references source from Jac code.
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
import os
|
|
11
|
+
|
|
10
12
|
import jaclang.compiler.absyntree as ast
|
|
11
13
|
from jaclang.compiler.passes import Pass
|
|
12
14
|
from jaclang.settings import settings
|
|
@@ -28,11 +30,15 @@ class PyCollectDepsPass(Pass):
|
|
|
28
30
|
if not isinstance(node, ast.AstSymbolNode):
|
|
29
31
|
return
|
|
30
32
|
|
|
33
|
+
# Adding the path of the file related to the py import
|
|
31
34
|
path: str = ""
|
|
32
35
|
if isinstance(node, ast.ModulePath):
|
|
33
36
|
if node.path:
|
|
34
37
|
path = ".".join([i.value for i in node.path])
|
|
35
38
|
node.abs_path = self.ir.py_mod_dep_map.get(path)
|
|
39
|
+
if node.abs_path and os.path.isfile(node.abs_path.replace(".pyi", ".py")):
|
|
40
|
+
node.abs_path = node.abs_path.replace(".pyi", ".py")
|
|
41
|
+
|
|
36
42
|
elif isinstance(node, ast.ModuleItem):
|
|
37
43
|
imp = node.parent_of_type(ast.Import)
|
|
38
44
|
mod_path_node = imp.get_all_sub_nodes(ast.ModulePath)[0]
|
|
@@ -40,6 +46,8 @@ class PyCollectDepsPass(Pass):
|
|
|
40
46
|
path = ".".join([i.value for i in mod_path_node.path])
|
|
41
47
|
path += f".{node.name.value}"
|
|
42
48
|
node.abs_path = self.ir.py_mod_dep_map.get(path)
|
|
49
|
+
if node.abs_path and os.path.isfile(node.abs_path.replace(".pyi", ".py")):
|
|
50
|
+
node.abs_path = node.abs_path.replace(".pyi", ".py")
|
|
43
51
|
|
|
44
52
|
if len(node.gen.mypy_ast) == 0:
|
|
45
53
|
return
|
|
@@ -2641,6 +2641,31 @@ class PyastGenPass(Pass):
|
|
|
2641
2641
|
]
|
|
2642
2642
|
elif node.op.name in [Tok.STAR_POW]:
|
|
2643
2643
|
node.gen.py_ast = node.operand.gen.py_ast
|
|
2644
|
+
elif node.op.name in [Tok.BW_AND]:
|
|
2645
|
+
node.gen.py_ast = [
|
|
2646
|
+
self.sync(
|
|
2647
|
+
ast3.Call(
|
|
2648
|
+
func=self.sync(
|
|
2649
|
+
ast3.Attribute(
|
|
2650
|
+
value=self.sync(
|
|
2651
|
+
ast3.Name(id=Con.JAC_FEATURE.value, ctx=ast3.Load())
|
|
2652
|
+
),
|
|
2653
|
+
attr="get_object",
|
|
2654
|
+
ctx=ast3.Load(),
|
|
2655
|
+
)
|
|
2656
|
+
),
|
|
2657
|
+
args=[],
|
|
2658
|
+
keywords=[
|
|
2659
|
+
self.sync(
|
|
2660
|
+
ast3.keyword(
|
|
2661
|
+
arg="id",
|
|
2662
|
+
value=node.operand.gen.py_ast[0],
|
|
2663
|
+
)
|
|
2664
|
+
),
|
|
2665
|
+
],
|
|
2666
|
+
)
|
|
2667
|
+
)
|
|
2668
|
+
]
|
|
2644
2669
|
else:
|
|
2645
2670
|
self.ice(f"Unknown Unary operator {node.op.value}")
|
|
2646
2671
|
|