origen_metal 1.4.0

Bare metal APIs for the Origen SDK
use crate::prog_gen::{
    BinType, FlowCondition, FlowID, GroupType, Limit, LimitSelector, ParamValue, PatternGroupType,
    ResourcesType, UniquenessOption,
};
use crate::prog_gen::supported_testers::SupportedTester;
use crate::prog_gen::advantest::smt8::processors::create_flow_data::FlowData;

#[derive(Clone, Debug, PartialEq, Serialize)]
pub enum PGM {
    /// This will be ignored by all processors, so can be used to indicate the absence of a node
    Nil,
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    //// Common pat gen and prog gen nodes
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    TesterEq(Vec<SupportedTester>), // Child nodes should only be processed when targetting the given tester(s)
    TesterNeq(Vec<SupportedTester>), // Child nodes should only be processed unless targetting the given tester(s)
    //// Teradyne custom nodes

    //// Advantest custom nodes

    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    //// Flow (prog gen) nodes
    //////////////////////////////////////////////////////////////////////////////////////////////////////////
    Flow(String),
    SubFlow(String, Option<FlowID>),
    /// Defines a new test, this must be done before attributes can be set via PGMSetAttr. Note that this doesn't
    /// actually add it to the test flow, that must be done via a PGMTest node
    ///         ID,    Name,     Tester,       Library  Template
    DefTest(usize, String, SupportedTester, String, String),
    /// Defines a new test invocation, this must be done before attributes can be set via PGMSetAttr. Note that
    /// this doesn't actually add it to the test flow, that must be done via a PGMTest node
    ///            ID,    Name,     Tester
    DefTestInv(usize, String, SupportedTester),
    /// Assign an existing test to an existing invocation
    ///                 InvID  TestID
    AssignTestToInv(usize, usize),
    /// Define a collection item underneath a test or another collection item
    ///                       ItemID ParentID CollectionName InstanceID AllowMissing
    DefTestCollectionItem(usize, usize, String, String, bool),
    /// Set the attribute with the given name within the given test (ID), to the given value
    SetAttr(usize, String, Option<ParamValue>, bool),
    /// Set the limit of the given test or invocation, (test_id, inv_id, hi/lo, value). Note that either test_id
    /// or inv_id must be present, but not both.
    SetLimit(Option<usize>, Option<usize>, LimitSelector, Option<Limit>),
    /// Execute a test (or invocation) from the flow
    Test(usize, FlowID),
    /// Execute a test (or invocation) from the flow, where the test is simply a string to be inserted
    /// into the flow
    ///                     Bin            Softbin        Number
    TestStr(String, FlowID, Option<usize>, Option<usize>, Option<usize>),
    /// Defines a new pattern group, also used to model IG-XL pattern sets
    PatternGroup(usize, String, SupportedTester, Option<PatternGroupType>),
    /// Push a pattern to the given pattern group ID
    PushPattern(usize, String, Option<String>),
    /// Render the given text directly to the flow
    Render(String),
    /// Add a log line to the flow
    Log(String),
    /// A FlowID will always be present when the group type is a flow group
    Group(String, Option<SupportedTester>, GroupType, Option<FlowID>),
    /// All children will be gated by the given condition (if_failed, if_enabled, etc.)
    Condition(FlowCondition),
    /// Execute a test (or invocation) from the flow with a CZ setup reference
    Cz(usize, String, FlowID),
    /// Bin (number, is_soft, type, description, priority)
    DefBin(usize, bool, BinType, Option<String>, Option<usize>),
    /// Bin out (hard, soft, type)
    Bin(usize, Option<usize>, BinType),
    /// Events to run if the test or group with the given ID failed
    OnFailed(FlowID),
    /// Events to run if the test or group with the given ID passed
    OnPassed(FlowID),
    /// Any tests contained within a Resources block will not be added to the flow, but will be added
    /// to 'resource' sheets/files, e.g. the test instances sheet
    Resources,
    /// Volatile flag definition (a flag that can be changed state by tests)
    Volatile(String),
    /// Set the flag to the given state (name, state, autogenerated). Autogenerated should be set to differentiate
    /// a flag operation that has been generated by Origen (to implement flow control logic) vs. once that has
    /// been directly specified by the user
    SetFlag(String, bool, bool),
    SetDefaultFlagState(String, bool),
    /// Continue in the event of a failure
    Continue,
    /// Delay binning in the event of a failure
    Delayed,
    Else,
    Whenever,    // Placeholder
    WheneverAny, // Placeholder
    WheneverAll, // Placeholder
    /// Enable a flow switch
    Enable(String),
    /// Disable a flow switch
    Disable(String),
    ResourcesFilename(String, ResourcesType),
    BypassSubFlows,
    FlowDescription(String),
    FlowNameOverride(String),
    Namespace(String),
    /// Apply the given uniqueness option to all contained test names, etc.
    Uniqueness(UniquenessOption),

    IGXLSetWaitFlags(usize, Vec<String>),

    FlowData(FlowData),

    /// A typed data variable declaration: (name, type_name, initial_value).
    /// Used for declaring local or global variables in any tester format that supports them
    /// (e.g. V93K SMT8 variable sheets), not to be confused with the flow-control flag
    /// variables tracked in the Model.
    Variable(String, String, Option<String>),

    /// A step or node whose type is not specifically recognized by the current processor.
    /// Carries the original type name and raw identifying data so it can be passed through
    /// losslessly and reconstructed by an importer. (step_type_name, raw_data)
    Unknown(String, String),

    /// A source-level documentation comment. Does not execute at runtime.
    /// Distinct from Log (which is a runtime output statement). Used to annotate
    /// the generated flow source in formats that support inline comments/descriptions.
    Comment(String),

    /// A timed delay/wait step. Duration is a format-agnostic string
    /// (e.g. "1s", "500ms", "1.5e-3"). Processors targeting testers with
    /// timing support should emit the appropriate wait primitive; others should
    /// pass it through unchanged.
    Wait(String),

    /// Variable assignment: (variable_name, value_expression).
    /// Complements Variable (declaration) — assigns a new value to an existing
    /// variable. The value_expression may be a literal or a tester-specific
    /// expression string.
    SetVariable(String, String),

    /// Flow input/output parameter declaration: (name, type_name, default_value).
    /// Distinct from Variable (local variable). Represents a named, typed parameter
    /// of a SubFlow — analogous to a function argument. Used in formats with named
    /// parameter declarations such as SMT7.
    Parameter(String, String, Option<String>),

    /// Multi-site synchronization barrier. Processors targeting testers that support
    /// multi-site execution should emit the appropriate sync primitive (e.g. V93K
    /// synchronization). Processors that don't understand this node should pass it
    /// through unchanged.
    Synchronize,

    /// A labeled jump target. Formats that support labeled flow control use this to mark
    /// a named jump destination. Complemented by Goto.
    Label(String),

    /// Jump to a labeled target. Formats that support labeled flow control use this to
    /// redirect execution to the named label. Complemented by Label.
    Goto(String),

    /// Events to run if the test or group with the given ID produced a runtime error
    /// or abort (not a test failure). Completes the result-handler triad alongside
    /// OnPassed and OnFailed. Processors that don't handle this should pass it through.
    OnError(FlowID),

    /// An external procedure/subroutine call with positional arguments: (procedure_name, args).
    /// Distinct from SubFlow (which is flow-graph-aware and tracked by the Model).
    /// Used for calling external procedures, library routines, or user-defined subroutines
    /// that are not part of the flow graph. Processors that don't handle this should pass
    /// it through unchanged.
    Call(String, Vec<String>),

    /// A bounded iteration loop: (iteration_count, counter_variable_name).
    /// `iteration_count` is None for condition-driven or infinite loops.
    /// `counter_variable_name` is None if the loop counter is not exposed as a variable.
    /// Child nodes form the loop body. Fills the gap left by the payload-less Whenever* placeholders
    /// for formats with explicit loop constructs (e.g. SMT7 loops).
    Loop(Option<u32>, Option<String>),

    /// A structured result report entry: (category, message).
    /// Distinct from Log (runtime stdout) and Comment (source annotation).
    /// Produces structured output that becomes part of the test result record.
    /// Used by formats like SMT8 result annotation steps.
    Report(String, String),

    /// A runtime assertion: (expression, failure_message).
    /// If the expression evaluates to false at runtime, execution halts with an error
    /// (not a test failure). Distinct from Test (which measures a DUT) and Condition
    /// (which branches). Used for program-correctness checks and defensive assertions.
    Assertion(String, String),

    /// A named hook or callback invocation with positional arguments: (callback_name, args).
    /// Used for formats where callbacks are first-class flow steps. Processors that don't
    /// handle this should pass it through unchanged.
    Callback(String, Vec<String>),
}

impl std::fmt::Display for PGM {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match &self {
            _ => write!(f, "{}", format!("{:?}", self)),
        }
    }
}