feat(dsl): C ABI and Python DSL checking, closing p7-s5 (#43) - #105
Merged
Conversation
Checking a DSL source needs no engine — it is a frontend service — so the result is its own opaque handle rather than an engine's diagnostic list. A failing check still produces one, because that is the case whose diagnostics a caller wants; only a NULL argument returns without it. A zero-initialized scn_dsl_check_options turns the standard library off, which is what a zero struct has to mean for an appendable ABI struct; NULL options therefore means the C++ defaults, library included. capi/ now links scena::frontend-dsl, PRIVATE like the XML frontend: no frontend type reaches capi.h, which stays C-clean. Refs #43
The XML loaders return (status, scenario) because the scenario is the payload and the findings are secondary. A check has no payload — the findings are the result, alongside how far the checker got — so it returns one named object instead of a four-tuple. DslCheck carries status, diagnostics, type_count and file_count, and is falsy unless the status is Ok. python/examples/check_dsl.py runs in CI: a clean source, a defective one, and an import resolved through a search path. Refs #43
…ing docs The parity audit only ever looked at scena::Engine methods, so the load and check entry points — the functions a host calls to get a scenario in — could lag a binding unnoticed. It now audits scena::xml and scena::dsl namespace-scope entry points alongside the methods, with the same exclusions-carry-reasons rule; xml::validate_* and dsl::load_* are excluded and say why. Also: the coverage matrix records all four checking surfaces, and scena-check.md gains the C and Python worked examples that c-api.md and python.md link to. Refs #43
scena-frontend-dsl is a static library, and this PR is the first thing to link it into a shared object (scena-capi and the Python extension). GNU ld rejects that outright without -fPIC. The XML frontend and the core already carry POSITION_INDEPENDENT_CODE for exactly this reason; macOS never noticed because its toolchain compiles PIC by default. Refs #43
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The last slice of p7-s5:
scena::dsl::check_*reaches all three of Scena'ssurfaces, so the DSL checker is not a C++-and-CLI-only feature.
C ABI
scn_check_dsl_file/scn_check_dsl_stringproduce an opaquescn_dsl_checkcarrying the diagnostics, the type count and the file count. Checking needs no
engine — it is a frontend service — which is why the result is its own handle
rather than an engine's diagnostic list, and why its borrowed strings stay valid
until
scn_dsl_check_destroyinstead of until the next mutating call.Two decisions worth naming:
diagnostics you want. Only a NULL argument returns without one, which is also
how a caller tells a null argument apart from an unreadable path — both answer
SCN_ERROR_INVALID_ARGUMENT, per the Status model's host-misuse split.scn_dsl_check_optionsturns the standard library off.A zero struct has to mean zero for an appendable ABI struct, so
NULLoptionsis what means "the C++ defaults, library included". Both are documented on the
declarations.
capi/linksscena::frontend-dslPRIVATE, like the XML frontend; nothing incapi.hnames a C++ type.No ABI version bump. The header's rule is that adding symbols moves the
minor, but nothing is published yet and every prior symbol addition (p5-s4,
p5-s5, p6-s1, p6-s2) also landed at
10000. Bumping only for this one wouldmisrepresent the others; the released version is the maintainer's call.
Python
scena.check_dsl_file/check_dsl_stringreturn aDslCheck—status,diagnostics,type_count,file_count, falsy unlessOk. The XML loadersreturn
(status, scenario)because the scenario is the payload and the findingsare secondary; a check has no payload, so a named object reads better than a
four-tuple.
python/examples/check_dsl.pyruns in CI: a clean source, a defective one, andan import resolved through a search path.
Parity audit
The audit only ever looked at
scena::Enginemethods, so the frontend entrypoints could lag a binding unnoticed — which is exactly what this PR would have
risked. It now audits the namespace-scope entry points of
scena::xmlandscena::dslalongside the methods, same exclusions-carry-reasons rule:xml::validate_*(loading validates on the way through) anddsl::load_*(thelower half of
check_*; its result is an AST no binding can carry).test_parity.py's doctored-header test copies the frontend headers into itssandbox too, so it still fails for the right reason.
Tests
capi_test.cpp+6: coverage, counts, search paths, the standard-librarytoggle, an unreadable path, and the null-argument sweep.
c_consumer.c: the same surface exercised from pure C11.test_dsl_check.py+10.Docs
scena-check.mdgains the C and Python worked examples;c-api.mdandpython.mdlink to them; the DSL coverage matrix records all four checkingsurfaces as a table of its own.
Closes #43