pycforge 0.15.2__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.
- pycforge/__init__.py +8 -0
- pycforge/__main__.py +2 -0
- pycforge/_version.py +1 -0
- pycforge/converter/__init__.py +0 -0
- pycforge/converter/analysis/__init__.py +5 -0
- pycforge/converter/analysis/functions.py +723 -0
- pycforge/converter/analysis/model.py +158 -0
- pycforge/converter/analysis/planning.py +464 -0
- pycforge/converter/analysis/stage.py +1976 -0
- pycforge/converter/analysis/symbols.py +237 -0
- pycforge/converter/analysis/validation.py +2166 -0
- pycforge/converter/c_output/__init__.py +2 -0
- pycforge/converter/c_output/conformance.py +297 -0
- pycforge/converter/c_output/renderer.py +220 -0
- pycforge/converter/conditional_regions/__init__.py +71 -0
- pycforge/converter/conditional_regions/analysis.py +481 -0
- pycforge/converter/conditional_regions/lowering.py +579 -0
- pycforge/converter/conditional_regions/model.py +243 -0
- pycforge/converter/conditional_regions/validation.py +690 -0
- pycforge/converter/containers/__init__.py +19 -0
- pycforge/converter/containers/analysis.py +542 -0
- pycforge/converter/containers/lowering.py +290 -0
- pycforge/converter/containers/model.py +146 -0
- pycforge/converter/contracts/__init__.py +0 -0
- pycforge/converter/contracts/configuration.py +178 -0
- pycforge/converter/contracts/identifiers.py +68 -0
- pycforge/converter/contracts/versions.py +71 -0
- pycforge/converter/core/__init__.py +0 -0
- pycforge/converter/core/artifact_io.py +87 -0
- pycforge/converter/core/cancellation.py +7 -0
- pycforge/converter/core/canonicalization.py +254 -0
- pycforge/converter/core/context.py +13 -0
- pycforge/converter/core/diagnostics.py +95 -0
- pycforge/converter/core/enums.py +23 -0
- pycforge/converter/core/fingerprint.py +22 -0
- pycforge/converter/core/pipeline.py +8 -0
- pycforge/converter/core/progress.py +25 -0
- pycforge/converter/core/request.py +50 -0
- pycforge/converter/core/resource_policy.py +31 -0
- pycforge/converter/core/result.py +23 -0
- pycforge/converter/core/serialization.py +36 -0
- pycforge/converter/core/stage.py +10 -0
- pycforge/converter/core/stage_artifact.py +80 -0
- pycforge/converter/core/stage_outcome.py +15 -0
- pycforge/converter/decision_trace/__init__.py +0 -0
- pycforge/converter/decision_trace/recorder.py +52 -0
- pycforge/converter/facade.py +459 -0
- pycforge/converter/frontend/__init__.py +4 -0
- pycforge/converter/frontend/normalizer.py +59 -0
- pycforge/converter/frontend/parser.py +20 -0
- pycforge/converter/frontend/source_document.py +93 -0
- pycforge/converter/frontend/stages.py +518 -0
- pycforge/converter/frontend/validation.py +76 -0
- pycforge/converter/io/__init__.py +0 -0
- pycforge/converter/io/atomic_writer.py +33 -0
- pycforge/converter/ir/__init__.py +1 -0
- pycforge/converter/ir/c_ir/__init__.py +4 -0
- pycforge/converter/ir/c_ir/builder.py +26 -0
- pycforge/converter/ir/c_ir/model.py +318 -0
- pycforge/converter/ir/c_ir/serialization.py +88 -0
- pycforge/converter/ir/c_ir/validation.py +834 -0
- pycforge/converter/ir/python_ir/__init__.py +17 -0
- pycforge/converter/ir/python_ir/nodes.py +86 -0
- pycforge/converter/keyword_calls/__init__.py +68 -0
- pycforge/converter/keyword_calls/analysis.py +458 -0
- pycforge/converter/keyword_calls/lowering.py +271 -0
- pycforge/converter/keyword_calls/model.py +304 -0
- pycforge/converter/keyword_calls/validation.py +802 -0
- pycforge/converter/keyword_only_calls/__init__.py +68 -0
- pycforge/converter/keyword_only_calls/analysis.py +640 -0
- pycforge/converter/keyword_only_calls/lowering.py +376 -0
- pycforge/converter/keyword_only_calls/model.py +328 -0
- pycforge/converter/keyword_only_calls/validation.py +1357 -0
- pycforge/converter/lowering.py +1000 -0
- pycforge/converter/modules/__init__.py +13 -0
- pycforge/converter/modules/analysis.py +1250 -0
- pycforge/converter/modules/lowering.py +200 -0
- pycforge/converter/modules/model.py +73 -0
- pycforge/converter/modules/stage.py +192 -0
- pycforge/converter/numeric_semantics/__init__.py +23 -0
- pycforge/converter/numeric_semantics/analysis.py +420 -0
- pycforge/converter/numeric_semantics/lowering.py +153 -0
- pycforge/converter/numeric_semantics/model.py +123 -0
- pycforge/converter/records/__init__.py +34 -0
- pycforge/converter/records/analysis.py +1394 -0
- pycforge/converter/records/lowering.py +393 -0
- pycforge/converter/records/model.py +319 -0
- pycforge/converter/rules/__init__.py +3 -0
- pycforge/converter/support_templates/__init__.py +49 -0
- pycforge/converter/support_templates/assembly.py +106 -0
- pycforge/converter/support_templates/factories.py +348 -0
- pycforge/converter/support_templates/model.py +159 -0
- pycforge/converter/support_templates/registry.py +388 -0
- pycforge/converter/telemetry/__init__.py +0 -0
- pycforge/converter/telemetry/sink.py +39 -0
- pycforge/ide/__init__.py +19 -0
- pycforge/ide/__main__.py +5 -0
- pycforge/ide/_worker_event_codec.py +276 -0
- pycforge/ide/_worker_protocol_json.py +197 -0
- pycforge/ide/_worker_protocol_types.py +90 -0
- pycforge/ide/_worker_request_codec.py +200 -0
- pycforge/ide/_worker_request_data.py +260 -0
- pycforge/ide/_worker_result_data.py +343 -0
- pycforge/ide/action_contract.py +469 -0
- pycforge/ide/action_validation.py +229 -0
- pycforge/ide/command_palette.py +223 -0
- pycforge/ide/controller.py +904 -0
- pycforge/ide/controller_conversion.py +546 -0
- pycforge/ide/controller_io.py +205 -0
- pycforge/ide/editor.py +951 -0
- pycforge/ide/editor_commands_qt.py +274 -0
- pycforge/ide/editor_lexical.py +43 -0
- pycforge/ide/editor_sidebars.py +236 -0
- pycforge/ide/editor_syntax.py +243 -0
- pycforge/ide/find_replace.py +535 -0
- pycforge/ide/icons.py +91 -0
- pycforge/ide/io_service.py +196 -0
- pycforge/ide/model.py +164 -0
- pycforge/ide/panels.py +903 -0
- pycforge/ide/positions.py +220 -0
- pycforge/ide/process_worker.py +130 -0
- pycforge/ide/qt.py +230 -0
- pycforge/ide/qt_actions.py +418 -0
- pycforge/ide/qt_close.py +169 -0
- pycforge/ide/qt_command_palette.py +297 -0
- pycforge/ide/qt_contract.py +220 -0
- pycforge/ide/qt_documents.py +590 -0
- pycforge/ide/qt_editor_buffers.py +113 -0
- pycforge/ide/qt_editor_surfaces.py +112 -0
- pycforge/ide/qt_menus.py +324 -0
- pycforge/ide/qt_projection.py +500 -0
- pycforge/ide/qt_shell.py +348 -0
- pycforge/ide/qt_shell_interactions.py +320 -0
- pycforge/ide/qt_state.py +393 -0
- pycforge/ide/qt_workspace_features.py +398 -0
- pycforge/ide/qt_workspace_navigation.py +208 -0
- pycforge/ide/qt_workspace_observers.py +173 -0
- pycforge/ide/qt_workspace_panels.py +545 -0
- pycforge/ide/qt_workspace_widgets.py +228 -0
- pycforge/ide/resources/icons/about.svg +1 -0
- pycforge/ide/resources/icons/add-document.svg +1 -0
- pycforge/ide/resources/icons/brand-mark.svg +1 -0
- pycforge/ide/resources/icons/bundle-search.svg +1 -0
- pycforge/ide/resources/icons/cancel.svg +1 -0
- pycforge/ide/resources/icons/check.svg +1 -0
- pycforge/ide/resources/icons/chevron-right.svg +1 -0
- pycforge/ide/resources/icons/close.svg +1 -0
- pycforge/ide/resources/icons/collapse-all.svg +1 -0
- pycforge/ide/resources/icons/command-palette.svg +1 -0
- pycforge/ide/resources/icons/convert.svg +1 -0
- pycforge/ide/resources/icons/copy.svg +1 -0
- pycforge/ide/resources/icons/cut.svg +1 -0
- pycforge/ide/resources/icons/decision-trace.svg +1 -0
- pycforge/ide/resources/icons/details.svg +1 -0
- pycforge/ide/resources/icons/diagnostics.svg +1 -0
- pycforge/ide/resources/icons/duplicate-line.svg +1 -0
- pycforge/ide/resources/icons/exit.svg +1 -0
- pycforge/ide/resources/icons/expand-all.svg +1 -0
- pycforge/ide/resources/icons/export.svg +1 -0
- pycforge/ide/resources/icons/find.svg +1 -0
- pycforge/ide/resources/icons/go-to-line.svg +1 -0
- pycforge/ide/resources/icons/go-to-output.svg +1 -0
- pycforge/ide/resources/icons/go-to-source.svg +1 -0
- pycforge/ide/resources/icons/history.svg +1 -0
- pycforge/ide/resources/icons/indent.svg +1 -0
- pycforge/ide/resources/icons/link-c.svg +1 -0
- pycforge/ide/resources/icons/mappings.svg +1 -0
- pycforge/ide/resources/icons/module.svg +1 -0
- pycforge/ide/resources/icons/move-down.svg +1 -0
- pycforge/ide/resources/icons/move-line-down.svg +1 -0
- pycforge/ide/resources/icons/move-line-up.svg +1 -0
- pycforge/ide/resources/icons/move-up.svg +1 -0
- pycforge/ide/resources/icons/next.svg +1 -0
- pycforge/ide/resources/icons/open.svg +1 -0
- pycforge/ide/resources/icons/outdent.svg +1 -0
- pycforge/ide/resources/icons/outline.svg +1 -0
- pycforge/ide/resources/icons/paste.svg +1 -0
- pycforge/ide/resources/icons/previous.svg +1 -0
- pycforge/ide/resources/icons/primary-module.svg +1 -0
- pycforge/ide/resources/icons/redo.svg +1 -0
- pycforge/ide/resources/icons/remove-document.svg +1 -0
- pycforge/ide/resources/icons/replace.svg +1 -0
- pycforge/ide/resources/icons/save-as.svg +1 -0
- pycforge/ide/resources/icons/save.svg +1 -0
- pycforge/ide/resources/icons/select-all.svg +1 -0
- pycforge/ide/resources/icons/settings.svg +1 -0
- pycforge/ide/resources/icons/show-c.svg +1 -0
- pycforge/ide/resources/icons/split-view.svg +1 -0
- pycforge/ide/resources/icons/summary.svg +1 -0
- pycforge/ide/resources/icons/telemetry.svg +1 -0
- pycforge/ide/resources/icons/toggle-comment.svg +1 -0
- pycforge/ide/resources/icons/toggle-fold.svg +1 -0
- pycforge/ide/resources/icons/undo.svg +1 -0
- pycforge/ide/resources/icons/whitespace.svg +1 -0
- pycforge/ide/revisions.py +400 -0
- pycforge/ide/search_service.py +280 -0
- pycforge/ide/session_history.py +150 -0
- pycforge/ide/source_editing.py +417 -0
- pycforge/ide/source_structure.py +558 -0
- pycforge/ide/source_structure_async.py +191 -0
- pycforge/ide/supervisor.py +503 -0
- pycforge/ide/theme.py +119 -0
- pycforge/ide/theme_stylesheet.py +598 -0
- pycforge/ide/theme_workspace_stylesheet.py +155 -0
- pycforge/ide/visual_tokens.py +142 -0
- pycforge/ide/worker_protocol.py +80 -0
- pycforge/ide/workspace_search.py +462 -0
- pycforge/ide/workspace_session.py +256 -0
- pycforge/laboratory/__init__.py +6 -0
- pycforge/laboratory/audits.py +2244 -0
- pycforge/laboratory/checkpoint_e.py +2685 -0
- pycforge/laboratory/cli.py +119 -0
- pycforge/laboratory/exit_codes.py +11 -0
- pycforge/laboratory/keyword_audit.py +661 -0
- pycforge/laboratory/keyword_only_audit.py +481 -0
- pycforge-0.15.2.dist-info/METADATA +209 -0
- pycforge-0.15.2.dist-info/RECORD +221 -0
- pycforge-0.15.2.dist-info/WHEEL +5 -0
- pycforge-0.15.2.dist-info/entry_points.txt +5 -0
- pycforge-0.15.2.dist-info/licenses/LICENSE +674 -0
- pycforge-0.15.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"""C IR lowering adapter for the approved fixed local-container profile.
|
|
2
|
+
|
|
3
|
+
The adapter owns only container representation mechanics. Scalar expression
|
|
4
|
+
evaluation, source binding, control-flow nesting, diagnostics, and provenance
|
|
5
|
+
remain services of the cumulative lowerer and are supplied explicitly.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import hashlib
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from typing import Any, Callable
|
|
13
|
+
|
|
14
|
+
from pycforge.converter.ir.c_ir import (
|
|
15
|
+
CAssignmentStatement,
|
|
16
|
+
CBinaryExpr,
|
|
17
|
+
CBinaryOp,
|
|
18
|
+
CBlock,
|
|
19
|
+
CForStatement,
|
|
20
|
+
CIdentifier,
|
|
21
|
+
CIdentifierRef,
|
|
22
|
+
CInitializerList,
|
|
23
|
+
CIntegerLiteral,
|
|
24
|
+
CStorage,
|
|
25
|
+
CSubscriptExpr,
|
|
26
|
+
CType,
|
|
27
|
+
CVariableDeclaration,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _sid(prefix: str, *parts: str) -> str:
|
|
32
|
+
return prefix + hashlib.sha256("\x1f".join(parts).encode()).hexdigest()[:20]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass(slots=True)
|
|
36
|
+
class ContainerLoweringServices:
|
|
37
|
+
nodes: dict[str, dict[str, Any]]
|
|
38
|
+
shapes: dict[str, dict[str, Any]]
|
|
39
|
+
bindings: dict[str, dict[str, Any]]
|
|
40
|
+
bindings_by_assignment: dict[str, dict[str, Any]]
|
|
41
|
+
accesses: dict[str, dict[str, Any]]
|
|
42
|
+
iterations: dict[str, dict[str, Any]]
|
|
43
|
+
source_bindings_by_id: dict[str, dict[str, Any]]
|
|
44
|
+
source_bindings_by_occurrence: dict[str, dict[str, Any]]
|
|
45
|
+
generated_names: dict[str, str]
|
|
46
|
+
generated_spellings: set[str]
|
|
47
|
+
expression: Callable[..., tuple[tuple[Any, ...], Any]]
|
|
48
|
+
temporary: Callable[..., tuple[CVariableDeclaration, CIdentifierRef]]
|
|
49
|
+
category_type: Callable[[str], CType]
|
|
50
|
+
identifier: Callable[[dict[str, Any], dict[str, Any]], CIdentifier]
|
|
51
|
+
provenance: Callable[..., Any]
|
|
52
|
+
synthetic_provenance: Callable[..., Any]
|
|
53
|
+
block_statements: Callable[..., tuple[Any, ...]]
|
|
54
|
+
temporary_spelling: Callable[[str, str], str]
|
|
55
|
+
reject: Callable[..., Any]
|
|
56
|
+
control_depth: Callable[[], int]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ContainerCIRLowerer:
|
|
60
|
+
"""Lower proved container facts without owning scalar or control semantics."""
|
|
61
|
+
|
|
62
|
+
def __init__(self, services: ContainerLoweringServices) -> None:
|
|
63
|
+
self.services = services
|
|
64
|
+
self.storage: dict[str, dict[str, Any]] = {}
|
|
65
|
+
self.component_spellings: dict[tuple[str, str], str] = {}
|
|
66
|
+
|
|
67
|
+
def declaration(self, node: dict[str, Any]) -> tuple[Any, ...]:
|
|
68
|
+
s = self.services
|
|
69
|
+
fact = s.bindings_by_assignment[node["node_id"]]
|
|
70
|
+
if not fact.get("valid"):
|
|
71
|
+
s.reject(fact.get("diagnostic_code") or "PYC3403", fact.get("reason") or "Invalid fixed container binding", node)
|
|
72
|
+
shape = s.shapes.get(fact["literal_node_id"])
|
|
73
|
+
if not shape or not shape.get("valid"):
|
|
74
|
+
s.reject(
|
|
75
|
+
(shape or {}).get("diagnostic_code") or "PYC3402",
|
|
76
|
+
(shape or {}).get("reason") or "Fixed container shape fact is absent or invalid",
|
|
77
|
+
s.nodes.get(fact["literal_node_id"], node),
|
|
78
|
+
)
|
|
79
|
+
target = s.nodes[fact["target_node_id"]]
|
|
80
|
+
binding = s.source_bindings_by_id.get(fact["binding_id"])
|
|
81
|
+
if not binding:
|
|
82
|
+
s.reject("PYC3403", "Fixed container binding cannot be resolved", target)
|
|
83
|
+
if s.control_depth():
|
|
84
|
+
s.reject("PYC3403", "A fixed container must be bound directly in a function body", node)
|
|
85
|
+
|
|
86
|
+
literal = s.nodes[fact["literal_node_id"]]
|
|
87
|
+
prelude: list[Any] = []
|
|
88
|
+
if fact["container_kind"] in {"list", "tuple"}:
|
|
89
|
+
element_refs: list[Any] = []
|
|
90
|
+
for ordinal, element_id in enumerate(shape["element_node_ids"]):
|
|
91
|
+
expression_prelude, expression = s.expression(s.nodes[element_id])
|
|
92
|
+
prelude.extend(expression_prelude)
|
|
93
|
+
declaration, reference = s.temporary(
|
|
94
|
+
"container_item",
|
|
95
|
+
literal,
|
|
96
|
+
ordinal,
|
|
97
|
+
s.category_type(fact["element_category"]),
|
|
98
|
+
expression,
|
|
99
|
+
(element_id, literal["node_id"]),
|
|
100
|
+
)
|
|
101
|
+
prelude.append(declaration)
|
|
102
|
+
element_refs.append(reference)
|
|
103
|
+
identifier = s.identifier(binding, target)
|
|
104
|
+
declaration = CVariableDeclaration(
|
|
105
|
+
_sid("c-container-array-", node["node_id"]),
|
|
106
|
+
identifier,
|
|
107
|
+
self._array_type(
|
|
108
|
+
fact["element_category"],
|
|
109
|
+
fact["capacity"],
|
|
110
|
+
readonly=fact["container_kind"] == "tuple",
|
|
111
|
+
),
|
|
112
|
+
CInitializerList(
|
|
113
|
+
_sid("c-container-init-", literal["node_id"]),
|
|
114
|
+
tuple(element_refs),
|
|
115
|
+
s.provenance(literal),
|
|
116
|
+
),
|
|
117
|
+
CStorage.NONE,
|
|
118
|
+
s.provenance(node),
|
|
119
|
+
)
|
|
120
|
+
self.storage[fact["binding_id"]] = {
|
|
121
|
+
"iteration": identifier,
|
|
122
|
+
"values": identifier,
|
|
123
|
+
"kind": fact["container_kind"],
|
|
124
|
+
}
|
|
125
|
+
return tuple(prelude) + (declaration,)
|
|
126
|
+
|
|
127
|
+
key_refs: list[Any] = []
|
|
128
|
+
value_refs: list[Any] = []
|
|
129
|
+
for ordinal, (key_id, value_id) in enumerate(zip(shape["key_node_ids"], shape["value_node_ids"])):
|
|
130
|
+
key_prelude, key_expression = s.expression(s.nodes[key_id])
|
|
131
|
+
prelude.extend(key_prelude)
|
|
132
|
+
key_declaration, key_reference = s.temporary(
|
|
133
|
+
"container_key",
|
|
134
|
+
literal,
|
|
135
|
+
ordinal,
|
|
136
|
+
s.category_type(fact["key_category"]),
|
|
137
|
+
key_expression,
|
|
138
|
+
(key_id, literal["node_id"]),
|
|
139
|
+
)
|
|
140
|
+
prelude.append(key_declaration)
|
|
141
|
+
key_refs.append(key_reference)
|
|
142
|
+
|
|
143
|
+
value_prelude, value_expression = s.expression(s.nodes[value_id])
|
|
144
|
+
prelude.extend(value_prelude)
|
|
145
|
+
value_declaration, value_reference = s.temporary(
|
|
146
|
+
"container_value",
|
|
147
|
+
literal,
|
|
148
|
+
ordinal,
|
|
149
|
+
s.category_type(fact["value_category"]),
|
|
150
|
+
value_expression,
|
|
151
|
+
(value_id, literal["node_id"]),
|
|
152
|
+
)
|
|
153
|
+
prelude.append(value_declaration)
|
|
154
|
+
value_refs.append(value_reference)
|
|
155
|
+
|
|
156
|
+
key_identifier = self._component_identifier(fact, literal, "keys")
|
|
157
|
+
value_identifier = self._component_identifier(fact, literal, "values")
|
|
158
|
+
key_declaration = CVariableDeclaration(
|
|
159
|
+
_sid("c-container-keys-", node["node_id"]),
|
|
160
|
+
key_identifier,
|
|
161
|
+
self._array_type(fact["key_category"], fact["capacity"], readonly=True),
|
|
162
|
+
CInitializerList(_sid("c-container-keys-init-", literal["node_id"]), tuple(key_refs), s.provenance(literal)),
|
|
163
|
+
CStorage.NONE,
|
|
164
|
+
s.provenance(node),
|
|
165
|
+
)
|
|
166
|
+
value_declaration = CVariableDeclaration(
|
|
167
|
+
_sid("c-container-values-", node["node_id"]),
|
|
168
|
+
value_identifier,
|
|
169
|
+
self._array_type(fact["value_category"], fact["capacity"], readonly=True),
|
|
170
|
+
CInitializerList(_sid("c-container-values-init-", literal["node_id"]), tuple(value_refs), s.provenance(literal)),
|
|
171
|
+
CStorage.NONE,
|
|
172
|
+
s.provenance(node),
|
|
173
|
+
)
|
|
174
|
+
self.storage[fact["binding_id"]] = {
|
|
175
|
+
"iteration": key_identifier,
|
|
176
|
+
"values": value_identifier,
|
|
177
|
+
"kind": "dict",
|
|
178
|
+
}
|
|
179
|
+
return tuple(prelude) + (key_declaration, value_declaration)
|
|
180
|
+
|
|
181
|
+
def access(self, node: dict[str, Any]) -> tuple[tuple[Any, ...], Any]:
|
|
182
|
+
s = self.services
|
|
183
|
+
fact = s.accesses.get(node["node_id"])
|
|
184
|
+
if not fact or not fact.get("supported"):
|
|
185
|
+
s.reject(
|
|
186
|
+
(fact or {}).get("diagnostic_code") or "PYC3404",
|
|
187
|
+
(fact or {}).get("reason") or "Container access lacks a static proof",
|
|
188
|
+
node,
|
|
189
|
+
)
|
|
190
|
+
storage = self.storage.get(fact["binding_id"])
|
|
191
|
+
if not storage:
|
|
192
|
+
s.reject("PYC3403", "Container access occurs before its fixed local declaration", node)
|
|
193
|
+
offset = fact.get("resolved_offset")
|
|
194
|
+
if not isinstance(offset, int) or isinstance(offset, bool):
|
|
195
|
+
s.reject("PYC3404", "Container access lacks a resolved integer offset", node)
|
|
196
|
+
provenance = s.provenance(node)
|
|
197
|
+
identifier = storage["values"]
|
|
198
|
+
container = CIdentifierRef(
|
|
199
|
+
_sid("c-container-ref-", node["node_id"], identifier.binding_id),
|
|
200
|
+
identifier.binding_id,
|
|
201
|
+
provenance,
|
|
202
|
+
)
|
|
203
|
+
index = CIntegerLiteral(
|
|
204
|
+
_sid("c-container-offset-", node["node_id"]),
|
|
205
|
+
offset,
|
|
206
|
+
"LL",
|
|
207
|
+
s.synthetic_provenance((node["node_id"],), node["node_id"]),
|
|
208
|
+
)
|
|
209
|
+
return (), CSubscriptExpr(_sid("c-subscript-", node["node_id"]), container, index, provenance)
|
|
210
|
+
|
|
211
|
+
def iteration(self, node: dict[str, Any]) -> tuple[Any, ...]:
|
|
212
|
+
s = self.services
|
|
213
|
+
fact = s.iterations[node["node_id"]]
|
|
214
|
+
if not fact.get("supported"):
|
|
215
|
+
s.reject(fact.get("diagnostic_code") or "PYC3407", fact.get("reason") or "Unsupported container iteration", node)
|
|
216
|
+
storage = self.storage.get(fact["binding_id"])
|
|
217
|
+
if not storage:
|
|
218
|
+
s.reject("PYC3403", "Container iteration occurs before its fixed local declaration", node)
|
|
219
|
+
target = s.nodes[node["fields"]["target"]]
|
|
220
|
+
target_binding = s.source_bindings_by_occurrence.get(target["node_id"])
|
|
221
|
+
if not target_binding:
|
|
222
|
+
s.reject("PYC3407", "Container loop target binding could not be resolved", target)
|
|
223
|
+
|
|
224
|
+
index_binding_id = _sid("bind-container-index-", node["node_id"])
|
|
225
|
+
index_provenance = s.synthetic_provenance((node["node_id"],), node["node_id"])
|
|
226
|
+
index_identifier = CIdentifier(
|
|
227
|
+
index_binding_id,
|
|
228
|
+
s.temporary_spelling("index", index_binding_id),
|
|
229
|
+
index_provenance,
|
|
230
|
+
)
|
|
231
|
+
zero = CIntegerLiteral(_sid("c-container-loop-zero-", node["node_id"]), 0, "LL", index_provenance)
|
|
232
|
+
one = CIntegerLiteral(_sid("c-container-loop-one-", node["node_id"]), 1, "LL", index_provenance)
|
|
233
|
+
capacity = CIntegerLiteral(_sid("c-container-loop-capacity-", node["node_id"]), fact["capacity"], "LL", index_provenance)
|
|
234
|
+
initializer = CVariableDeclaration(
|
|
235
|
+
_sid("c-container-loop-init-", node["node_id"]),
|
|
236
|
+
index_identifier,
|
|
237
|
+
CType("int64_t"),
|
|
238
|
+
zero,
|
|
239
|
+
CStorage.NONE,
|
|
240
|
+
index_provenance,
|
|
241
|
+
)
|
|
242
|
+
condition_ref = CIdentifierRef(_sid("c-container-loop-condition-ref-", node["node_id"]), index_binding_id, index_provenance)
|
|
243
|
+
condition = CBinaryExpr(_sid("c-container-loop-condition-", node["node_id"]), CBinaryOp.LESS, condition_ref, capacity, index_provenance)
|
|
244
|
+
update_left = CIdentifierRef(_sid("c-container-loop-update-left-", node["node_id"]), index_binding_id, index_provenance)
|
|
245
|
+
update_value = CBinaryExpr(_sid("c-container-loop-update-value-", node["node_id"]), CBinaryOp.ADD, update_left, one, index_provenance)
|
|
246
|
+
update_target = CIdentifierRef(_sid("c-container-loop-update-target-", node["node_id"]), index_binding_id, index_provenance)
|
|
247
|
+
update = CAssignmentStatement(_sid("c-container-loop-update-", node["node_id"]), update_target, update_value, index_provenance)
|
|
248
|
+
|
|
249
|
+
data_identifier = storage["iteration"]
|
|
250
|
+
data_ref = CIdentifierRef(_sid("c-container-loop-data-", node["node_id"]), data_identifier.binding_id, index_provenance)
|
|
251
|
+
element_index = CIdentifierRef(_sid("c-container-loop-element-index-", node["node_id"]), index_binding_id, index_provenance)
|
|
252
|
+
element = CSubscriptExpr(_sid("c-container-loop-element-", node["node_id"]), data_ref, element_index, index_provenance)
|
|
253
|
+
target_declaration = CVariableDeclaration(
|
|
254
|
+
_sid("c-container-loop-target-", node["node_id"]),
|
|
255
|
+
s.identifier(target_binding, target),
|
|
256
|
+
s.category_type(fact["target_category"]),
|
|
257
|
+
element,
|
|
258
|
+
CStorage.NONE,
|
|
259
|
+
s.provenance(target, fallback_plan_node=node["node_id"]),
|
|
260
|
+
)
|
|
261
|
+
source_body = s.block_statements(node["fields"].get("body", []), loop=True)
|
|
262
|
+
body = CBlock(
|
|
263
|
+
_sid("c-container-loop-body-", node["node_id"]),
|
|
264
|
+
(target_declaration,) + source_body,
|
|
265
|
+
s.provenance(node),
|
|
266
|
+
)
|
|
267
|
+
return (CForStatement(_sid("c-container-loop-", node["node_id"]), initializer, condition, update, body, s.provenance(node)),)
|
|
268
|
+
|
|
269
|
+
def _array_type(self, category: str, capacity: int, *, readonly: bool = False) -> CType:
|
|
270
|
+
scalar = self.services.category_type(category)
|
|
271
|
+
return CType(scalar.base, scalar.qualifiers, scalar.pointer_depth, (capacity,), readonly)
|
|
272
|
+
|
|
273
|
+
def _component_identifier(self, fact: dict[str, Any], node: dict[str, Any], component: str) -> CIdentifier:
|
|
274
|
+
s = self.services
|
|
275
|
+
binding_id = _sid("bind-container-component-", fact["binding_id"], component)
|
|
276
|
+
key = (fact["binding_id"], component)
|
|
277
|
+
spelling = self.component_spellings.get(key)
|
|
278
|
+
if spelling is None:
|
|
279
|
+
base = f"{s.generated_names[fact['binding_id']]}_{component}"
|
|
280
|
+
spelling = base
|
|
281
|
+
suffix = 1
|
|
282
|
+
while spelling in s.generated_spellings:
|
|
283
|
+
suffix += 1
|
|
284
|
+
spelling = f"{base}_{suffix}"
|
|
285
|
+
s.generated_spellings.add(spelling)
|
|
286
|
+
self.component_spellings[key] = spelling
|
|
287
|
+
return CIdentifier(binding_id, spelling, s.synthetic_provenance((node["node_id"],), fact["assignment_node_id"]))
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
__all__ = ["ContainerCIRLowerer", "ContainerLoweringServices"]
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Immutable facts for the Phase 11 fixed local-container profile."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from pycforge.converter.analysis.model import ValueCategory
|
|
9
|
+
from pycforge.converter.contracts.configuration import MAX_CONTAINER_ELEMENTS
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True, slots=True)
|
|
14
|
+
class ContainerShapeFact:
|
|
15
|
+
literal_node_id: str
|
|
16
|
+
container_kind: str
|
|
17
|
+
capacity: int
|
|
18
|
+
element_node_ids: tuple[str, ...]
|
|
19
|
+
key_node_ids: tuple[str, ...]
|
|
20
|
+
value_node_ids: tuple[str, ...]
|
|
21
|
+
element_category: ValueCategory
|
|
22
|
+
key_category: ValueCategory
|
|
23
|
+
value_category: ValueCategory
|
|
24
|
+
key_values: tuple[int | str, ...]
|
|
25
|
+
storage_model: str
|
|
26
|
+
mutable: bool
|
|
27
|
+
valid: bool
|
|
28
|
+
diagnostic_code: str | None
|
|
29
|
+
reason: str | None
|
|
30
|
+
|
|
31
|
+
def to_dict(self) -> dict[str, Any]:
|
|
32
|
+
return {
|
|
33
|
+
"literal_node_id": self.literal_node_id,
|
|
34
|
+
"container_kind": self.container_kind,
|
|
35
|
+
"capacity": self.capacity,
|
|
36
|
+
"element_node_ids": list(self.element_node_ids),
|
|
37
|
+
"key_node_ids": list(self.key_node_ids),
|
|
38
|
+
"value_node_ids": list(self.value_node_ids),
|
|
39
|
+
"element_category": self.element_category.value,
|
|
40
|
+
"key_category": self.key_category.value,
|
|
41
|
+
"value_category": self.value_category.value,
|
|
42
|
+
"key_values": list(self.key_values),
|
|
43
|
+
"storage_model": self.storage_model,
|
|
44
|
+
"mutable": self.mutable,
|
|
45
|
+
"valid": self.valid,
|
|
46
|
+
"diagnostic_code": self.diagnostic_code,
|
|
47
|
+
"reason": self.reason,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass(frozen=True, slots=True)
|
|
52
|
+
class ContainerBindingFact:
|
|
53
|
+
binding_id: str
|
|
54
|
+
source_name: str
|
|
55
|
+
assignment_node_id: str
|
|
56
|
+
target_node_id: str
|
|
57
|
+
literal_node_id: str
|
|
58
|
+
container_kind: str
|
|
59
|
+
capacity: int
|
|
60
|
+
element_category: ValueCategory
|
|
61
|
+
key_category: ValueCategory
|
|
62
|
+
value_category: ValueCategory
|
|
63
|
+
allowed_use_node_ids: tuple[str, ...]
|
|
64
|
+
invalid_use_node_ids: tuple[str, ...]
|
|
65
|
+
valid: bool
|
|
66
|
+
diagnostic_code: str | None
|
|
67
|
+
rejection_node_id: str | None
|
|
68
|
+
reason: str | None
|
|
69
|
+
|
|
70
|
+
def to_dict(self) -> dict[str, Any]:
|
|
71
|
+
return {
|
|
72
|
+
"binding_id": self.binding_id,
|
|
73
|
+
"source_name": self.source_name,
|
|
74
|
+
"assignment_node_id": self.assignment_node_id,
|
|
75
|
+
"target_node_id": self.target_node_id,
|
|
76
|
+
"literal_node_id": self.literal_node_id,
|
|
77
|
+
"container_kind": self.container_kind,
|
|
78
|
+
"capacity": self.capacity,
|
|
79
|
+
"element_category": self.element_category.value,
|
|
80
|
+
"key_category": self.key_category.value,
|
|
81
|
+
"value_category": self.value_category.value,
|
|
82
|
+
"allowed_use_node_ids": list(self.allowed_use_node_ids),
|
|
83
|
+
"invalid_use_node_ids": list(self.invalid_use_node_ids),
|
|
84
|
+
"valid": self.valid,
|
|
85
|
+
"diagnostic_code": self.diagnostic_code,
|
|
86
|
+
"rejection_node_id": self.rejection_node_id,
|
|
87
|
+
"reason": self.reason,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@dataclass(frozen=True, slots=True)
|
|
92
|
+
class ContainerAccessFact:
|
|
93
|
+
subscript_node_id: str
|
|
94
|
+
binding_id: str | None
|
|
95
|
+
container_kind: str | None
|
|
96
|
+
slice_node_id: str | None
|
|
97
|
+
result_category: ValueCategory
|
|
98
|
+
resolved_offset: int | None
|
|
99
|
+
source_index: int | None
|
|
100
|
+
key_value: int | str | None
|
|
101
|
+
supported: bool
|
|
102
|
+
diagnostic_code: str | None
|
|
103
|
+
reason: str | None
|
|
104
|
+
|
|
105
|
+
def to_dict(self) -> dict[str, Any]:
|
|
106
|
+
return {
|
|
107
|
+
"subscript_node_id": self.subscript_node_id,
|
|
108
|
+
"binding_id": self.binding_id,
|
|
109
|
+
"container_kind": self.container_kind,
|
|
110
|
+
"slice_node_id": self.slice_node_id,
|
|
111
|
+
"result_category": self.result_category.value,
|
|
112
|
+
"resolved_offset": self.resolved_offset,
|
|
113
|
+
"source_index": self.source_index,
|
|
114
|
+
"key_value": self.key_value,
|
|
115
|
+
"supported": self.supported,
|
|
116
|
+
"diagnostic_code": self.diagnostic_code,
|
|
117
|
+
"reason": self.reason,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(frozen=True, slots=True)
|
|
122
|
+
class ContainerIterationFact:
|
|
123
|
+
for_node_id: str
|
|
124
|
+
binding_id: str | None
|
|
125
|
+
container_kind: str | None
|
|
126
|
+
target_node_id: str | None
|
|
127
|
+
target_category: ValueCategory
|
|
128
|
+
capacity: int
|
|
129
|
+
order_policy: str
|
|
130
|
+
supported: bool
|
|
131
|
+
diagnostic_code: str | None
|
|
132
|
+
reason: str | None
|
|
133
|
+
|
|
134
|
+
def to_dict(self) -> dict[str, Any]:
|
|
135
|
+
return {
|
|
136
|
+
"for_node_id": self.for_node_id,
|
|
137
|
+
"binding_id": self.binding_id,
|
|
138
|
+
"container_kind": self.container_kind,
|
|
139
|
+
"target_node_id": self.target_node_id,
|
|
140
|
+
"target_category": self.target_category.value,
|
|
141
|
+
"capacity": self.capacity,
|
|
142
|
+
"order_policy": self.order_policy,
|
|
143
|
+
"supported": self.supported,
|
|
144
|
+
"diagnostic_code": self.diagnostic_code,
|
|
145
|
+
"reason": self.reason,
|
|
146
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"""Versioned public configuration identities for the promoted converter.
|
|
2
|
+
|
|
3
|
+
The constants in this module are deliberately data-only so the public request,
|
|
4
|
+
CLI, workspace, analysis, and lowering layers cannot drift to different phase
|
|
5
|
+
identities.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
DEFAULT_TARGET_CONTRACT = "c11-portable-fixed-v1"
|
|
11
|
+
DEFAULT_SEMANTIC_POLICY = "strict-source-v1"
|
|
12
|
+
PHASE9_RULE_SET = "phase9-functions-calls-v0.9"
|
|
13
|
+
PHASE11_RULE_SET = "phase11-bounded-containers-v0.11"
|
|
14
|
+
PHASE12_RULE_SET = "phase12-explicit-module-bundles-v0.12"
|
|
15
|
+
PHASE12_RENDERER = "c-renderer-v0.12"
|
|
16
|
+
PHASE12_MODULE_POLICY = "phase12-explicit-sourcebundle-modules-v0.12"
|
|
17
|
+
PHASE13_RULE_SET = "phase13-static-records-v0.13"
|
|
18
|
+
PHASE13_RENDERER = "c-renderer-v0.13"
|
|
19
|
+
# Phase 14A remains an explicit historical request profile after 14B becomes
|
|
20
|
+
# active. Keep these identities named rather than deriving them from the
|
|
21
|
+
# defaults so a historical request cannot be silently relabeled.
|
|
22
|
+
PHASE14A_RULE_SET = "phase14-bounded-numeric-v0.14"
|
|
23
|
+
PHASE14A_RENDERER = "c-renderer-v0.14"
|
|
24
|
+
PHASE14_RULE_SET = PHASE14A_RULE_SET
|
|
25
|
+
PHASE14_RENDERER = PHASE14A_RENDERER
|
|
26
|
+
PHASE14B_RULE_SET = "phase14-conditional-regions-v0.14.1"
|
|
27
|
+
PHASE14B_RENDERER = "c-renderer-v0.14.1"
|
|
28
|
+
PHASE14C_RULE_SET = "phase14-direct-keyword-calls-v0.14.2"
|
|
29
|
+
PHASE14C_RENDERER = "c-renderer-v0.14.2"
|
|
30
|
+
DEFAULT_RULE_SET = "phase14-required-keyword-only-calls-v0.14.3"
|
|
31
|
+
DEFAULT_RENDERER = "c-renderer-v0.14.3"
|
|
32
|
+
DEFAULT_HELPER_POLICY = "phase10-support-templates-v0.10"
|
|
33
|
+
DEFAULT_CONTAINER_POLICY = "phase11-fixed-local-containers-v0.11"
|
|
34
|
+
# Module, record, and numeric policies are deliberately unchanged in Phase 14B.
|
|
35
|
+
DEFAULT_MODULE_POLICY = "phase13-explicit-record-modules-v0.13"
|
|
36
|
+
DEFAULT_RECORD_POLICY = "phase13-immutable-automatic-records-v0.13"
|
|
37
|
+
PHASE14A_NUMERIC_POLICY = "phase14-proved-floor-arithmetic-v0.14"
|
|
38
|
+
DEFAULT_NUMERIC_POLICY = PHASE14A_NUMERIC_POLICY
|
|
39
|
+
MAX_CONTAINER_ELEMENTS = 64
|
|
40
|
+
MAX_SOURCE_DOCUMENTS = 64
|
|
41
|
+
MAX_IMPORT_ITEMS = 4_096
|
|
42
|
+
|
|
43
|
+
SUPPORTED_TARGET_CONTRACTS = frozenset(
|
|
44
|
+
{
|
|
45
|
+
DEFAULT_TARGET_CONTRACT,
|
|
46
|
+
# Read-compatible identity used by the earliest public request object.
|
|
47
|
+
"pycforge-c11-int64-v0.1",
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
SUPPORTED_SEMANTIC_POLICIES = frozenset(
|
|
51
|
+
{
|
|
52
|
+
DEFAULT_SEMANTIC_POLICY,
|
|
53
|
+
# Read-compatible identity used by the earliest public request object.
|
|
54
|
+
"strict-v0.1",
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
SUPPORTED_RULE_SETS = frozenset(
|
|
58
|
+
{
|
|
59
|
+
"phase3-frontend-v0.3",
|
|
60
|
+
"phase5-planning-v0.5",
|
|
61
|
+
"phase6-first-slice-v0.6",
|
|
62
|
+
"phase8-control-flow-v0.8",
|
|
63
|
+
PHASE9_RULE_SET,
|
|
64
|
+
PHASE11_RULE_SET,
|
|
65
|
+
PHASE12_RULE_SET,
|
|
66
|
+
PHASE13_RULE_SET,
|
|
67
|
+
PHASE14A_RULE_SET,
|
|
68
|
+
PHASE14B_RULE_SET,
|
|
69
|
+
PHASE14C_RULE_SET,
|
|
70
|
+
DEFAULT_RULE_SET,
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
SUPPORTED_RENDERERS = frozenset(
|
|
74
|
+
{
|
|
75
|
+
"phase3-none-v0.3",
|
|
76
|
+
"c-renderer-v0.6",
|
|
77
|
+
"c-renderer-v0.8",
|
|
78
|
+
"c-renderer-v0.9",
|
|
79
|
+
"c-renderer-v0.11",
|
|
80
|
+
PHASE12_RENDERER,
|
|
81
|
+
PHASE13_RENDERER,
|
|
82
|
+
PHASE14A_RENDERER,
|
|
83
|
+
PHASE14B_RENDERER,
|
|
84
|
+
PHASE14C_RENDERER,
|
|
85
|
+
DEFAULT_RENDERER,
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# Rule-set and renderer identities are a paired compatibility profile. Phase 5
|
|
90
|
+
# is planning-only and therefore keeps the current request default renderer;
|
|
91
|
+
# every rendering phase requires its exact historical renderer.
|
|
92
|
+
COMPATIBLE_RENDERERS_BY_RULE_SET = {
|
|
93
|
+
"phase3-frontend-v0.3": frozenset({"phase3-none-v0.3"}),
|
|
94
|
+
"phase5-planning-v0.5": frozenset({DEFAULT_RENDERER}),
|
|
95
|
+
"phase6-first-slice-v0.6": frozenset({"c-renderer-v0.6"}),
|
|
96
|
+
"phase8-control-flow-v0.8": frozenset({"c-renderer-v0.8"}),
|
|
97
|
+
PHASE9_RULE_SET: frozenset({"c-renderer-v0.9"}),
|
|
98
|
+
PHASE11_RULE_SET: frozenset({"c-renderer-v0.11"}),
|
|
99
|
+
PHASE12_RULE_SET: frozenset({PHASE12_RENDERER}),
|
|
100
|
+
PHASE13_RULE_SET: frozenset({PHASE13_RENDERER}),
|
|
101
|
+
PHASE14A_RULE_SET: frozenset({PHASE14A_RENDERER}),
|
|
102
|
+
PHASE14B_RULE_SET: frozenset({PHASE14B_RENDERER}),
|
|
103
|
+
PHASE14C_RULE_SET: frozenset({PHASE14C_RENDERER}),
|
|
104
|
+
DEFAULT_RULE_SET: frozenset({DEFAULT_RENDERER}),
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
SUPPORTED_HELPER_POLICIES = frozenset({DEFAULT_HELPER_POLICY})
|
|
108
|
+
SUPPORTED_CONTAINER_POLICIES = frozenset({DEFAULT_CONTAINER_POLICY})
|
|
109
|
+
SUPPORTED_MODULE_POLICIES = frozenset({PHASE12_MODULE_POLICY, DEFAULT_MODULE_POLICY})
|
|
110
|
+
SUPPORTED_RECORD_POLICIES = frozenset({DEFAULT_RECORD_POLICY})
|
|
111
|
+
SUPPORTED_NUMERIC_POLICIES = frozenset({DEFAULT_NUMERIC_POLICY})
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def supports_functions(rule_set: str) -> bool:
|
|
115
|
+
return rule_set in {
|
|
116
|
+
PHASE9_RULE_SET,
|
|
117
|
+
PHASE11_RULE_SET,
|
|
118
|
+
PHASE12_RULE_SET,
|
|
119
|
+
PHASE13_RULE_SET,
|
|
120
|
+
PHASE14A_RULE_SET,
|
|
121
|
+
PHASE14B_RULE_SET,
|
|
122
|
+
PHASE14C_RULE_SET,
|
|
123
|
+
DEFAULT_RULE_SET,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def supports_containers(rule_set: str) -> bool:
|
|
128
|
+
return rule_set in {
|
|
129
|
+
PHASE11_RULE_SET,
|
|
130
|
+
PHASE12_RULE_SET,
|
|
131
|
+
PHASE13_RULE_SET,
|
|
132
|
+
PHASE14A_RULE_SET,
|
|
133
|
+
PHASE14B_RULE_SET,
|
|
134
|
+
PHASE14C_RULE_SET,
|
|
135
|
+
DEFAULT_RULE_SET,
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def supports_modules(rule_set: str) -> bool:
|
|
140
|
+
return rule_set in {
|
|
141
|
+
PHASE12_RULE_SET,
|
|
142
|
+
PHASE13_RULE_SET,
|
|
143
|
+
PHASE14A_RULE_SET,
|
|
144
|
+
PHASE14B_RULE_SET,
|
|
145
|
+
PHASE14C_RULE_SET,
|
|
146
|
+
DEFAULT_RULE_SET,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def supports_records(rule_set: str) -> bool:
|
|
151
|
+
return rule_set in {
|
|
152
|
+
PHASE13_RULE_SET,
|
|
153
|
+
PHASE14A_RULE_SET,
|
|
154
|
+
PHASE14B_RULE_SET,
|
|
155
|
+
PHASE14C_RULE_SET,
|
|
156
|
+
DEFAULT_RULE_SET,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def supports_numeric(rule_set: str) -> bool:
|
|
161
|
+
return rule_set in {
|
|
162
|
+
PHASE14A_RULE_SET,
|
|
163
|
+
PHASE14B_RULE_SET,
|
|
164
|
+
PHASE14C_RULE_SET,
|
|
165
|
+
DEFAULT_RULE_SET,
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def supports_conditional_regions(rule_set: str) -> bool:
|
|
170
|
+
return rule_set in {PHASE14B_RULE_SET, PHASE14C_RULE_SET, DEFAULT_RULE_SET}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def supports_keyword_calls(rule_set: str) -> bool:
|
|
174
|
+
return rule_set in {PHASE14C_RULE_SET, DEFAULT_RULE_SET}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def supports_keyword_only_calls(rule_set: str) -> bool:
|
|
178
|
+
return rule_set == DEFAULT_RULE_SET
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Data-only ISO C11 identifier reservations shared by planning and validation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
C_KEYWORDS = frozenset({
|
|
7
|
+
"auto", "break", "case", "char", "const", "continue", "default", "do",
|
|
8
|
+
"double", "else", "enum", "extern", "float", "for", "goto", "if",
|
|
9
|
+
"inline", "int", "long", "register", "restrict", "return", "short",
|
|
10
|
+
"signed", "sizeof", "static", "struct", "switch", "typedef", "union",
|
|
11
|
+
"unsigned", "void", "volatile", "while", "_Alignas", "_Alignof",
|
|
12
|
+
"_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn",
|
|
13
|
+
"_Static_assert", "_Thread_local",
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
TARGET_RESERVED_NAMES = {
|
|
17
|
+
"bool", "true", "false", "size_t",
|
|
18
|
+
"int8_t", "uint8_t", "int16_t", "uint16_t", "int32_t", "uint32_t",
|
|
19
|
+
"int64_t", "uint64_t",
|
|
20
|
+
}
|
|
21
|
+
for _width in (8, 16, 32, 64):
|
|
22
|
+
TARGET_RESERVED_NAMES.update({
|
|
23
|
+
f"int_least{_width}_t", f"uint_least{_width}_t", f"int_fast{_width}_t", f"uint_fast{_width}_t",
|
|
24
|
+
f"INT{_width}_MIN", f"INT{_width}_MAX", f"UINT{_width}_MAX", f"INT{_width}_C", f"UINT{_width}_C",
|
|
25
|
+
f"INT_LEAST{_width}_MIN", f"INT_LEAST{_width}_MAX", f"UINT_LEAST{_width}_MAX",
|
|
26
|
+
f"INT_FAST{_width}_MIN", f"INT_FAST{_width}_MAX", f"UINT_FAST{_width}_MAX",
|
|
27
|
+
})
|
|
28
|
+
TARGET_RESERVED_NAMES.update({
|
|
29
|
+
"intptr_t", "uintptr_t", "intmax_t", "uintmax_t", "INTPTR_MIN", "INTPTR_MAX", "UINTPTR_MAX",
|
|
30
|
+
"INTMAX_MIN", "INTMAX_MAX", "UINTMAX_MAX", "INTMAX_C", "UINTMAX_C", "PTRDIFF_MIN", "PTRDIFF_MAX",
|
|
31
|
+
"SIG_ATOMIC_MIN", "SIG_ATOMIC_MAX", "SIZE_MAX", "WCHAR_MIN", "WCHAR_MAX", "WINT_MIN", "WINT_MAX",
|
|
32
|
+
})
|
|
33
|
+
TARGET_RESERVED_NAMES = frozenset(TARGET_RESERVED_NAMES)
|
|
34
|
+
|
|
35
|
+
# ISO C library identifiers with external linkage are reserved even when their
|
|
36
|
+
# declaring header is not included. `main` is included as the hosted entry point.
|
|
37
|
+
C11_EXTERNAL_IDENTIFIERS = frozenset("""
|
|
38
|
+
main errno stdin stdout stderr
|
|
39
|
+
isalnum isalpha isblank iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper
|
|
40
|
+
feclearexcept fegetexceptflag feraiseexcept fesetexceptflag fetestexcept fegetround fesetround fegetenv feholdexcept fesetenv feupdateenv
|
|
41
|
+
imaxabs imaxdiv strtoimax strtoumax wcstoimax wcstoumax setlocale localeconv setjmp longjmp signal raise
|
|
42
|
+
remove rename tmpfile tmpnam fclose fflush fopen freopen setbuf setvbuf fprintf fscanf printf scanf snprintf sprintf sscanf
|
|
43
|
+
vfprintf vfscanf vprintf vscanf vsnprintf vsprintf vsscanf fgetc fgets fputc fputs getc getchar putc putchar puts ungetc
|
|
44
|
+
fread fwrite fgetpos fseek fsetpos ftell rewind clearerr feof ferror perror
|
|
45
|
+
atof atoi atol atoll strtod strtof strtold strtol strtoll strtoul strtoull rand srand aligned_alloc calloc free malloc realloc
|
|
46
|
+
abort atexit at_quick_exit exit _Exit getenv quick_exit system bsearch qsort abs labs llabs div ldiv lldiv
|
|
47
|
+
mblen mbtowc wctomb mbstowcs wcstombs
|
|
48
|
+
memcpy memmove strcpy strncpy strcat strncat memcmp strcmp strcoll strncmp strxfrm memchr strchr strcspn strpbrk strrchr strspn strstr strtok memset strerror strlen
|
|
49
|
+
call_once cnd_broadcast cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait mtx_destroy mtx_init mtx_lock mtx_timedlock mtx_trylock mtx_unlock
|
|
50
|
+
thrd_create thrd_current thrd_detach thrd_equal thrd_exit thrd_join thrd_sleep thrd_yield tss_create tss_delete tss_get tss_set
|
|
51
|
+
clock difftime mktime time timespec_get asctime ctime gmtime localtime strftime
|
|
52
|
+
mbrtoc16 c16rtomb mbrtoc32 c32rtomb
|
|
53
|
+
fwprintf fwscanf swprintf swscanf vfwprintf vfwscanf vswprintf vswscanf vwprintf vwscanf wprintf wscanf
|
|
54
|
+
fgetwc fgetws fputwc fputws fwide getwc getwchar putwc putwchar ungetwc
|
|
55
|
+
wcstod wcstof wcstold wcstol wcstoll wcstoul wcstoull wcscpy wcsncpy wmemcpy wmemmove wcscat wcsncat
|
|
56
|
+
wmemcmp wcscmp wcscoll wcsncmp wcsxfrm wmemchr wcschr wcscspn wcspbrk wcsrchr wcsspn wcsstr wcstok wmemset wcslen wcsftime
|
|
57
|
+
btowc wctob mbsinit mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs
|
|
58
|
+
iswalnum iswalpha iswblank iswcntrl iswctype iswdigit iswgraph iswlower iswprint iswpunct iswspace iswupper iswxdigit towlower towupper towctrans wctype wctrans
|
|
59
|
+
""".split())
|
|
60
|
+
|
|
61
|
+
_MATH_EXTERNAL_BASES = frozenset("""
|
|
62
|
+
acos asin atan atan2 cos sin tan acosh asinh atanh exp exp2 expm1 frexp ilogb ldexp log log10 log1p log2 logb modf scalbn scalbln
|
|
63
|
+
cbrt fabs hypot pow sqrt erf erfc lgamma tgamma ceil floor nearbyint rint lrint llrint round lround llround trunc
|
|
64
|
+
fmod remainder remquo copysign nan nextafter nexttoward fdim fmax fmin fma
|
|
65
|
+
cacos casin catan ccos csin ctan cacosh casinh catanh cexp clog cabs cpow csqrt carg cimag conj cproj creal
|
|
66
|
+
""".split())
|
|
67
|
+
C11_EXTERNAL_IDENTIFIERS |= frozenset(name + suffix for name in _MATH_EXTERNAL_BASES for suffix in ("", "f", "l"))
|
|
68
|
+
|