opencrbasic 1.1.0__tar.gz → 1.1.1__tar.gz
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.
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/PKG-INFO +4 -5
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/README.md +3 -4
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/pyproject.toml +4 -2
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/__init__.py +1 -1
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/analysis.py +1 -1
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/__init__.py +3 -4
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/cr3xx.py +3 -4
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/expressions.py +3 -5
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/instr_data.py +5 -7
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/instr_rules.py +1 -1
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/structure.py +8 -16
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/terminals.py +3 -3
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/warnings.py +4 -9
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checks.py +4 -4
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/cli.py +1 -1
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/compiler.py +1 -1
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/tests/corpus/README.md +21 -21
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/.gitignore +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/LICENSE +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/__main__.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/bindings.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/catalog.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checkconfig.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/ess.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/instr_measure.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/instructions.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/intervals.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/longconv.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/scan_time.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/storage.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/structs.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/symbols.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/unused.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/checker/var_types.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/commands.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/consteval.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/background_calibration.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/before_beginprog.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/background_calibration.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/before_beginprog.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/ess_variables.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/fnotch.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/functions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/instructions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/measure.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/mode.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/pipeline_tasks.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/settings_fields.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/status_members.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/symbols.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/terminals.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/before_beginprog.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/ess_variables.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/fnotch.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/functions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/instructions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/measure.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/mode.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/settings_fields.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/status_members.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/symbols.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr300/terminals.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/before_beginprog.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/ess_variables.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/fnotch.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/functions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/instructions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/measure.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/mode.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/settings_fields.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/status_members.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/symbols.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr350/terminals.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/ess_variables.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/fnotch.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/functions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/instructions.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/measure.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/mode.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/notices_cr6.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/pipeline_tasks.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/settings_fields.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/status_members.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/status_table.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/symbols.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/terminals.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/type_codes.json +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/diagnostics.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/editing.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/formatting.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/helpdocs.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/hover.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/inlay.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lexer.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/__init__.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/__main__.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/config.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/features.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/server.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/session.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/lsp/worker.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/macros.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/mode.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/navigation.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/parser.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/positions.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/preprocess.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/profiles.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/provenance.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/quickfix.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/rename.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/signature.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/source.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/sources.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/syntax.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/tables.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/tables_hook.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/tdf.py +0 -0
- {opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/timing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: opencrbasic
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: Open-source re-implementation of the Campbell Scientific CRBasic pre-compilers (CR6, CR1000X, CR300, CR350)
|
|
5
5
|
Project-URL: Repository, https://github.com/UtrechtUniversity/open-crbasic
|
|
6
6
|
Author: Utrecht University
|
|
@@ -38,8 +38,8 @@ Status, measured against the real compilers: `PROGRESS.md`. Design and the v1.0
|
|
|
38
38
|
## Scope
|
|
39
39
|
|
|
40
40
|
- **Gated profiles: CR6 and CR1000X.** On these, v1.0 gates the reference verdict in the relevant
|
|
41
|
-
area (the
|
|
42
|
-
first error for realistic mistakes on relevant rules, measured on the
|
|
41
|
+
area (the station/GEUS instruction set and language constructs), the execution mode, and the
|
|
42
|
+
first error for realistic mistakes on relevant rules, measured on the station programs, the 507
|
|
43
43
|
CRBasic help examples, the 66 GEUS programs, the saved fuzz replay and fresh `--relevant` fuzz
|
|
44
44
|
seeds. The help examples and GEUS programs are not redistributed here; see
|
|
45
45
|
[tests/corpus/README.md](tests/corpus/README.md) for running against local copies. One relevant-area false accept is known: a `Sub` name that is also another routine's
|
|
@@ -159,8 +159,7 @@ result.tables # list of tdf.TdfTable (Status, DataTables, DataTableInfo, ConstT
|
|
|
159
159
|
`parser.parse_file()` gives the syntax tree (`syntax.py`) for other tools.
|
|
160
160
|
|
|
161
161
|
[openloggernet](https://github.com/UtrechtUniversity/open-loggernet) uses opencrbasic when
|
|
162
|
-
`CR6COMP=opencrbasic` is set
|
|
163
|
-
CI.
|
|
162
|
+
`CR6COMP=opencrbasic` is set.
|
|
164
163
|
|
|
165
164
|
## Editor support
|
|
166
165
|
|
|
@@ -21,8 +21,8 @@ Status, measured against the real compilers: `PROGRESS.md`. Design and the v1.0
|
|
|
21
21
|
## Scope
|
|
22
22
|
|
|
23
23
|
- **Gated profiles: CR6 and CR1000X.** On these, v1.0 gates the reference verdict in the relevant
|
|
24
|
-
area (the
|
|
25
|
-
first error for realistic mistakes on relevant rules, measured on the
|
|
24
|
+
area (the station/GEUS instruction set and language constructs), the execution mode, and the
|
|
25
|
+
first error for realistic mistakes on relevant rules, measured on the station programs, the 507
|
|
26
26
|
CRBasic help examples, the 66 GEUS programs, the saved fuzz replay and fresh `--relevant` fuzz
|
|
27
27
|
seeds. The help examples and GEUS programs are not redistributed here; see
|
|
28
28
|
[tests/corpus/README.md](tests/corpus/README.md) for running against local copies. One relevant-area false accept is known: a `Sub` name that is also another routine's
|
|
@@ -142,8 +142,7 @@ result.tables # list of tdf.TdfTable (Status, DataTables, DataTableInfo, ConstT
|
|
|
142
142
|
`parser.parse_file()` gives the syntax tree (`syntax.py`) for other tools.
|
|
143
143
|
|
|
144
144
|
[openloggernet](https://github.com/UtrechtUniversity/open-loggernet) uses opencrbasic when
|
|
145
|
-
`CR6COMP=opencrbasic` is set
|
|
146
|
-
CI.
|
|
145
|
+
`CR6COMP=opencrbasic` is set.
|
|
147
146
|
|
|
148
147
|
## Editor support
|
|
149
148
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "opencrbasic"
|
|
3
|
-
version = "1.1.
|
|
3
|
+
version = "1.1.1"
|
|
4
4
|
description = "Open-source re-implementation of the Campbell Scientific CRBasic pre-compilers (CR6, CR1000X, CR300, CR350)"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -31,7 +31,8 @@ crbc-lsp = "opencrbasic.lsp.server:main"
|
|
|
31
31
|
# `uv sync` installs `dev` by default: the test runner and the reverse-engineering tools
|
|
32
32
|
# (`tools/extract_tables.py`, `tools/message_catalog.py` read the exe with pefile), and pygls
|
|
33
33
|
# so the suite can test the language server; pytest-xdist for parallel test runs (`-n`); pyrefly
|
|
34
|
-
# checks the repository (`[tool.pyrefly]`); pre-commit runs ruff and pyrefly before each commit
|
|
34
|
+
# checks the repository (`[tool.pyrefly]`); pre-commit runs ruff and pyrefly before each commit;
|
|
35
|
+
# openloggernet drives a logger for `tools/logger_oracle.py`.
|
|
35
36
|
dev = [
|
|
36
37
|
"pytest>=8",
|
|
37
38
|
"pefile>=2024.8.26",
|
|
@@ -39,6 +40,7 @@ dev = [
|
|
|
39
40
|
"pytest-xdist>=3.6",
|
|
40
41
|
"pyrefly==1.3.1",
|
|
41
42
|
"pre-commit>=4",
|
|
43
|
+
"openloggernet>=0.3.0",
|
|
42
44
|
]
|
|
43
45
|
|
|
44
46
|
[build-system]
|
|
@@ -14,7 +14,7 @@ from .compiler import compile_file
|
|
|
14
14
|
from .sources import DiskSource, LimitedSource, OverlaySource, RecordingSource, SourceProvider
|
|
15
15
|
|
|
16
16
|
API_VERSION = 2 # 2: findings, notices, config_error, AnalysisRequest.checks (M6)
|
|
17
|
-
DOCS = "https://github.com/UtrechtUniversity/
|
|
17
|
+
DOCS = "https://github.com/UtrechtUniversity/open-crbasic/blob/main/"
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
def _no_overlays() -> Mapping[Path, bytes]:
|
|
@@ -953,10 +953,9 @@ def _check(program: S.Program, profile: Profile, diags: Diagnostics, result) ->
|
|
|
953
953
|
|
|
954
954
|
if not diags.errors:
|
|
955
955
|
# `When Main Sequence Scan %d is running, background calibration will be disabled.`:
|
|
956
|
-
#
|
|
957
|
-
#
|
|
958
|
-
#
|
|
959
|
-
# `check_background_calibration` docstring has the oracle evidence). Independent of
|
|
956
|
+
# oracle-confirmed *not* ungated the way `_check_reachability`/`_check_fnotch` are
|
|
957
|
+
# (`checker/warnings.py`'s `check_background_calibration` docstring has the oracle evidence).
|
|
958
|
+
# Independent of
|
|
960
959
|
# `tables_hook`'s own availability, so called ahead of that guard rather than inside it.
|
|
961
960
|
_run_pass(warnings.check_background_calibration, program, profile, diags, env)
|
|
962
961
|
_run_pass(warnings.check_slow_scan_skips, program, profile, diags, env)
|
|
@@ -389,9 +389,8 @@ def check(program: S.Program, profile, diags: Diagnostics) -> None:
|
|
|
389
389
|
# `acceptdatarecords_1.CR6`, `SerialOpen (COMC1,...)`'s `COMC1 is not defined.` taints every
|
|
390
390
|
# following two-plus-argument instruction to end of file, `Scan`'s own `Sec` and
|
|
391
391
|
# `AcceptDataRecords`'s own `32769`, despite that finding being **ungated** and thus, in this
|
|
392
|
-
# project's own pass model, skipping tier B
|
|
393
|
-
#
|
|
394
|
-
# tier-B block the way `check_expr_cascade` was: `checker/__init__.py` now calls it once,
|
|
392
|
+
# project's own pass model, skipping tier B entirely), this is not called from inside the
|
|
393
|
+
# `if not diags.errors:` tier-B block: `checker/__init__.py` calls it once,
|
|
395
394
|
# unconditionally, after every other diagnostic-producing pass has run, so it can see -- and rewrite
|
|
396
395
|
# -- the complete, final diagnostic list regardless of which tier first tainted the file. It is
|
|
397
396
|
# still a no-op when nothing in the file ever taints (no `_is_cascade_trigger` match and no
|
|
@@ -555,7 +554,7 @@ def check_too_many_cascade(program: S.Program, profile, diags: Diagnostics) -> N
|
|
|
555
554
|
"""CR300/CR350 only; a no-op on every other logger and when nothing in the file ever taints
|
|
556
555
|
(see this module's comment above for the oracle evidence and the exact shape implemented).
|
|
557
556
|
Called from `checker/__init__.py` once, unconditionally, after every other pass -- see that
|
|
558
|
-
comment for why this
|
|
557
|
+
comment for why this cannot be tier-B-only.
|
|
559
558
|
"""
|
|
560
559
|
if profile.name not in ("cr300", "cr350"):
|
|
561
560
|
return
|
|
@@ -25,9 +25,8 @@ _TYPE_CODES_PATH = Path(__file__).resolve().parent.parent / "data" / "type_codes
|
|
|
25
25
|
# separate function (`4`/`16`/`17`/`19` `FUN_004b5db0`, a different failure message). Restricting
|
|
26
26
|
# to this explicit include-list (rather than excluding the handful of kinds known *not* to
|
|
27
27
|
# resolve) is deliberate: the default for an unrecognised kind is "don't check", so a gap in this
|
|
28
|
-
# list only under-reports, never falsely rejects
|
|
29
|
-
#
|
|
30
|
-
# `ConstTable(GlobalConfigTable)`, kind `expr_marker`) is the concrete case that shape of bug
|
|
28
|
+
# list only under-reports, never falsely rejects; the station corpus's `Main.CR6`
|
|
29
|
+
# `ConstTable(GlobalConfigTable)` (kind `expr_marker`) is the concrete case that shape of bug
|
|
31
30
|
# looks like.
|
|
32
31
|
_RESOLVED_KINDS = frozenset(
|
|
33
32
|
{
|
|
@@ -74,8 +73,7 @@ _CONST_FAMILY_KINDS = frozenset({"const_expr", "const_expr_only", "datatype_kw"}
|
|
|
74
73
|
# separate `FooBar is not defined.` / `BazQux is not defined.` lines on CR300/CR350, in the source
|
|
75
74
|
# (left-to-right) order `_undefined_names` already walks in. Modelled below as a plain per-logger
|
|
76
75
|
# branch on `profile.name` (both loggers in each pair share identical behaviour, oracle-confirmed
|
|
77
|
-
# side by side) rather than a new `Profile` field
|
|
78
|
-
# `checker/expressions.py`/`checker/symbols.py` (`PLAN.md`'s ownership split).
|
|
76
|
+
# side by side) rather than a new `Profile` field.
|
|
79
77
|
_WHOLE_EXPR_ECHO_LOGGERS = frozenset({"cr6", "cr1000x"})
|
|
80
78
|
|
|
81
79
|
# `NAN`/`INF` are accepted as predefined float constants on all four loggers (oracle-confirmed,
|
|
@@ -45,13 +45,11 @@ from . import symbols
|
|
|
45
45
|
# `docs/instructions.md`'s "not independently oracle-confirmed" list for exactly which those are.
|
|
46
46
|
# One more call site exists (the unlabelled string `"Et"`, near the `SampleFieldCal` call site)
|
|
47
47
|
# that could not be attributed to a specific instruction with confidence and is deliberately left
|
|
48
|
-
# out
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# `
|
|
52
|
-
#
|
|
53
|
-
# below not yet recognising `FFT` as a field producer, before `FFT` was added here too) and is
|
|
54
|
-
# included as `FFT`.
|
|
48
|
+
# out: never guess into a false reject. The other unlabelled string nearby, `"FFT"`, is
|
|
49
|
+
# independently confirmed (a scratch probe, `tfft.cr6`, and two CHM corpus files whose
|
|
50
|
+
# `DataTable` bodies contain only `FFT(...)` calls, `fft_1.CR6`/`covspa_1.CR6`, which compile
|
|
51
|
+
# only when `FFT` also counts as a field producer for `Table %s declared with no output
|
|
52
|
+
# fields.`) and is included as `FFT`.
|
|
55
53
|
TABLE_ONLY_INSTRUCTIONS: dict[str, str] = {
|
|
56
54
|
"CARDOUT": "CardOut", # checked with the oracle
|
|
57
55
|
"MQTTPUBLISHTABLE": "MQTTPublishTable",
|
|
@@ -1223,7 +1223,7 @@ def check_data_interval(program: S.Program, profile, diags: Diagnostics, env: co
|
|
|
1223
1223
|
per-logger difference, not shared with CR300/CR350 (`_SCAN_VALUE_CHECK_LOGGERS`; found the
|
|
1224
1224
|
same way as `check_scan_params`'s own CR300/CR350 gate, same session).
|
|
1225
1225
|
- `DataTable interval %d uSec not integrally divisible by scan interval %d uSec.` (function
|
|
1226
|
-
`FUN_004f6540`) -- project knowledge (`
|
|
1226
|
+
`FUN_004f6540`) -- project knowledge (open-crbasic-skills `lessons.md` "`DataInterval` versus
|
|
1227
1227
|
`Scan`": "a table interval must be at least the scan interval and an exact integer multiple
|
|
1228
1228
|
of it", human-verified against `CR6Comp.exe`), reported at each `CallTable <name>` site whose
|
|
1229
1229
|
table has a `DataInterval` and which sits directly inside a `Scan...NextScan` block (main
|
|
@@ -2186,7 +2186,7 @@ def check_pass2(
|
|
|
2186
2186
|
"Before `BeginProg`" only means the top level of the program, never a statement lexically
|
|
2187
2187
|
inside a `Sub`/`Function` body (regardless of that body's own textual position, almost always
|
|
2188
2188
|
before `BeginProg` itself, `docs/checker.md` "Pass model": found as a **regression** against
|
|
2189
|
-
|
|
2189
|
+
the station corpus's `Main.CR6` and several siblings, all of which call a built-in
|
|
2190
2190
|
function bare, with no `Call` keyword, e.g. `SerialOpen(...)` inside a `Function`/`Sub` defined
|
|
2191
2191
|
above `BeginProg` -- perfectly ordinary CRBasic, since the body only executes when the
|
|
2192
2192
|
`Sub`/`Function` is later called from inside `Scan`/`NextScan`, oracle-reconfirmed by re-running
|
|
@@ -5120,8 +5120,7 @@ def _check_array_dims(stmt: S.Declaration, diags: Diagnostics, env: consteval.En
|
|
|
5120
5120
|
separate variables of the same declaration.
|
|
5121
5121
|
|
|
5122
5122
|
A dimension that does not fold to a constant at all (`NotConstant`) is left alone: no oracle
|
|
5123
|
-
evidence
|
|
5124
|
-
reject an accepted program) rules out it.
|
|
5123
|
+
evidence supports guessing at that shape, and a guess could reject an accepted program.
|
|
5125
5124
|
"""
|
|
5126
5125
|
for index, v in enumerate(stmt.vars):
|
|
5127
5126
|
before = len(diags.items)
|
|
@@ -5779,24 +5778,17 @@ def _check_alias_dims(
|
|
|
5779
5778
|
check in this project) into a single **row-major flat offset** (`_alias_flat_offset`:
|
|
5780
5779
|
`flat = i_n + sum_{k<n} (i_k - 1) * prod(d_{k+1..n})`, the ordinary multi-dimensional-array-
|
|
5781
5780
|
as-flat-buffer formula, last index varying fastest) that must land in `[1,
|
|
5782
|
-
prod(all declared dims)]`.
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
reasons) -- a fresh, wider oracle sweep this round (`docs/checker.md` "Round 7") found the
|
|
5788
|
-
"first index alone" account is wrong in general: `Alias grid(4,-2) = Ts` (first index `4`,
|
|
5789
|
-
out of `[1,3]` by the old account) **compiles clean** (`(4-1)*3+(-2)=7`, in `[1,9]`), while
|
|
5790
|
-
`Alias grid(2,-1) = Ts` (a valid first index, an out-of-range *second* index by the old
|
|
5791
|
-
account, which the old rule never checked at all) also compiles clean
|
|
5792
|
-
(`(2-1)*3+(-1)=2`, in `[1,9]`) -- both correctly predicted by the flat formula, neither by
|
|
5793
|
-
"only check position 0". A **scalar** (no declared dimensions at all) behaves exactly like a
|
|
5781
|
+
prod(all declared dims)]`. Oracle evidence (`docs/checker.md` "Round 7"), for
|
|
5782
|
+
`Public grid(3,3)`: `Alias grid(2,4) = Ts` compiles (`(2-1)*3+4=7`), `Alias grid(4,2) = Ts`
|
|
5783
|
+
fails (`11`), and `Alias grid(4,-2) = Ts` (`7`) and `Alias grid(2,-1) = Ts` (`2`) both
|
|
5784
|
+
compile clean: the first index is not checked on its own. A **scalar** (no declared
|
|
5785
|
+
dimensions at all) behaves exactly like a
|
|
5794
5786
|
size-1 array (`Public y` / `Alias y(1) = Ts` compiles, `Alias y(2) = Ts` fails: flat
|
|
5795
5787
|
formula with `dims=(1,)` reduces to `flat=i1`, range `[1,1]`), which is why `declared_all_
|
|
5796
5788
|
dims` maps every declared variable, not just array ones, the same convention `dim0_sizes`
|
|
5797
5789
|
already used. Skipped (no check at all, under-reporting only) when any declared dimension or
|
|
5798
5790
|
any index argument does not fold to a constant (`declared_all_dims`/the tuple-folding loop
|
|
5799
|
-
below, both
|
|
5791
|
+
below, both conservative the same way check 3 is) or when the index
|
|
5800
5792
|
tuple's own length does not match the variable's own declared dimension count (no oracle
|
|
5801
5793
|
evidence gathered for that shape either way).
|
|
5802
5794
|
3. **`Duplicate Alias`** (round 7; no trailing period, no echoed name): the source side's own
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Per-logger analog-channel and port terminal model.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Models the analog-channel range check for all four loggers, driven by oracle-probed per-logger
|
|
4
|
+
data (`data/<logger>/terminals.json`; evidence, probes and the message-text differences:
|
|
5
|
+
`docs/loggers.md`, `docs/instructions.md`).
|
|
6
6
|
|
|
7
7
|
Each logger's `terminals.json` names its own channel "kinds" -- CR6 has separate `u_terminal`
|
|
8
8
|
(single-ended-shaped: any `U1..U12`, no oddness constraint; `ACPower`, `CS616`'s `CS616Chan`,
|
|
@@ -405,15 +405,10 @@ def check_background_calibration(program: S.Program, profile: Profile, diags: Di
|
|
|
405
405
|
`Invalid symbol in expression` error present (`Delay never reached at run time.` alongside it,
|
|
406
406
|
same probe file). A warning-only file (no errors, e.g. a reachability warning with no error
|
|
407
407
|
anywhere) still gets *both* warnings together, confirming this is specifically errors, not "any
|
|
408
|
-
diagnostic", that gates it.
|
|
409
|
-
tier (alongside `warnings.check`/`tables_hook.attach
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
`instr_rules.check_scan_min_interval` (this round): dozens of pre-existing `false_accept`/
|
|
413
|
-
`message_diff` fuzz reproducers (`tests/corpus/fuzz/cr6/message_diff/ba333c2ee146.CR6` and
|
|
414
|
-
siblings) already showed this exact extra, spurious warning line alongside an unrelated real
|
|
415
|
-
error -- a genuine, previously-undocumented false-accept-shaped bug independent of this round's
|
|
416
|
-
own `Scan`-interval work, not a regression it introduced.
|
|
408
|
+
diagnostic", that gates it. It is therefore called from `checker/__init__.py`'s final
|
|
409
|
+
`if not diags.errors:` tier (alongside `warnings.check`/`tables_hook.attach`), not from
|
|
410
|
+
`check_early`'s unconditional call site. Fuzz reproducers such as
|
|
411
|
+
`tests/corpus/fuzz/cr6/message_diff/ba333c2ee146.CR6` cover the gate.
|
|
417
412
|
"""
|
|
418
413
|
data = profile.background_calibration
|
|
419
414
|
if not data:
|
|
@@ -147,7 +147,7 @@ def _ambiguous_names(program: S.Program) -> set[str]:
|
|
|
147
147
|
def _numeric_concatenation(program: S.Program, profile) -> list[Finding]:
|
|
148
148
|
"""OCB002: a String `+` (or `&`) assigned to a numeric variable (`L = 2000 + Mid(S,5,2)`). The
|
|
149
149
|
reference accepts it, but `+` with a String operand concatenates, and the variable receives
|
|
150
|
-
the converted text: a GPS clock set this way read 2057 (`
|
|
150
|
+
the converted text: a GPS clock set this way read 2057 (open-crbasic-skills `lessons.md` "`+` with
|
|
151
151
|
a string operand concatenates", hardware 2026-10-22). Only a chain mixing numeric and String
|
|
152
152
|
operands is reported: a String alone (`X = Mid(...)`) is a plain conversion, and Strings joined
|
|
153
153
|
into a number's text (`X = HexStr(6) + "." + HexStr(7)`, GEUS programs) are deliberate."""
|
|
@@ -263,8 +263,8 @@ def _zero_divisors(program: S.Program, profile) -> list[Finding]:
|
|
|
263
263
|
|
|
264
264
|
def _unsized_string_parameters(program: S.Program, profile) -> list[Finding]:
|
|
265
265
|
"""OCB005: a `Sub`/`Function` String parameter without `* size`. It holds 23 characters (24
|
|
266
|
-
bytes with the terminator) and a longer argument is cut (hardware,
|
|
267
|
-
lessons.md` "Default string parameter size"). Information only: a short argument is fine."""
|
|
266
|
+
bytes with the terminator) and a longer argument is cut (hardware, open-crbasic-skills
|
|
267
|
+
`lessons.md` "Default string parameter size"). Information only: a short argument is fine."""
|
|
268
268
|
return [
|
|
269
269
|
Finding(
|
|
270
270
|
"OCB005",
|
|
@@ -284,7 +284,7 @@ def _unsized_string_parameters(program: S.Program, profile) -> list[Finding]:
|
|
|
284
284
|
def _unaligned_intervals(program: S.Program, profile) -> list[Finding]:
|
|
285
285
|
"""OCB006: a constant `DataInterval` that divides neither an hour nor a day (`7 Min`, `25 Hr`).
|
|
286
286
|
Its records are phased from the start hour and may not align with midnight (hardware,
|
|
287
|
-
`
|
|
287
|
+
open-crbasic-skills `lessons.md` "`DataInterval` phase"). Information only; an interval of 0
|
|
288
288
|
(every call) is not reported."""
|
|
289
289
|
env, out = _const_env(program, profile), []
|
|
290
290
|
for st in _statements(program):
|
|
@@ -142,7 +142,7 @@ def _message_bytes(lines: list[str]) -> bytes:
|
|
|
142
142
|
"""`lines` joined the way the message file actually wants them: CRLF throughout, except the
|
|
143
143
|
blank line straight after a `-- Compile Failed!` header, which the real exe writes as a bare
|
|
144
144
|
LF (oracle-confirmed on both a plain failing compile and a `-t`/`-b` one, `docs/cli.md`
|
|
145
|
-
"Message file layout"
|
|
145
|
+
"Message file layout").
|
|
146
146
|
"""
|
|
147
147
|
if len(lines) >= 2 and lines[1] == "" and lines[0].endswith("Failed!"):
|
|
148
148
|
return (lines[0] + "\r\n\n" + "\r\n".join(lines[2:]) + "\r\n").encode("latin-1", "replace")
|
|
@@ -156,7 +156,7 @@ class CompileResult:
|
|
|
156
156
|
# no-line `-u` warning, regardless of which included file declared it, prints before every
|
|
157
157
|
# "table declared but never called" warning). `_no_line_kind` below reproduces that
|
|
158
158
|
# ordering by message shape rather than by which module raised it, so this stays correct
|
|
159
|
-
# without `checker/warnings.py`
|
|
159
|
+
# without `checker/warnings.py` needing to tag its own
|
|
160
160
|
# diagnostics; a stable sort keeps each kind's own relative (insertion) order within itself.
|
|
161
161
|
# On one line the reachability warning follows that line's errors (oracle: 15 of 15 corpus
|
|
162
162
|
# and fuzz transcripts); other warnings keep their check order.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# Test corpora
|
|
2
|
-
|
|
3
|
-
| Directory | Contents | In git |
|
|
4
|
-
|---|---|---|
|
|
5
|
-
| `
|
|
6
|
-
| `fuzz/` | Saved fuzz reproducers seeded from `
|
|
7
|
-
| `chm/` | The 507 complete example programs in Campbell's CRBasic help. | no |
|
|
8
|
-
| `../../examples/Logger Programs/` | The 66 GEUS station programs used as a CR1000X corpus. | no |
|
|
9
|
-
|
|
10
|
-
The help examples and GEUS programs belong to others and are not redistributed
|
|
11
|
-
([docs/legal.md](../../docs/legal.md)). Tests that need them skip when they are absent. To run
|
|
12
|
-
those tests locally:
|
|
13
|
-
|
|
14
|
-
1. Extract the CRBasic help (the `.chm` installed with CRBasic Editor) into `extracted_chm/` at the
|
|
15
|
-
repository root, for example with `7z x CRBasic.chm -oextracted_chm`.
|
|
16
|
-
2. `uv run python tools/extract_chm_examples.py` writes `tests/corpus/chm/`.
|
|
17
|
-
3. Put the GEUS programs, if you have them, in `examples/Logger Programs/`.
|
|
18
|
-
4. For the differential tools, copy the Campbell compilers into `compiler/` (README, "How it was
|
|
19
|
-
built").
|
|
20
|
-
|
|
21
|
-
All of these paths are git-ignored.
|
|
1
|
+
# Test corpora
|
|
2
|
+
|
|
3
|
+
| Directory | Contents | In git |
|
|
4
|
+
|---|---|---|
|
|
5
|
+
| `station/` | A field station's CR6 programs and libraries (2026-11-01 snapshot). Tests pin results to these exact files, so refresh them only together with the expectations. | yes |
|
|
6
|
+
| `fuzz/` | Saved fuzz reproducers seeded from `station/`, replayed by `tools/fuzz_replay.py`. | yes |
|
|
7
|
+
| `chm/` | The 507 complete example programs in Campbell's CRBasic help. | no |
|
|
8
|
+
| `../../examples/Logger Programs/` | The 66 GEUS station programs used as a CR1000X corpus. | no |
|
|
9
|
+
|
|
10
|
+
The help examples and GEUS programs belong to others and are not redistributed
|
|
11
|
+
([docs/legal.md](../../docs/legal.md)). Tests that need them skip when they are absent. To run
|
|
12
|
+
those tests locally:
|
|
13
|
+
|
|
14
|
+
1. Extract the CRBasic help (the `.chm` installed with CRBasic Editor) into `extracted_chm/` at the
|
|
15
|
+
repository root, for example with `7z x CRBasic.chm -oextracted_chm`.
|
|
16
|
+
2. `uv run python tools/extract_chm_examples.py` writes `tests/corpus/chm/`.
|
|
17
|
+
3. Put the GEUS programs, if you have them, in `examples/Logger Programs/`.
|
|
18
|
+
4. For the differential tools, copy the Campbell compilers into `compiler/` (README, "How it was
|
|
19
|
+
built").
|
|
20
|
+
|
|
21
|
+
All of these paths are git-ignored.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opencrbasic-1.1.0 → opencrbasic-1.1.1}/src/opencrbasic/data/cr1000x/background_calibration.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|