10
10
from decimal import Decimal
11
11
from enum import Enum
12
12
from fractions import Fraction
13
- from functools import wraps , partial
13
+ from functools import partial , wraps
14
14
from itertools import chain
15
15
from typing import (
16
- Iterable ,
17
- Pattern ,
18
- Optional ,
19
- List ,
20
- Union ,
16
+ Callable ,
17
+ Collection ,
21
18
Deque ,
22
19
Dict ,
23
- Callable ,
20
+ Iterable ,
21
+ List ,
22
+ Optional ,
23
+ Pattern ,
24
24
Tuple ,
25
25
Type ,
26
- Collection ,
26
+ Union ,
27
27
)
28
28
29
29
import attr
46
46
)
47
47
from basilisp .lang .compiler .exception import CompilerException , CompilerPhase
48
48
from basilisp .lang .compiler .nodes import (
49
- Node ,
50
- NodeOp ,
51
- ConstType ,
49
+ Await ,
50
+ Binding ,
51
+ Catch ,
52
52
Const ,
53
- WithMeta ,
53
+ ConstType ,
54
54
Def ,
55
55
Do ,
56
- If ,
57
- VarRef ,
56
+ Fn ,
57
+ FnMethod ,
58
58
HostCall ,
59
59
HostField ,
60
- MaybeClass ,
61
- MaybeHostForm ,
62
- Map as MapNode ,
63
- Set as SetNode ,
64
- Vector as VectorNode ,
65
- Quote ,
66
- ReaderLispForm ,
60
+ If ,
61
+ Import ,
67
62
Invoke ,
68
- Throw ,
69
- Try ,
70
- LocalType ,
71
- SetBang ,
72
- Local ,
73
63
Let ,
64
+ Local ,
65
+ LocalType ,
74
66
Loop ,
75
- Recur ,
76
- Fn ,
77
- Import ,
78
- FnMethod ,
79
- Binding ,
67
+ Map as MapNode ,
68
+ MaybeClass ,
69
+ MaybeHostForm ,
70
+ Node ,
80
71
NodeEnv ,
81
- Catch ,
72
+ NodeOp ,
73
+ PyDict ,
82
74
PyList ,
83
75
PySet ,
84
76
PyTuple ,
85
- PyDict ,
77
+ Quote ,
78
+ ReaderLispForm ,
79
+ Recur ,
80
+ Set as SetNode ,
81
+ SetBang ,
82
+ Throw ,
83
+ Try ,
84
+ VarRef ,
85
+ Vector as VectorNode ,
86
+ WithMeta ,
86
87
)
87
- from basilisp .lang .runtime import Var
88
+ from basilisp .lang .runtime import CORE_NS , NS_VAR_NAME as LISP_NS_VAR , Var
88
89
from basilisp .lang .typing import LispForm
89
90
from basilisp .lang .util import count , genname , munge
90
91
from basilisp .util import Maybe
96
97
USE_VAR_INDIRECTION = "use_var_indirection"
97
98
WARN_ON_VAR_INDIRECTION = "warn_on_var_indirection"
98
99
99
- # Lisp AST node keywords
100
- INIT = kw .keyword ("init" )
101
-
102
100
# String constants used in generating code
103
101
_BUILTINS_NS = "builtins"
104
- _CORE_NS = "basilisp.core"
105
102
_DEFAULT_FN = "__lisp_expr__"
106
103
_DO_PREFIX = "lisp_do"
107
104
_FN_PREFIX = "lisp_fn"
112
109
_THROW_PREFIX = "lisp_throw"
113
110
_TRY_PREFIX = "lisp_try"
114
111
_NS_VAR = "__NS"
115
- _LISP_NS_VAR = "*ns*"
116
112
117
113
118
114
GeneratorException = partial (CompilerException , phase = CompilerPhase .CODE_GENERATION )
@@ -520,6 +516,15 @@ def expressionize(
520
516
#################
521
517
522
518
519
+ @_with_ast_loc_deps
520
+ def _await_to_py_ast (ctx : GeneratorContext , node : Await ) -> GeneratedPyAST :
521
+ assert node .op == NodeOp .AWAIT
522
+ expr_ast = gen_py_ast (ctx , node .expr )
523
+ return GeneratedPyAST (
524
+ node = ast .Await (value = expr_ast .node ), dependencies = expr_ast .dependencies
525
+ )
526
+
527
+
523
528
def __should_warn_on_redef (
524
529
ctx : GeneratorContext , defsym : sym .Symbol , safe_name : str , def_meta : lmap .Map
525
530
) -> bool :
@@ -553,13 +558,12 @@ def _def_to_py_ast( # pylint: disable=too-many-branches
553
558
defsym = node .name
554
559
is_defn = False
555
560
556
- if INIT in node .children :
561
+ if node .init is not None :
557
562
# Since Python function definitions always take the form `def name(...):`,
558
563
# it is redundant to assign them to the their final name after they have
559
564
# been defined under a private alias. This codepath generates `defn`
560
565
# declarations by directly generating the Python `def` with the correct
561
566
# function name and short-circuiting the default double-declaration.
562
- assert node .init is not None , "Def init must be defined"
563
567
if node .init .op == NodeOp .FN :
564
568
assert isinstance (node .init , Fn )
565
569
def_ast = _fn_to_py_ast (ctx , node .init , def_name = defsym .name )
@@ -736,6 +740,7 @@ def __single_arity_fn_to_py_ast(
736
740
737
741
lisp_fn_name = node .local .name if node .local is not None else None
738
742
py_fn_name = __fn_name (lisp_fn_name ) if def_name is None else munge (def_name )
743
+ py_fn_node = ast .AsyncFunctionDef if node .is_async else ast .FunctionDef
739
744
with ctx .new_symbol_table (py_fn_name ), ctx .new_recur_point (
740
745
method .loop_id , RecurType .FN , is_variadic = node .is_variadic
741
746
):
@@ -751,7 +756,7 @@ def __single_arity_fn_to_py_ast(
751
756
return GeneratedPyAST (
752
757
node = ast .Name (id = py_fn_name , ctx = ast .Load ()),
753
758
dependencies = [
754
- ast . FunctionDef (
759
+ py_fn_node (
755
760
name = py_fn_name ,
756
761
args = ast .arguments (
757
762
args = fn_args ,
@@ -776,6 +781,7 @@ def __multi_arity_dispatch_fn(
776
781
arity_map : Dict [int , str ],
777
782
default_name : Optional [str ] = None ,
778
783
max_fixed_arity : Optional [int ] = None ,
784
+ is_async : bool = False ,
779
785
) -> GeneratedPyAST :
780
786
"""Return the Python AST nodes for a argument-length dispatch function
781
787
for multi-arity functions.
@@ -884,14 +890,15 @@ def fn(*args):
884
890
),
885
891
]
886
892
893
+ py_fn_node = ast .AsyncFunctionDef if is_async else ast .FunctionDef
887
894
return GeneratedPyAST (
888
895
node = ast .Name (id = name , ctx = ast .Load ()),
889
896
dependencies = [
890
897
ast .Assign (
891
898
targets = [ast .Name (id = dispatch_map_name , ctx = ast .Store ())],
892
899
value = ast .Dict (keys = dispatch_keys , values = dispatch_vals ),
893
900
),
894
- ast . FunctionDef (
901
+ py_fn_node (
895
902
name = name ,
896
903
args = ast .arguments (
897
904
args = [],
@@ -910,7 +917,7 @@ def fn(*args):
910
917
911
918
912
919
@_with_ast_loc_deps
913
- def __multi_arity_fn_to_py_ast (
920
+ def __multi_arity_fn_to_py_ast ( # pylint: disable=too-many-locals
914
921
ctx : GeneratorContext ,
915
922
node : Fn ,
916
923
methods : Collection [FnMethod ],
@@ -923,6 +930,8 @@ def __multi_arity_fn_to_py_ast(
923
930
lisp_fn_name = node .local .name if node .local is not None else None
924
931
py_fn_name = __fn_name (lisp_fn_name ) if def_name is None else munge (def_name )
925
932
933
+ py_fn_node = ast .AsyncFunctionDef if node .is_async else ast .FunctionDef
934
+
926
935
arity_to_name = {}
927
936
rest_arity_name : Optional [str ] = None
928
937
fn_defs = []
@@ -946,7 +955,7 @@ def __multi_arity_fn_to_py_ast(
946
955
ctx , method .params , method .body
947
956
)
948
957
fn_defs .append (
949
- ast . FunctionDef (
958
+ py_fn_node (
950
959
name = arity_name ,
951
960
args = ast .arguments (
952
961
args = fn_args ,
@@ -2113,6 +2122,7 @@ def _const_node_to_py_ast(ctx: GeneratorContext, lisp_ast: Const) -> GeneratedPy
2113
2122
2114
2123
2115
2124
_NODE_HANDLERS : Dict [NodeOp , PyASTGenerator ] = { # type: ignore
2125
+ NodeOp .AWAIT : _await_to_py_ast ,
2116
2126
NodeOp .CONST : _const_node_to_py_ast ,
2117
2127
NodeOp .DEF : _def_to_py_ast ,
2118
2128
NodeOp .DO : _do_to_py_ast ,
@@ -2203,9 +2213,7 @@ def _from_module_import() -> ast.ImportFrom:
2203
2213
2204
2214
2205
2215
def _ns_var (
2206
- py_ns_var : str = _NS_VAR ,
2207
- lisp_ns_var : str = _LISP_NS_VAR ,
2208
- lisp_ns_ns : str = _CORE_NS ,
2216
+ py_ns_var : str = _NS_VAR , lisp_ns_var : str = LISP_NS_VAR , lisp_ns_ns : str = CORE_NS
2209
2217
) -> ast .Assign :
2210
2218
"""Assign a Python variable named `ns_var` to the value of the current
2211
2219
namespace."""
0 commit comments