Files
wehub-resource-sync 41cb1c0170
OpenSSF Scorecard / scorecard (push) Failing after 0s
DCO / dco (push) Failing after 0s
CodeQL SAST / analyze (push) Failing after 1s
Deploy Pages / deploy (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:28:05 +08:00

642 lines
29 KiB
C

/*
* repro_grammar_scientific.c -- Exhaustive per-grammar INVARIANT battery for the
* SCIENTIFIC / SHADER / SMART-CONTRACT language family.
*
* One TEST() per language so per-language RED/GREEN shows on the bug-repro
* board. Each test runs the SAME battery against a tiny idiomatic fixture for
* that language: a function (or method) that CALLS another function strictly
* inside its body. The shared single-file + pipeline runners keep this DRY and
* identical to repro_grammar_core.c so the families are comparable.
*
* Languages covered (15) and the CBM_LANG_* enum each uses (all verified present
* in internal/cbm/cbm.h -- none missing, none skipped):
* GLSL -> CBM_LANG_GLSL (shader; reuses C node types)
* HLSL -> CBM_LANG_HLSL (shader; C++-family node types)
* WGSL -> CBM_LANG_WGSL (shader; own grammar)
* ISPC -> CBM_LANG_ISPC (shader/SIMD; C-family node types)
* Slang -> CBM_LANG_SLANG (shader; C++-family node types)
* Cairo -> CBM_LANG_CAIRO (smart-contract; Rust-like)
* Sway -> CBM_LANG_SWAY (smart-contract; Rust-like)
* FunC -> CBM_LANG_FUNC (smart-contract; TON)
* Wolfram -> CBM_LANG_WOLFRAM (CAS; assignment-as-definition)
* MATLAB -> CBM_LANG_MATLAB (numeric)
* Magma -> CBM_LANG_MAGMA (CAS)
* FORM -> CBM_LANG_FORM (symbolic; procedure_definition / call_statement)
* TLA+ -> CBM_LANG_TLAPLUS (formal spec; operator_definition)
* Agda -> CBM_LANG_AGDA (dependently-typed)
* Apex -> CBM_LANG_APEX (Salesforce; Java-like, methods only)
*
* BATTERY DIMENSIONS (identical to repro_grammar_core.c)
* -----------------------------------------------------
* SINGLE-FILE (cbm_extract_file, via inv_rx + inv_count_* helpers):
* 1. extract-clean : inv_extract_clean(src,lang,file) == 1
* 2. labels-valid : inv_count_bad_labels(r) == 0
* 3. fqn-wellformed : inv_count_bad_fqns(r) == 0
* 4. ranges-valid : inv_count_bad_ranges(r) == 0
* 5. defs-present : the function/method written in the fixture is extracted
* 6. calls-extracted : inv_has_call(r, "<callee>") == 1 (the in-body call)
*
* FULL-PIPELINE (rh_index_files -> cbm_store_t*, via inv_count_* store helpers):
* 7. callable-sourcing : module_sourced == 0 -- every in-body call sourced at a
* Function/Method node, NEVER at a Module node.
* 8. no-dangling : inv_count_dangling_edges(store,project,"CALLS") == 0
*
* ROBUSTNESS: each TEST also feeds a deliberately malformed fixture through the
* single-file extractor and asserts it RETURNS (no crash, NULL-or-result both
* acceptable). A hard crash would not return at all and would fail the test.
*
* KNOWN GAP (the point of this file): these are mostly grammar-only (non-LSP)
* languages, so dimension 7 (callable-sourcing) is expected RED for the majority
* via the same cbm_enclosing_func_qn -> Module fallback documented in
* repro_grammar_core.c (func_kinds_for_lang in helpers.c not matching the
* grammar's emitted function node types, with no cross-LSP rescue for these
* langs). Several langs are additionally expected RED at dimension 6
* (calls-extracted) because their call node type is unusual and the in-body
* call may not be captured at all: Wolfram (call=apply), FORM
* (call=call_statement), Agda (call=module_application), MATLAB (command/
* function_call ambiguity). RED rows ARE the deliverable -- they document the
* gap honestly per language.
*
* Coding rule: inline comments are line comments only (no block comments inside
* block comments).
*/
#include "test_framework.h"
#include "repro_invariant_lib.h"
#include <store/store.h>
#include <stdio.h>
#include <string.h>
/* ── Shared single-file battery (dimensions 1-6) ────────────────────────────
*
* Runs the six single-file invariants against one fixture. Returns 0 when all
* pass, 1 otherwise (printing a per-dimension FAIL line). lang_tag is for
* diagnostics only. expect_label / expect_label2 are def labels the fixture is
* guaranteed to produce; pass NULL for expect_label2 when the language's
* class/struct labeling is not asserted. callee is the in-body callee name that
* must appear in the extracted calls.
*/
static int single_file_battery(const char *lang_tag, const char *src,
CBMLanguage lang, const char *file,
const char *expect_label,
const char *expect_label2, const char *callee) {
const char *RED = tf_red();
const char *RST = tf_reset();
int fails = 0;
/* 1. extract-clean -- must hold before anything else is meaningful. */
if (inv_extract_clean(src, lang, file) != 1) {
printf(" %sFAIL%s [%s] extract-clean: NULL result or has_error set\n",
RED, RST, lang_tag);
return 1; /* nothing else can be trusted */
}
CBMFileResult *r = inv_rx(src, lang, file);
if (!r) {
printf(" %sFAIL%s [%s] inv_rx returned NULL after clean extract\n",
RED, RST, lang_tag);
return 1;
}
/* 2. labels-valid */
int bad_labels = inv_count_bad_labels(r);
if (bad_labels != 0) {
printf(" %sFAIL%s [%s] labels-valid: %d def(s) with invalid label\n",
RED, RST, lang_tag, bad_labels);
fails++;
}
/* 3. fqn-wellformed */
int bad_fqns = inv_count_bad_fqns(r);
if (bad_fqns != 0) {
printf(" %sFAIL%s [%s] fqn-wellformed: %d def(s) with malformed QN\n",
RED, RST, lang_tag, bad_fqns);
fails++;
}
/* 4. ranges-valid */
int bad_ranges = inv_count_bad_ranges(r);
if (bad_ranges != 0) {
printf(" %sFAIL%s [%s] ranges-valid: %d def(s) with invalid range\n",
RED, RST, lang_tag, bad_ranges);
fails++;
}
/* 5. defs-present -- the function/method the fixture wrote must be extracted. */
if (expect_label && inv_count_label(r, expect_label) < 1) {
printf(" %sFAIL%s [%s] defs-present: no def labelled \"%s\"\n",
RED, RST, lang_tag, expect_label);
fails++;
}
if (expect_label2 && inv_count_label(r, expect_label2) < 1) {
printf(" %sFAIL%s [%s] defs-present: no def labelled \"%s\"\n",
RED, RST, lang_tag, expect_label2);
fails++;
}
/* 6. calls-extracted -- the in-body call must be captured. */
if (inv_has_call(r, callee) != 1) {
printf(" %sFAIL%s [%s] calls-extracted: no call to \"%s\" found\n",
RED, RST, lang_tag, callee);
fails++;
}
cbm_free_result(r);
return fails ? 1 : 0;
}
/* ── Shared full-pipeline battery (dimensions 7-8) ──────────────────────────
*
* Indexes the single-file fixture through the production pipeline and asserts
* callable-sourcing (no Module-sourced in-body CALLS) and no dangling CALLS
* edges. Returns 0 on PASS, 1 on FAIL. Dimension 7 is RED for most grammar-only
* languages on current code -- that is the intended signal.
*/
static int pipeline_battery(const char *lang_tag, const char *filename,
const char *src) {
const char *RED = tf_red();
const char *RST = tf_reset();
RFile files[1];
files[0].name = filename;
files[0].content = src;
RProj lp;
cbm_store_t *store = rh_index_files(&lp, files, 1);
if (!store) {
printf(" %sFAIL%s [%s] pipeline: rh_index_files returned NULL\n",
RED, RST, lang_tag);
return 1;
}
int fails = 0;
/* 7. callable-sourcing -- mod must be 0; we also require >=1 callable-sourced
* edge so a fixture that produced zero CALLS edges cannot vacuously pass. */
int module_sourced = 0;
int callable_sourced = 0;
inv_count_calls_by_source(store, lp.project, &module_sourced,
&callable_sourced);
if (module_sourced != 0) {
printf(" %sFAIL%s [%s] callable-sourcing: %d in-body CALLS sourced at "
"Module (callable=%d) -- known enclosing-func gap\n",
RED, RST, lang_tag, module_sourced, callable_sourced);
fails++;
} else if (callable_sourced < 1) {
printf(" %sFAIL%s [%s] callable-sourcing: 0 CALLS edges (fixture "
"produced no in-body call edge to attribute)\n",
RED, RST, lang_tag);
fails++;
}
/* 8. no-dangling -- every CALLS edge endpoint must resolve. */
int dangling = inv_count_dangling_edges(store, lp.project, "CALLS");
if (dangling != 0) {
printf(" %sFAIL%s [%s] no-dangling: %d dangling CALLS endpoint(s)\n",
RED, RST, lang_tag, dangling);
fails++;
}
rh_cleanup(&lp, store);
return fails ? 1 : 0;
}
/* ── Robustness probe ───────────────────────────────────────────────────────
*
* Feed a deliberately malformed/truncated fixture through the single-file
* extractor. The ONLY invariant here is liveness: the call must RETURN (a hard
* crash would not). NULL or a result are both acceptable; if a result comes
* back its ranges must still be well-formed (no negative/inverted lines).
* Returns 0 on PASS (returned + ranges sane), 1 on FAIL.
*/
static int robustness_probe(const char *lang_tag, const char *bad_src,
CBMLanguage lang, const char *file) {
const char *RED = tf_red();
const char *RST = tf_reset();
CBMFileResult *r = inv_rx(bad_src, lang, file);
if (!r) {
/* Returned cleanly with NULL -- acceptable, no crash. */
return 0;
}
int bad_ranges = inv_count_bad_ranges(r);
cbm_free_result(r);
if (bad_ranges != 0) {
printf(" %sFAIL%s [%s] robustness: malformed input produced %d def(s) "
"with invalid range\n",
RED, RST, lang_tag, bad_ranges);
return 1;
}
return 0;
}
/* ── GLSL ────────────────────────────────────────────────────────────────────
* Shader; reuses C node types (c_func_types / c_call_types). Idiomatic: a helper
* function called from inside main(). No class/struct in the fixture (shaders
* have none). Expected: dims 1-6 + 8 GREEN, dim 7 RED (shares C func_kinds; the
* C family dominates the Module-sourced CALLS list).
*/
TEST(repro_grammar_scientific_glsl) {
static const char src[] =
"#version 450\n"
"\n"
"float scale(float x) {\n"
" return x * 2.0;\n"
"}\n"
"\n"
"void main() {\n"
" float v = scale(0.5);\n"
" gl_FragColor = vec4(v);\n"
"}\n";
if (single_file_battery("GLSL", src, CBM_LANG_GLSL, "shader.frag",
"Function", NULL, "scale") != 0)
return 1;
if (robustness_probe("GLSL", "void main() { float v = scale(",
CBM_LANG_GLSL, "shader.frag") != 0)
return 1;
return pipeline_battery("GLSL", "shader.frag", src);
}
/* ── HLSL ────────────────────────────────────────────────────────────────────
* Shader; C++-family node types (hlsl_func_types = function_definition,
* hlsl_call_types = call_expression). Idiomatic: a helper called from a pixel
* shader entry point. Expected: dims 1-6 + 8 GREEN, dim 7 RED (C++ func_kinds
* gap). No class/struct asserted (shaders rarely use them idiomatically here).
*/
TEST(repro_grammar_scientific_hlsl) {
static const char src[] =
"float scale(float x) {\n"
" return x * 2.0;\n"
"}\n"
"\n"
"float4 PSMain(float2 uv : TEXCOORD0) : SV_TARGET {\n"
" float v = scale(uv.x);\n"
" return float4(v, v, v, 1.0);\n"
"}\n";
if (single_file_battery("HLSL", src, CBM_LANG_HLSL, "shader.hlsl",
"Function", NULL, "scale") != 0)
return 1;
if (robustness_probe("HLSL", "float4 PSMain( { return scale(",
CBM_LANG_HLSL, "shader.hlsl") != 0)
return 1;
return pipeline_battery("HLSL", "shader.hlsl", src);
}
/* ── WGSL ────────────────────────────────────────────────────────────────────
* WebGPU shading language; own grammar (wgsl_func_types = function_declaration,
* wgsl_call_types = type_constructor_or_function_call_expression). Idiomatic: a
* helper fn called from an @fragment entry point. Expected: dims 1-6 + 8 GREEN,
* dim 7 RED (grammar-only, enclosing-func walk falls back to Module). The call
* node type is the unusual WGSL one -- dim 6 is a real risk if helpers.c does
* not map it.
*/
TEST(repro_grammar_scientific_wgsl) {
static const char src[] =
"fn scale(x: f32) -> f32 {\n"
" return x * 2.0;\n"
"}\n"
"\n"
"@fragment\n"
"fn fs_main() -> @location(0) vec4<f32> {\n"
" let v = scale(0.5);\n"
" return vec4<f32>(v, v, v, 1.0);\n"
"}\n";
if (single_file_battery("WGSL", src, CBM_LANG_WGSL, "shader.wgsl",
"Function", NULL, "scale") != 0)
return 1;
if (robustness_probe("WGSL", "fn fs_main() -> { let v = scale(",
CBM_LANG_WGSL, "shader.wgsl") != 0)
return 1;
return pipeline_battery("WGSL", "shader.wgsl", src);
}
/* ── ISPC ────────────────────────────────────────────────────────────────────
* Intel SPMD Program Compiler; C-family node types (ispc_func_types =
* function_definition, ispc_call_types = call_expression). Idiomatic: an inline
* helper called from an exported kernel. Expected: dims 1-6 + 8 GREEN, dim 7 RED
* (shares the C/C++ enclosing-func handling).
*/
TEST(repro_grammar_scientific_ispc) {
static const char src[] =
"static inline float scale(float x) {\n"
" return x * 2.0f;\n"
"}\n"
"\n"
"export void run(uniform float out[], uniform int n) {\n"
" foreach (i = 0 ... n) {\n"
" out[i] = scale((float)i);\n"
" }\n"
"}\n";
if (single_file_battery("ISPC", src, CBM_LANG_ISPC, "kernel.ispc",
"Function", NULL, "scale") != 0)
return 1;
if (robustness_probe("ISPC", "export void run( { out[0] = scale(",
CBM_LANG_ISPC, "kernel.ispc") != 0)
return 1;
return pipeline_battery("ISPC", "kernel.ispc", src);
}
/* ── Slang ───────────────────────────────────────────────────────────────────
* NVIDIA Slang shading language; C++-family node types (slang_func_types =
* function_definition, slang_call_types = call_expression). Idiomatic: a helper
* called from a compute entry point. Expected: dims 1-6 + 8 GREEN, dim 7 RED
* (C++ func_kinds gap, no cross-LSP rescue for Slang).
*/
TEST(repro_grammar_scientific_slang) {
static const char src[] =
"float scale(float x) {\n"
" return x * 2.0;\n"
"}\n"
"\n"
"[shader(\"compute\")]\n"
"void csMain(uint3 tid : SV_DispatchThreadID) {\n"
" float v = scale(float(tid.x));\n"
" outBuf[tid.x] = v;\n"
"}\n";
if (single_file_battery("Slang", src, CBM_LANG_SLANG, "shader.slang",
"Function", NULL, "scale") != 0)
return 1;
if (robustness_probe("Slang", "void csMain( { float v = scale(",
CBM_LANG_SLANG, "shader.slang") != 0)
return 1;
return pipeline_battery("Slang", "shader.slang", src);
}
/* ── Cairo ───────────────────────────────────────────────────────────────────
* StarkNet smart-contract language; Rust-like (cairo_func_types =
* function_definition/function_signature, cairo_call_types = call_expression/
* call). Idiomatic: a free fn calling another free fn. Expected: dims 1-6 + 8
* GREEN, dim 7 RED (Rust-shaped enclosing-func walk falls back to Module, no
* cross-LSP rescue for Cairo).
*/
TEST(repro_grammar_scientific_cairo) {
static const char src[] =
"fn add(a: felt252, b: felt252) -> felt252 {\n"
" a + b\n"
"}\n"
"\n"
"fn compute(x: felt252) -> felt252 {\n"
" add(x, 1)\n"
"}\n";
if (single_file_battery("Cairo", src, CBM_LANG_CAIRO, "lib.cairo",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("Cairo", "fn compute(x: felt252) -> { add(",
CBM_LANG_CAIRO, "lib.cairo") != 0)
return 1;
return pipeline_battery("Cairo", "lib.cairo", src);
}
/* ── Sway ────────────────────────────────────────────────────────────────────
* Fuel smart-contract language; Rust-like (sway_func_types = function_item,
* sway_call_types = call_expression). Idiomatic: a free fn calling another.
* Expected: dims 1-6 + 8 GREEN, dim 7 RED (same Rust-shaped enclosing-func gap).
*/
TEST(repro_grammar_scientific_sway) {
static const char src[] =
"fn add(a: u64, b: u64) -> u64 {\n"
" a + b\n"
"}\n"
"\n"
"fn compute(x: u64) -> u64 {\n"
" add(x, 1)\n"
"}\n";
if (single_file_battery("Sway", src, CBM_LANG_SWAY, "main.sw",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("Sway", "fn compute(x: u64) -> { add(",
CBM_LANG_SWAY, "main.sw") != 0)
return 1;
return pipeline_battery("Sway", "main.sw", src);
}
/* ── FunC ────────────────────────────────────────────────────────────────────
* TON smart-contract language; (func_func_types = function_definition,
* func_call_types = method_call). Idiomatic: a function calling another. NOTE
* the call node type is "method_call" -- if the grammar emits a plain call node
* for `add(x, 1)` rather than `method_call`, dim 6 (calls-extracted) is a real
* RED risk. Expected: dims 1-5 GREEN, dim 6 at risk, dim 7 RED, dim 8 GREEN.
*/
TEST(repro_grammar_scientific_func) {
static const char src[] =
"int add(int a, int b) {\n"
" return a + b;\n"
"}\n"
"\n"
"int compute(int x) {\n"
" return add(x, 1);\n"
"}\n";
if (single_file_battery("FunC", src, CBM_LANG_FUNC, "contract.fc",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("FunC", "int compute(int x) { return add(",
CBM_LANG_FUNC, "contract.fc") != 0)
return 1;
return pipeline_battery("FunC", "contract.fc", src);
}
/* ── Wolfram ─────────────────────────────────────────────────────────────────
* Wolfram Language / Mathematica; definitions are assignments (wolfram_func_types
* = set_delayed/set, wolfram_call_types = apply). Idiomatic: `add` defined with
* `:=`, then `compute` calls `add`. NOTE the call node type is "apply" -- the
* in-body `add[x, 1]` must surface as an apply node for dim 6 to pass; this is a
* real RED risk. Expected: dims 1-5 GREEN, dim 6 at risk, dim 7 RED (assignment-
* as-def has no function-node ancestry for the enclosing-func walk), dim 8 GREEN.
*/
TEST(repro_grammar_scientific_wolfram) {
static const char src[] =
"add[a_, b_] := a + b\n"
"\n"
"compute[x_] := add[x, 1]\n";
if (single_file_battery("Wolfram", src, CBM_LANG_WOLFRAM, "calc.wl",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("Wolfram", "compute[x_] := add[x,",
CBM_LANG_WOLFRAM, "calc.wl") != 0)
return 1;
return pipeline_battery("Wolfram", "calc.wl", src);
}
/* ── MATLAB ───────────────────────────────────────────────────────────────────
* Numeric; (matlab_func_types = function_definition, matlab_call_types =
* function_call/command). Idiomatic: a top-level function `compute` calling a
* local function `add`. NOTE MATLAB's call/command ambiguity: `add(x, 1)` should
* be a function_call, but a bare `add x` would parse as a command -- the
* idiomatic parenthesized form is used here. Expected: dims 1-6 + 8 GREEN, dim 7
* RED (enclosing-func gap).
*/
TEST(repro_grammar_scientific_matlab) {
static const char src[] =
"function r = compute(x)\n"
" r = add(x, 1);\n"
"end\n"
"\n"
"function s = add(a, b)\n"
" s = a + b;\n"
"end\n";
if (single_file_battery("MATLAB", src, CBM_LANG_MATLAB, "calc.m",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("MATLAB", "function r = compute(x)\n r = add(",
CBM_LANG_MATLAB, "calc.m") != 0)
return 1;
return pipeline_battery("MATLAB", "calc.m", src);
}
/* ── Magma ────────────────────────────────────────────────────────────────────
* Computational algebra system; (magma_func_types = function_definition/
* procedure_definition, magma_call_types = call_expression). Idiomatic: a
* function `Add` and a function `Compute` that calls it.
*
* Fixture correction: the prior `Add := function(a, b) ... end function;`
* assignment form does NOT parse to a `function_definition` in tree-sitter-magma
* — `function(a, b)` is read as a `call_expression` named "function" and the
* trailing `end function;` lands in an ERROR node, so no Function def was minted.
* The declarative `function Name(...) ... end function;` form (the construct the
* grammar and magma_func_types target) parses cleanly into `function_definition`
* with a `name` field. Expected: dims 1-6 + 8 GREEN, dim 7 RED (enclosing-func gap).
*/
TEST(repro_grammar_scientific_magma) {
static const char src[] =
"function Add(a, b)\n"
" return a + b;\n"
"end function;\n"
"\n"
"function Compute(x)\n"
" return Add(x, 1);\n"
"end function;\n";
if (single_file_battery("Magma", src, CBM_LANG_MAGMA, "calc.magma",
"Function", NULL, "Add") != 0)
return 1;
if (robustness_probe("Magma", "function Compute(x)\n return Add(",
CBM_LANG_MAGMA, "calc.magma") != 0)
return 1;
return pipeline_battery("Magma", "calc.magma", src);
}
/* ── FORM ─────────────────────────────────────────────────────────────────────
* Symbolic manipulation system; (form_func_types = procedure_definition,
* form_call_types = call_statement). Idiomatic: a `#procedure add` definition and
* a second procedure that `#call add` invokes. NOTE the call node type is
* "call_statement" matching FORM's `#call` preprocessor directive -- dim 6
* depends on the grammar emitting that node for `#call add`. Expected: dims 1-5
* GREEN, dim 6 at risk, dim 7 RED, dim 8 GREEN.
*/
TEST(repro_grammar_scientific_form) {
static const char src[] =
"#procedure add(x)\n"
" Local r = `x' + 1;\n"
"#endprocedure\n"
"\n"
"#procedure compute(y)\n"
" #call add(`y')\n"
"#endprocedure\n";
if (single_file_battery("FORM", src, CBM_LANG_FORM, "calc.frm",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("FORM", "#procedure compute(y)\n #call add(",
CBM_LANG_FORM, "calc.frm") != 0)
return 1;
return pipeline_battery("FORM", "calc.frm", src);
}
/* ── TLA+ ─────────────────────────────────────────────────────────────────────
* Formal specification language; (tlaplus_func_types = operator_definition/
* function_definition, tlaplus_call_types = function_evaluation/call). Idiomatic:
* an operator `Add` and an operator `Compute` that applies it. The defs surface
* via operator_definition; the in-body `Add(x, 1)` must surface as a
* function_evaluation/call node for dim 6. Expected: dims 1-5 GREEN, dim 6 at
* risk, dim 7 RED, dim 8 GREEN.
*/
TEST(repro_grammar_scientific_tlaplus) {
static const char src[] =
"---- MODULE Calc ----\n"
"Add(a, b) == a + b\n"
"Compute(x) == Add(x, 1)\n"
"====\n";
if (single_file_battery("TLA+", src, CBM_LANG_TLAPLUS, "Calc.tla",
"Function", NULL, "Add") != 0)
return 1;
if (robustness_probe("TLA+", "---- MODULE Calc ----\nCompute(x) == Add(",
CBM_LANG_TLAPLUS, "Calc.tla") != 0)
return 1;
return pipeline_battery("TLA+", "Calc.tla", src);
}
/* ── Agda ─────────────────────────────────────────────────────────────────────
* Dependently-typed language; (agda_func_types = function, agda_call_types =
* module_application). Idiomatic: a function `add` and a function `compute` that
* applies it. NOTE the call node type is "module_application" -- a plain function
* application `add x one` will almost certainly NOT match that node type, so dim
* 6 (calls-extracted) is a strong RED expectation. Expected: dims 1-5 GREEN, dim
* 6 RED, dim 7 RED (no callable-sourced edge to attribute -> 0 CALLS), dim 8
* GREEN (vacuously -- no edges).
*/
TEST(repro_grammar_scientific_agda) {
static const char src[] =
"module Calc where\n"
"\n"
"open import Agda.Builtin.Nat\n"
"\n"
"add : Nat -> Nat -> Nat\n"
"add a b = a + b\n"
"\n"
"compute : Nat -> Nat\n"
"compute x = add x 1\n";
if (single_file_battery("Agda", src, CBM_LANG_AGDA, "Calc.agda",
"Function", NULL, "add") != 0)
return 1;
if (robustness_probe("Agda", "module Calc where\ncompute x = add x",
CBM_LANG_AGDA, "Calc.agda") != 0)
return 1;
return pipeline_battery("Agda", "Calc.agda", src);
}
/* ── Apex ─────────────────────────────────────────────────────────────────────
* Salesforce Apex; Java-like, methods-only (apex_func_types = method_declaration/
* constructor_declaration, apex_class_types = class_declaration, apex_call_types =
* method_invocation). Idiomatic: a class with two methods, the public one calling
* the private one in-body. Expected: dims 1-6 + 8 GREEN, dim 7 likely RED
* (analogous to Java per the breadth-suite gap evidence). Asserts both "Method"
* and "Class" defs are present.
*/
TEST(repro_grammar_scientific_apex) {
static const char src[] =
"public class Calculator {\n"
" private Integer add(Integer a, Integer b) {\n"
" return a + b;\n"
" }\n"
"\n"
" public Integer compute(Integer x) {\n"
" return add(x, 1);\n"
" }\n"
"}\n";
if (single_file_battery("Apex", src, CBM_LANG_APEX, "Calculator.cls",
"Method", "Class", "add") != 0)
return 1;
if (robustness_probe("Apex", "public class Calculator { Integer compute() { return add(",
CBM_LANG_APEX, "Calculator.cls") != 0)
return 1;
return pipeline_battery("Apex", "Calculator.cls", src);
}
/* ── Suite ──────────────────────────────────────────────────────────────────── */
SUITE(repro_grammar_scientific) {
RUN_TEST(repro_grammar_scientific_glsl);
RUN_TEST(repro_grammar_scientific_hlsl);
RUN_TEST(repro_grammar_scientific_wgsl);
RUN_TEST(repro_grammar_scientific_ispc);
RUN_TEST(repro_grammar_scientific_slang);
RUN_TEST(repro_grammar_scientific_cairo);
RUN_TEST(repro_grammar_scientific_sway);
RUN_TEST(repro_grammar_scientific_func);
RUN_TEST(repro_grammar_scientific_wolfram);
RUN_TEST(repro_grammar_scientific_matlab);
RUN_TEST(repro_grammar_scientific_magma);
RUN_TEST(repro_grammar_scientific_form);
RUN_TEST(repro_grammar_scientific_tlaplus);
RUN_TEST(repro_grammar_scientific_agda);
RUN_TEST(repro_grammar_scientific_apex);
}