Summary
#580 fixed the <action> of <args> form for include-exposed actions (confirmed working on the build below). But there is a third call form #580's fix did not cover: a zero-argument action referenced by its bare name, e.g. store x as greet where greet comes from an include from file.
Because a bare zero-arg reference parses to Expression::Variable("greet") (there is no FunctionCall/ActionCall node and no of/call keyword), it never reaches the include-aware relaxation that #548/#580 added — so it takes the plain fatal Variable '<name>' is not defined path. It is fatal at top level and inside action bodies, but (like #580's original of symptom) works inside a main loop. call greet and adding a dummy parameter both work.
Environment
- WFL
26.7.21 (WebFirst Language (WFL) version 26.7.21), Linux, release build (cargo build --release)
Minimal reproduction
mod.wfl:
define action called greet:
return "hello from greet"
end action
main.wfl:
include from "mod.wfl"
store x as greet
display x
wfl main.wfl →
error[ANALYZE-SEMANTIC]: Variable 'greet' is not defined
x never prints; exit 3. The same store x as greet in the same file (no include) prints hello from greet.
The matrix (measured on 26.7.21)
Zero-arg action greet exposed via include from, referenced by bare name:
| context |
result |
| top-level statement |
❌ fatal Variable 'greet' is not defined (exit 3) |
inside a define action body |
❌ fatal (exit 3) |
inside a main loop |
✅ works (hello from greet) |
store x as call greet (top level) |
✅ works (non-fatal Undefined action warning) |
give it a dummy param, store x as greet1 of "x" |
✅ works |
For contrast, #580's exact of <args> repro now passes on 26.7.21 — both at top level and in an action body:
// mod.wfl: define action called greet with parameters s: return "HI-" with s end action
include from "mod.wfl"
store g as greet of "bob"
display "AFTER=" with g // AFTER=HI-bob, exit 0
So the of form is fixed; the bare zero-arg form is the surviving variant of the same family (#548 → #580 → this).
Why it survives #580's fix (pointers into current main)
Suggested fix
When the Expression::Variable branch finds an unresolved name that is not a known variable/parameter/builtin and self.has_includes is true, route it through warn_undefined_callee_if_includes (treat it as a possible zero-arg include-exposed action call) instead of the fatal report_undefined_name. That makes the bare zero-arg form behave like the of and call forms already do under include from, and removes the top-level vs main loop inconsistency.
Workarounds
Any of: call it with call greet; give every shared action a dummy parameter and call it with of (e.g. build_shared of "x"); or keep zero-arg helpers in the same file that uses them.
Impact / context
Found while building the WFL website (wfl-web — the site is written in WFL, rendered with the Scribe templating engine, and served either statically or by WFL's own web server). To share the page model across files, every shared action in lib/site.wfl / lib/playground.wfl had to take a throwaway argument purely so it could be called across an include from — e.g. build_shared of "x" where build_shared needs no input. Minor, with easy workarounds, but it's a small "nothing to unlearn" wrinkle in the module surface now that #580 has smoothed the of form.
Summary
#580 fixed the
<action> of <args>form for include-exposed actions (confirmed working on the build below). But there is a third call form #580's fix did not cover: a zero-argument action referenced by its bare name, e.g.store x as greetwheregreetcomes from aninclude fromfile.Because a bare zero-arg reference parses to
Expression::Variable("greet")(there is noFunctionCall/ActionCallnode and noof/callkeyword), it never reaches the include-aware relaxation that #548/#580 added — so it takes the plain fatalVariable '<name>' is not definedpath. It is fatal at top level and inside action bodies, but (like #580's originalofsymptom) works inside amain loop.call greetand adding a dummy parameter both work.Environment
26.7.21(WebFirst Language (WFL) version 26.7.21), Linux, release build (cargo build --release)Minimal reproduction
mod.wfl:main.wfl:wfl main.wfl→xnever prints; exit3. The samestore x as greetin the same file (no include) printshello from greet.The matrix (measured on 26.7.21)
Zero-arg action
greetexposed viainclude from, referenced by bare name:Variable 'greet' is not defined(exit 3)define actionbodymain loophello from greet)store x as call greet(top level)Undefined actionwarning)store x as greet1 of "x"For contrast, #580's exact
of <args>repro now passes on 26.7.21 — both at top level and in an action body:So the
ofform is fixed; the bare zero-arg form is the surviving variant of the same family (#548 → #580 → this).Why it survives #580's fix (pointers into current
main)warn_undefined_callee_if_includes(src/analyzer/mod.rs:519). Its own doc comment says it is the single method that both theofform (FunctionCallwith a bare-Variablecallee) and thecall … withform (ActionCall) route through — that was #548 fix is incomplete:<action> of <args>to an include-exposed action is still context-dependently fatal (works inmain loop/tests, fatal at top level & in action bodies) #580's fix.Expression::Variablebranch atsrc/analyzer/mod.rs:2263, which callsreport_undefined_namedirectly (src/analyzer/mod.rs:2294).report_undefined_name(src/analyzer/mod.rs:497) is fatal (errors.push) unlesstry_depth > 0, and it does not consulthas_includes. So the bare-Variablepath never gets the relaxation the callee paths now enjoy → fatal. (Themain loopcell being non-fatal mirrors #548 fix is incomplete:<action> of <args>to an include-exposed action is still context-dependently fatal (works inmain loop/tests, fatal at top level & in action bodies) #580's original context-dependence, so the same context mechanism is presumably at play.)Suggested fix
When the
Expression::Variablebranch finds an unresolved name that is not a known variable/parameter/builtin andself.has_includesis true, route it throughwarn_undefined_callee_if_includes(treat it as a possible zero-arg include-exposed action call) instead of the fatalreport_undefined_name. That makes the bare zero-arg form behave like theofandcallforms already do underinclude from, and removes the top-level vsmain loopinconsistency.Workarounds
Any of: call it with
call greet; give every shared action a dummy parameter and call it withof(e.g.build_shared of "x"); or keep zero-arg helpers in the same file that uses them.Impact / context
Found while building the WFL website (wfl-web — the site is written in WFL, rendered with the Scribe templating engine, and served either statically or by WFL's own web server). To share the page model across files, every shared action in
lib/site.wfl/lib/playground.wflhad to take a throwaway argument purely so it could be called across aninclude from— e.g.build_shared of "x"wherebuild_sharedneeds no input. Minor, with easy workarounds, but it's a small "nothing to unlearn" wrinkle in the module surface now that #580 has smoothed theofform.