Skip to content

Actions/containers from load module are invisible to the static analyzer (fatal "not defined") #584

Description

@logbie

Summary

load module from "..." loads and runs another file at runtime, but the static analyzer does not register the symbols that module defines. As a result, referencing an action (or container) defined in a loaded module fails semantic analysis with a fatal Variable '<name>' is not defined, and the program never runs (exit 3) — even though the call would succeed at runtime.

Minimal reproduction

lib_mod.wfl:

define action called mod_double with parameters n:
    return n plus n
end action

main_mod.wfl:

load module from "lib_mod.wfl"
display mod_double of 5

Run wfl main_mod.wfl:

error[ANALYZE-SEMANTIC]: Variable 'mod_double' is not defined

(exit code 3; the program does not execute.)

Loading a module that only defines/assigns top-level variables and uses them itself works fine — the problem is specifically sharing actions/containers across files, because the analyzer can't see them.

Root cause

In src/analyzer/mod.rs, Statement::LoadModuleStatement only analyzes the path expression; it does not parse the referenced module and register its declarations in the current scope:

Statement::LoadModuleStatement { path, .. } => {
    self.analyze_expression(path);
}

Impact

It's effectively impossible to split a WFL program into a shared library file plus caller files when the library exposes actions — the standard way to organize a larger codebase. My workaround for a multi-file WFL project was to keep the whole library in one file and concatenate it with each caller via a build step, which defeats the purpose of load module.

Environment

  • wfl built from source at current main
  • rustc 1.94.1, cargo 1.94.1, Linux

Suggested fix

When analyzing LoadModuleStatement, resolve and parse the referenced module (as the interpreter does) and register its top-level action/container/variable declarations into the analyzer scope, so callers pass semantic analysis. Circular includes would need the same guard the runtime already uses.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions