A small immutable record struct representing a handle to an IR expression plus its resolved shader type. It provides helpers for constructing valid/invalid values, queries for validity, component count, const-ness, and an implicit conversion to the underlying IrExpr.
using Editor.Prism.Core;
namespace Editor.Prism.Compiler.Ir;
/// <summary>
/// A handle to an IR expression and its resolved type. This is the currency nodes deal in:
/// <c>EmitContext</c> hands them <see cref="IrValue"/>s, they combine them, and they hand values back.
/// <para>
/// <see cref="Invalid"/> is the failure value. A node that could not produce a result returns it and
/// the compile continues — one broken node never aborts the whole graph.
/// </para>
/// </summary>
public readonly record struct IrValue( IrExpr Expr, ShaderType Type )
{
/// <summary>The failure value. Every operation on it produces another invalid value.</summary>
public static readonly IrValue Invalid = default;
/// <summary>Wrap an expression, taking its own type.</summary>
public static IrValue Of( IrExpr expr ) => expr is null ? Invalid : new IrValue( expr, expr.Type );
/// <summary>Wrap an expression with an explicit type.</summary>
public static IrValue Of( IrExpr expr, ShaderType type ) => expr is null ? Invalid : new IrValue( expr, type );
/// <summary>True when this value refers to a real expression.</summary>
public bool IsValid => Expr is not null;
/// <summary>Component count of the value's type.</summary>
public int Components => Type.Components;
/// <summary>True when the value is a compile-time literal.</summary>
public bool IsConstant => Expr is IrConst;
/// <summary>The literal behind this value, when it is one.</summary>
public bool TryGetConst( out ConstValue value )
{
if ( Expr is IrConst constant )
{
value = constant.Value;
return true;
}
value = default;
return false;
}
/// <summary>Implicitly unwrap to the underlying expression.</summary>
public static implicit operator IrExpr( IrValue value ) => value.Expr;
/// <inheritdoc/>
public override string ToString() => IsValid ? $"{Type.Hlsl}:{Expr.GetType().Name}" : "<invalid>";
}