예제 #1
0
        private static IEnumerable <DValue <RecordValue> > LazyAddColumns(EvalVisitor runner, SymbolContext context, IEnumerable <DValue <RecordValue> > sources, IRContext recordIRContext, NamedLambda[] newColumns)
        {
            foreach (var row in sources)
            {
                if (row.IsValue)
                {
                    // $$$ this is super inefficient... maybe a custom derived RecordValue?
                    var fields = new List <NamedValue>(row.Value.Fields);

                    var childContext = context.WithScopeValues(row.Value);

                    foreach (var column in newColumns)
                    {
                        var value = column.Lambda.Eval(runner, childContext);
                        fields.Add(new NamedValue(column.Name, value));
                    }

                    yield return(DValue <RecordValue> .Of(new InMemoryRecordValue(recordIRContext, fields.ToArray())));
                }
                else
                {
                    yield return(row);
                }
            }
        }
예제 #2
0
 // Helper to eval an arg that might be a lambda.
 internal DValue <T> EvalArg <T>(FormulaValue arg, SymbolContext context, IRContext irContext) where T : ValidFormulaValue
 {
     if (arg is LambdaFormulaValue lambda)
     {
         var val = lambda.Eval(this, context);
         return(val switch
         {
             T t => DValue <T> .Of(t),
             BlankValue b => DValue <T> .Of(b),
             ErrorValue e => DValue <T> .Of(e),
             _ => DValue <T> .Of(CommonErrors.RuntimeTypeMismatch(irContext))
         });
예제 #3
0
        public static Func <EvalVisitor, SymbolContext, IRContext, TableValue[], FormulaValue> StandardSingleColumnTable <T>(Func <EvalVisitor, SymbolContext, IRContext, T[], FormulaValue> targetFunction) where T : FormulaValue
        {
            return((runner, symbolContext, irContext, args) =>
            {
                var tableType = (TableType)irContext.ResultType;
                var resultType = tableType.ToRecord();
                var itemType = resultType.GetFieldType(BuiltinFunction.OneColumnTableResultNameStr);

                var arg0 = args[0];
                var resultRows = new List <DValue <RecordValue> >();
                foreach (var row in arg0.Rows)
                {
                    if (row.IsValue)
                    {
                        var value = row.Value.GetField(BuiltinFunction.ColumnName_ValueStr);
                        NamedValue namedValue;
                        namedValue = value switch
                        {
                            T t => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, targetFunction(runner, symbolContext, IRContext.NotInSource(itemType), new T[] { t })),
                            BlankValue bv => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, bv),
                            ErrorValue ev => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, ev),
                            _ => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, CommonErrors.RuntimeTypeMismatch(IRContext.NotInSource(itemType)))
                        };
                        var record = new InMemoryRecordValue(IRContext.NotInSource(resultType), new List <NamedValue>()
                        {
                            namedValue
                        });
                        resultRows.Add(DValue <RecordValue> .Of(record));
                    }
                    else if (row.IsBlank)
                    {
                        resultRows.Add(DValue <RecordValue> .Of(row.Blank));
                    }
                    else
                    {
                        resultRows.Add(DValue <RecordValue> .Of(row.Error));
                    }
                }
                return new InMemoryTableValue(irContext, resultRows);
            });
        }