Add POST coverage for physics-freeze words (Module 27), fix two real bugs found in the process
Cluster 4 of the POST-coverage sweep: physics_freeze_words_test.c covers the 6 words proof/StarForth_Physics_Freeze_Words.thy actually gives real lemmas for (FREEZE-WORD, UNFREEZE-WORD, FROZEN?, HEAT!, HEAT@, DECAY-RATE@), correcting an earlier fork summary's wrong "5 words" scope. Writing the tests surfaced two independent, pre-existing bugs in physics_freeze_words.c, both now fixed: - Every address-taking word cast the VM's caddr directly to a host pointer instead of resolving it through vm_ptr() -- caddr is an offset into vm->memory, not a host pointer. Fixed in all 9 call sites (the 5 in-scope words plus SHOW-HEAT, which shares the identical pattern). - Every underflow check used dsp < N (item count) instead of dsp < N-1, since this VM's dsp is a 0-indexed top-of-stack pointer. Fixed in all 6 checks. Together these meant every word in this file taking a stack-supplied name has been broken for any real caller since the file was written. Verified zero build warnings and a clean three-arch QEMU boot (amd64/aarch64/riscv64), 1009 passed / 0 failed / 0 errors identically on all three, dict_hash matching across arches. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
825ab078f1
commit
abb858a300
@@ -115,6 +115,12 @@ void run_q48_words_tests(VM * vm);
|
||||
*/
|
||||
void run_inference_words_tests(VM * vm);
|
||||
|
||||
/*
|
||||
* @brief Run tests for the proof-covered subset of physics-freeze words (Module 27)
|
||||
* @param vm Pointer to the VM instance
|
||||
*/
|
||||
void run_physics_freeze_words_tests(VM * vm);
|
||||
|
||||
/*
|
||||
* @brief Run tests for Mama FORTH vocabulary (capsule system M7.1)
|
||||
* @param vm Pointer to the VM instance
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
StarForth — Steady-State Virtual Machine Runtime
|
||||
|
||||
Copyright (c) 2023–2025 Robert A. James
|
||||
All rights reserved.
|
||||
|
||||
This file is part of the StarForth project.
|
||||
|
||||
Licensed under the StarForth License, Version 1.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
You may obtain a copy of the License at:
|
||||
https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
|
||||
|
||||
This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
express or implied, including but not limited to the warranties of
|
||||
merchantability, fitness for a particular purpose, and noninfringement.
|
||||
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* physics_freeze_words_test.c — POST tests for the proof-covered subset of
|
||||
* physics_freeze_words.c (Module 27)
|
||||
*
|
||||
* physics_freeze_words.c registers 9 words; proof/COVERAGE.md and
|
||||
* proof/StarForth_Physics_Freeze_Words.thy give real (non-"True"-placeholder)
|
||||
* lemmas for exactly 6 of them: FREEZE-WORD, UNFREEZE-WORD, FROZEN?, HEAT!,
|
||||
* HEAT@, DECAY-RATE@. FREEZE-CRITICAL, SHOW-HEAT, and ALL-HEATS carry only
|
||||
* trivial "not_modelled"/pass-through True lemmas, so they are intentionally
|
||||
* left uncovered here (matches the 6/9 figure in COVERAGE.md). No test file
|
||||
* for this module existed before.
|
||||
*
|
||||
* Each test case defines a scratch dictionary word (`:` ... `;`) and takes
|
||||
* its name via S" — every word here operates on ( caddr u ), the standard
|
||||
* counted-string-less pair the rest of the FORTH interpreter uses. Using
|
||||
* `run_test_suite` (no WordContract) rather than `run_test_suite_m`, matching
|
||||
* defining_words_tests.c's precedent: these test cases define dictionary
|
||||
* words, and check_physics_transparent's own contract explicitly documents
|
||||
* that its re-run mechanism does not snapshot/restore dictionary state.
|
||||
*/
|
||||
|
||||
#include "../include/test_runner.h"
|
||||
#include "../include/test_common.h"
|
||||
|
||||
/* Physics Freeze Words Test Suites - Module 27 */
|
||||
static WordTestSuite physics_freeze_word_suites[] = {
|
||||
{
|
||||
"FREEZE-WORD", {
|
||||
{"basic",
|
||||
": __freeze_test_word__ ; S\" __freeze_test_word__\" FREEZE-WORD S\" __freeze_test_word__\" FROZEN? . CR",
|
||||
"Should print: -1 (word is now frozen)", TEST_NORMAL, 0, 1, {0}},
|
||||
{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}
|
||||
},
|
||||
1, {0}
|
||||
},
|
||||
{
|
||||
"UNFREEZE-WORD", {
|
||||
{"basic",
|
||||
": __unfreeze_test_word__ ; S\" __unfreeze_test_word__\" FREEZE-WORD S\" __unfreeze_test_word__\" UNFREEZE-WORD S\" __unfreeze_test_word__\" FROZEN? . CR",
|
||||
"Should print: 0 (freeze cleared)", TEST_NORMAL, 0, 1, {0}},
|
||||
{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}
|
||||
},
|
||||
1, {0}
|
||||
},
|
||||
{
|
||||
"FROZEN?", {
|
||||
{"not_frozen",
|
||||
": __frozen_test_word__ ; S\" __frozen_test_word__\" FROZEN? . CR",
|
||||
"Should print: 0 (freshly defined word is not frozen)", TEST_NORMAL, 0, 1, {0}},
|
||||
{"not_found",
|
||||
"S\" __nonexistent_freeze_xyz__\" FROZEN? . CR",
|
||||
"Should print: 0 (not-found treated as not frozen)", TEST_EDGE_CASE, 0, 1, {0}},
|
||||
{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}
|
||||
},
|
||||
2, {0}
|
||||
},
|
||||
{
|
||||
"HEAT!", {
|
||||
{"basic",
|
||||
": __heat_store_test_word__ ; 999 S\" __heat_store_test_word__\" HEAT! S\" __heat_store_test_word__\" HEAT@ . CR",
|
||||
"Should print: 999", TEST_NORMAL, 0, 1, {0}},
|
||||
{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}
|
||||
},
|
||||
1, {0}
|
||||
},
|
||||
{
|
||||
"HEAT@", {
|
||||
{"of_fresh_word",
|
||||
": __heat_fetch_test_word__ ; S\" __heat_fetch_test_word__\" HEAT@ . CR",
|
||||
"Should print: 0 (freshly defined word has zero heat)", TEST_NORMAL, 0, 1, {0}},
|
||||
{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}
|
||||
},
|
||||
1, {0}
|
||||
},
|
||||
{
|
||||
"DECAY-RATE@", {
|
||||
{"basic", "DECAY-RATE@ . CR",
|
||||
"Should print the compile-time DECAY_RATE_PER_US_Q16 constant (no error)", TEST_NORMAL, 0, 1, {0}},
|
||||
{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}
|
||||
},
|
||||
1, {0}
|
||||
},
|
||||
{NULL, {{NULL, NULL, NULL, TEST_NORMAL, 0, 0, {0}}}, 0, {0}}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Executes the proof-covered subset of physics-freeze word test suites
|
||||
* @param vm Pointer to the Forth virtual machine instance
|
||||
* @details Covers the 6 words proof/StarForth_Physics_Freeze_Words.thy gives
|
||||
* real lemmas for: FREEZE-WORD, UNFREEZE-WORD, FROZEN?, HEAT!,
|
||||
* HEAT@, DECAY-RATE@. Does not cover FREEZE-CRITICAL, SHOW-HEAT, or
|
||||
* ALL-HEATS — those carry only trivial/not-modelled lemmas in the
|
||||
* same theory file.
|
||||
*/
|
||||
void run_physics_freeze_words_tests(VM *vm) {
|
||||
log_message(LOG_INFO, "Running Physics Freeze Words Tests (Module 27)...");
|
||||
|
||||
for (int i = 0; physics_freeze_word_suites[i].word_name != NULL; i++) {
|
||||
log_message(LOG_TEST, "▶ Testing module: %s", __FILE__);
|
||||
run_test_suite(vm, &physics_freeze_word_suites[i]);
|
||||
}
|
||||
|
||||
print_module_summary("Physics Freeze Words", 0, 0, 0, 0);
|
||||
}
|
||||
@@ -132,6 +132,7 @@ static TestModule test_modules[] = {
|
||||
{"Mama FORTH Words", NULL, 0, run_mama_forth_words_tests}, /* Module 24: Capsule System M7.1 */
|
||||
{"Q48.16 Words", NULL, 0, run_q48_words_tests}, /* Module 25: Q48.16 Fixed-Point Arithmetic */
|
||||
{"Inference Engine Words", NULL, 0, run_inference_words_tests}, /* Module 26: SSM Inference (proof-covered subset) */
|
||||
{"Physics Freeze Words", NULL, 0, run_physics_freeze_words_tests}, /* Module 27: Physics Freeze (proof-covered subset) */
|
||||
{NULL, NULL, 0, NULL} /* End marker */
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user