public static IFunction Create(IFunction index, IFunction[] elements, CompilationContext info) { if (index.AsExpression(info) != null && elements.All(e => e.AsExpression(info) != null)) { return(new Mux(index.AsExpression(info), elements.Select(e => e.AsExpression(info)))); } if (elements.Any(e => e.IsLeaf())) { return(NumberType.Instance); } return(new Indexer(index, elements)); }
/// <summary> /// Calculates the serialized size of the given Function or Type /// </summary> /// <param name="value">The value or type in question</param> /// <param name="info">Where to log error messages</param> /// <returns>The size of the structure in singles, or null if there was a problem</returns> public static int?GetSize(this IFunction value, CompilationContext info) { if (value == Error.Instance) { return(null); } if (value is SerializableType) { return(0); } if (value.IsLeaf() || value.AsExpression(info) != null) { return(1); } if (value.Inputs?.Length != 0) { info.LogError($"Cannot serialize {value} because it has inputs"); return(null); } if (value.Outputs == null) { info.LogError($"Cannot serialize {value} because it is not introspectable"); return(null); } return(value.Outputs.Select(o => GetSize(value.Call(o.Name, info), info)) // NB: An ordinary 'Sum' will treat null as 0 .Aggregate((int?)0, (a, b) => (a == null || b == null) ? null : a + b)); }
/// <summary> /// See the other overload of Serialize, but this time it takes a Queue rather than making a new array. /// </summary> /// <param name="value"></param> /// <param name="dataOut">The queue to append new values to</param> /// <param name="context"></param> public static void Serialize(this IFunction value, Queue <Expression> dataOut, CompilationContext context) { var expr = value.AsExpression(context); if (expr != null) { dataOut.Enqueue(expr); return; } if (value.IsLeaf()) { dataOut.Enqueue(Constant.Zero); return; } if (value is SerializableType) { return; } if (value.Inputs?.Length != 0) { context.LogError($"Cannot serialize {value} because it has inputs"); return; } if (value.Outputs == null) { context.LogError($"{value} doesn't have known outputs"); return; } // TODO: Arrays here? foreach (var output in value.Outputs) { Serialize(value.Call(output.Name, context), dataOut, context); } }
public Expression AsExpression(CompilationContext info) => _returnValue.AsExpression(info);