forked from algorandfoundation/puya
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__main__.py
More file actions
224 lines (208 loc) · 9.66 KB
/
__main__.py
File metadata and controls
224 lines (208 loc) · 9.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import sys
from collections.abc import Sequence
from importlib.metadata import version
from typing import Annotated, Literal
import cyclopts
from puya.algo_constants import MAINNET_AVM_VERSION, SUPPORTED_AVM_VERSIONS
from puya.errors import PuyaExitError
from puya.log import LogLevel, configure_logging, get_logger
from puya.options import LocalsCoalescingStrategy
from puyapy.compile import compile_to_teal
from puyapy.options import PuyaPyOptions
from puyapy.template import parse_template_key_value
logger = get_logger(__name__)
_app = cyclopts.App(help_on_error=True, version=f"puyapy {version('puyapy')}")
_outputs_group = cyclopts.Group(
name="Outputs",
help="Options for controlling what is output and where",
sort_key=10,
)
_compilation_group = cyclopts.Group(
name="Compilation",
help="Options that affect the compilation process, such as optimisation options etc.",
sort_key=20,
)
_templating_group = cyclopts.Group(
name="Templating",
help="Options for controlling the generation of TEAL template files",
sort_key=30,
)
_additional_outputs_group = cyclopts.Group(
name="Additional outputs",
help="Controls additional compiler outputs that may be useful to compiler developers.",
sort_key=100,
)
_OutputToggle = Annotated[bool, cyclopts.Parameter(group=_outputs_group)]
_InternalOutputToggle = Annotated[
bool, cyclopts.Parameter(group=_additional_outputs_group, negative=())
]
@_app.default
def puyapy(
paths: Annotated[
Sequence[cyclopts.types.ExistingPath], cyclopts.Parameter(name="PATH", negative=())
],
/,
*,
# outputs
out_dir: Annotated[
cyclopts.types.Directory | None, cyclopts.Parameter(group=_outputs_group)
] = None,
log_level: Annotated[LogLevel, cyclopts.Parameter(group=_outputs_group)] = LogLevel.info,
output_teal: _OutputToggle = True,
output_assembly_report: _OutputToggle = False,
output_source_map: _OutputToggle = True,
output_arc56: _OutputToggle = True,
output_arc32: _OutputToggle = False,
output_bytecode: _OutputToggle = False,
output_client: _OutputToggle = False,
debug_level: Annotated[
Literal[0, 1, 2], cyclopts.Parameter(alias="-g", group=_outputs_group)
] = 1,
# compilation
optimization_level: Annotated[
Literal[0, 1, 2], cyclopts.Parameter(alias="-O", group=_compilation_group)
] = 1,
treat_warnings_as_errors: Annotated[
bool, cyclopts.Parameter(alias="-Werror", group=_compilation_group)
] = False,
target_avm_version: Annotated[ # type: ignore[valid-type]
Literal[*SUPPORTED_AVM_VERSIONS],
cyclopts.Parameter(group=_compilation_group),
] = MAINNET_AVM_VERSION,
resource_encoding: Annotated[
Literal["index", "value"], cyclopts.Parameter(group=_compilation_group)
] = "value",
locals_coalescing_strategy: Annotated[
LocalsCoalescingStrategy, cyclopts.Parameter(group=_compilation_group)
] = LocalsCoalescingStrategy.root_operand,
validate_abi_args: Annotated[bool, cyclopts.Parameter(group=_compilation_group)] = True,
validate_abi_return: Annotated[bool, cyclopts.Parameter(group=_compilation_group)] = True,
validate_abi_values: Annotated[
bool | None, cyclopts.Parameter(group=_compilation_group, show=False)
] = None,
validate_abi_dynamic_severity: Annotated[
LogLevel | None,
cyclopts.Parameter(group=_compilation_group, show=False),
] = None,
# templating
template_var: Annotated[
Sequence[str],
cyclopts.Parameter(alias="-T", group=_templating_group, show_default=False, negative=()),
] = (),
template_vars_prefix: Annotated[str, cyclopts.Parameter(group=_templating_group)] = "TMPL_",
# internal outputs
output_awst: _InternalOutputToggle = False,
output_awst_json: _InternalOutputToggle = False,
output_source_annotations_json: _InternalOutputToggle = False,
output_ssa_ir: _InternalOutputToggle = False,
output_optimization_ir: _InternalOutputToggle = False,
output_destructured_ir: _InternalOutputToggle = False,
output_memory_ir: _InternalOutputToggle = False,
output_teal_intermediates: _InternalOutputToggle = False,
output_op_statistics: _InternalOutputToggle = False,
) -> None:
"""
PuyaPy compiler for compiling Algorand Python to TEAL
Parameters:
paths: Files or directories to compile
output_teal: Output TEAL code
output_assembly_report: Output "human-readable" source map
output_source_map: Output debug source maps
output_arc32: Output {contract}.arc32.json ARC-32 app spec file
output_arc56: Output {contract}.arc56.json ARC-56 app spec file
output_client: Output Algorand Python contract client for typed ARC-4 ABI calls
output_awst: Output parsed result of AWST
output_awst_json: Output parsed result of AWST as JSON
output_source_annotations_json: Output source annotations result of AWST parse as JSON
output_ssa_ir: Output IR (in SSA form) before optimizations
output_optimization_ir: Output IR after each optimization
output_destructured_ir: Output IR after SSA destructuring and before MIR
output_memory_ir: Output MIR before lowering to TEAL
output_bytecode: Output AVM bytecode
output_teal_intermediates: Output TEAL before peephole optimization and before
block optimization
output_op_statistics: Output statistics about ops used for each program compiled
optimization_level: Set optimization level of output TEAL / AVM bytecode
optimization_level: Set optimization level of output TEAL / AVM bytecode
treat_warnings_as_errors: Treat all compiler warnings as errors
debug_level: Output debug information level, 0 = none,
1 = debug, 2 = reserved for future use
target_avm_version: Target AVM version
template_var: Define template vars for use when assembling via --output-bytecode.
Should be specified without the prefix (see --template-vars-prefix), e.g.
-T SOME_INT=1234 SOME_BYTES=0x1A2B SOME_BOOL=True -T SOME_STR="hello"
template_vars_prefix: Define the prefix to use with --template-var
locals_coalescing_strategy: Strategy choice for out-of-ssa local variable coalescing.
The best choice for your app is best determined through
experimentation
resource_encoding: If "index", then resource types (Application, Asset, Account) in ABI
methods should be passed as an index into their
appropriate foreign array.
The default option "value", as of PuyaPy 5.0, means these values will be
passed directly.
validate_abi_args: Validates ABI transaction arguments by ensuring they are encoded
correctly
validate_abi_return: Validates encoding of ABI return values when using
`.from_log()`, `arc4.abi_call`, `arc4.arc4_create`
and `arc4.arc4_update`
out_dir: Path for outputting artefacts
log_level: Minimum level to log to console
"""
configure_logging(min_log_level=log_level)
_log_deprecated = logger.error if treat_warnings_as_errors else logger.warning
if validate_abi_dynamic_severity is not None:
_log_deprecated(
"the --validate-abi-dynamic-severity option is deprecated,"
" it has no effect and will be removed in a future version"
)
if validate_abi_values is not None:
_log_deprecated(
"the --validate_abi_values option is deprecated and will be removed in a future"
" version. It overrides --validate-abi-args and --validate-from-log options"
)
validate_abi_args = validate_abi_values
validate_abi_return = validate_abi_values
options = PuyaPyOptions(
paths=paths,
out_dir=out_dir,
log_level=log_level,
output_teal=output_teal,
output_assembly_report=output_assembly_report,
output_source_map=output_source_map,
output_arc56=output_arc56,
output_arc32=output_arc32,
output_bytecode=output_bytecode,
output_client=output_client,
debug_level=debug_level,
optimization_level=optimization_level,
treat_warnings_as_errors=treat_warnings_as_errors,
target_avm_version=target_avm_version,
resource_encoding=resource_encoding,
locals_coalescing_strategy=locals_coalescing_strategy,
output_awst=output_awst,
output_awst_json=output_awst_json,
output_source_annotations_json=output_source_annotations_json,
output_ssa_ir=output_ssa_ir,
output_optimization_ir=output_optimization_ir,
output_destructured_ir=output_destructured_ir,
output_memory_ir=output_memory_ir,
output_teal_intermediates=output_teal_intermediates,
output_op_statistics=output_op_statistics,
validate_abi_args=validate_abi_args,
validate_abi_return=validate_abi_return,
template_vars_prefix=template_vars_prefix,
cli_template_definitions=dict(parse_template_key_value(t) for t in template_var),
)
try:
compile_to_teal(options)
except PuyaExitError as ex:
sys.exit(ex.exit_code)
def _convert_argparse_style_flags(token: str) -> str:
match [*token]:
case "-", "O" | "g" as flag, value:
return f"-{flag}={value}"
return token
def app() -> None:
_app(map(_convert_argparse_style_flags, sys.argv[1:]))
if __name__ == "__main__":
app()