Summary
An action made available via include from can be called from inside a main loop or a describe/test block, but calling it from an ordinary top-level statement (module scope) raises a fatal Undefined action that aborts the whole program before any top-level code runs. The behavior is inconsistent depending on the call-site context.
Environment
- WFL built from source,
.build_meta.json: { "year": 26, "month": 6, "build": 5 }
- Linux, release build
Reproduction
mod.wfl (no stdlib, pure concatenation so this is isolated from #547):
define action called greet with parameters s:
return "HI-" with s
end action
main.wfl:
include from "mod.wfl"
display "BEFORE"
store g as call greet with "bob"
display "AFTER=" with g
Run wfl main.wfl:
error[ANALYZE-SEMANTIC]: Undefined action 'greet'
BEFORE is never printed — execution is aborted entirely (exit code 0).
Contrast — the same include works from other contexts
Called from a describe/test block (via wfl --test) or from inside a main loop, the same included action resolves correctly at runtime and returns the right value. In those contexts the analyzer still prints Undefined action, but it is non-fatal and the interpreter finds the action.
So:
| Call site |
Result |
| top-level statement |
fatal, program aborts, nothing runs |
check if block (top level) |
fatal |
main loop body |
works (analyzer warning is non-fatal) |
describe/test body |
works (analyzer warning is non-fatal) |
Expected
Consistent behavior: an include-exposed action should be callable from any context (or, if it genuinely can't be resolved, the error should be reported the same way everywhere — not fatal in one place and a harmless warning in another).
Notes
Likely related to how the semantic analyzer registers include-exposed actions relative to when top-level statements are checked. This is separate from #547 (that one is about stdlib calls inside an included action); this one reproduces with a pure, stdlib-free included action.
Summary
An action made available via
include fromcan be called from inside amain loopor adescribe/testblock, but calling it from an ordinary top-level statement (module scope) raises a fatalUndefined actionthat aborts the whole program before any top-level code runs. The behavior is inconsistent depending on the call-site context.Environment
.build_meta.json:{ "year": 26, "month": 6, "build": 5 }Reproduction
mod.wfl(no stdlib, pure concatenation so this is isolated from #547):main.wfl:Run
wfl main.wfl:BEFOREis never printed — execution is aborted entirely (exit code 0).Contrast — the same include works from other contexts
Called from a
describe/testblock (viawfl --test) or from inside amain loop, the same included action resolves correctly at runtime and returns the right value. In those contexts the analyzer still printsUndefined action, but it is non-fatal and the interpreter finds the action.So:
check ifblock (top level)main loopbodydescribe/testbodyExpected
Consistent behavior: an include-exposed action should be callable from any context (or, if it genuinely can't be resolved, the error should be reported the same way everywhere — not fatal in one place and a harmless warning in another).
Notes
Likely related to how the semantic analyzer registers include-exposed actions relative to when top-level statements are checked. This is separate from #547 (that one is about stdlib calls inside an included action); this one reproduces with a pure, stdlib-free included action.