Skip to content

engine: MDL parser ignores GET DIRECT SUBSCRIPT prefix (5th argument) #354

@bpowers

Description

@bpowers

Problem

The MDL parser in src/simlin-engine/src/mdl/convert/external_data.rs ignores the 5th argument to GET DIRECT SUBSCRIPT, which is a prefix string that should be prepended to element names loaded from external files.

The Vensim function signature is:

GET DIRECT SUBSCRIPT(file, tab, first_cell, last_cell, prefix)

The prefix argument is a string prepended to each element name read from the file. For example, if the file contains elements A, B, C and the prefix is 'Depth', the resulting dimension elements should be DepthA, DepthB, DepthC.

What happens today

  1. The GetDirectCall::Subscript enum variant (line 42-47) has a comment documenting the prefix parameter but does not include a prefix field in the struct.
  2. parse_get_direct (lines 120-131) reads only the first 4 arguments, silently discarding the 5th (prefix) argument.
  3. resolve_get_direct (lines 221-229) passes elements through from the DataProvider without any prefix prepending.

The existing test at line 398 even shows the 5th argument being present ('' -- empty prefix) but verifies it is discarded rather than stored:

let s = "{GET DIRECT SUBSCRIPT('b_subs.csv', ',', 'A2', 'A', '')}";

Concrete example

A model containing:

DimX: GET DIRECT SUBSCRIPT('depths.csv', ',', 'A1', 'A10', 'Depth')

Would produce elements like A, B, C instead of the correct DepthA, DepthB, DepthC. Any model using a non-empty prefix will get incorrect dimension element names.

Why it matters

  • Correctness: Models using non-empty prefixes (common in real-world Vensim models for namespace disambiguation) will get wrong dimension element names, causing downstream failures in dimension resolution, variable lookup, and simulation.
  • Silent failure: The prefix is silently dropped with no warning or error, making the root cause hard to diagnose.

Components affected

  • src/simlin-engine/src/mdl/convert/external_data.rs -- GetDirectCall::Subscript struct, parse_get_direct, and resolve_get_direct functions

Possible approach

  1. Add a prefix: String field to GetDirectCall::Subscript.
  2. In parse_get_direct, store args[4] (or default to empty string) as the prefix.
  3. In resolve_get_direct, after calling provider.load_subscript(), prepend the prefix to each returned element name (when the prefix is non-empty).
  4. Update the existing test to verify prefix storage, and add a test with a non-empty prefix.

Context

Identified during review of the mdl-full-compat branch. Related to #348 (GET DIRECT simulation support) but that issue covers overall function support, not this specific prefix-handling gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions