Пример #1
0
        // Return value of attribute with tuple indexing
        public TypedValue ValueNth(CodeValue attribute, NumberValue index, PointerValue lookup)
        {
            var row = lookup.Value as DataRow;

            Logger.Assert(row != null, "lookup is not row");
            return(row.ValueOffset(attribute.AsEval, (int)index.Value, OffsetModes.Absolute));
        }
Пример #2
0
        // Return ordinal as scalar
        public NumberValue OrdinalGroup(PointerValue lookup)
        {
            var row = lookup.Value as DataRow;

            Logger.Assert(row != null, "lookup is not row");
            return(row.Ordinal(true));
        }
Пример #3
0
        // Invoke a defined function with required argument in scope
        // If folded, applies an offset to get the right accumulator
        public TypedValue Invoke(CodeValue funcarg, PointerValue accblkarg, NumberValue accbasarg, TypedValue[] valargs)
        {
            Logger.WriteLine(3, "Invoke {0} accbase={1} ({2})", funcarg, accbasarg, String.Join(",", valargs.Select(a => a.ToString()).ToArray()));

            // wrap raw value with evaluator
            var expr = funcarg.Value as ExpressionEval;

            Logger.Assert(expr != null, "invoke eval");
            var        args = DataRow.CreateNonTuple(expr.Lookup, valargs);
            TypedValue ret;

            if (expr.HasFold)
            {
                var accblk  = accblkarg.Value as AccumulatorBlock;
                var accbase = (int)accbasarg.Value;
                ret = expr.EvalHasFold(args, accblk, accbase);
            }
            else
            {
                ret = expr.EvalOpen(args);
            }

            // If the return value is an unresolved sql table then resolve it now
            // before exiting the lookup scope (which it may need)
            if (ret is RelationValue && !(ret.AsTable() is DataTableLocal))
            {
                ret = RelationValue.Create(DataTableLocal.Convert(ret.AsTable(), args, expr.Evaluator));
            }
            Logger.WriteLine(3, "[Inv {0}]", ret);
            return(ret);
        }
Пример #4
0
        // Return rank of attribute with tuple indexing
        public TypedValue Rank(CodeValue attribute, NumberValue index, PointerValue lookup)
        {
            var row = lookup.Value as DataRow;

            Logger.Assert(row != null, "lookup is not row");
            var value  = attribute.AsEval.EvalOpen(row);
            var offset = row.Heading.FindIndex(attribute.AsEval.Name);

            return(NumberValue.Create(index.Value + 1));
        }
Пример #5
0
        // Fold an operation and one argument over a set of tuples
        public TypedValue Fold(PointerValue accblkarg, NumberValue accidarg, TypedValue defarg, CodeValue expr)
        {
            Logger.WriteLine(3, "Fold n={0} def={1} expr={2}", accidarg, defarg, expr);
            var accblock = accblkarg.Value as AccumulatorBlock;
            var accid    = (int)accidarg.Value;
            var accum    = accblock[accid] ?? defarg;

            accblock[accid] = expr.AsEval.EvalIsFolded(null, accblock[accid]);
            Logger.WriteLine(3, "[Fold {0}]", accblock[accid]);
            return(accblock[accid]);
        }
Пример #6
0
        // Invoke a do block with its own scope level
        public TypedValue DoBlock(CodeValue exprarg, PointerValue accblkarg)
        {
            Logger.WriteLine(3, "DoBlock {0}", exprarg);
            _catvars = _catvars.PushScope();
            var accblk = accblkarg.Value as AccumulatorBlock;
            var expr   = exprarg.Value as ExpressionEval;
            var ret    = expr.Evaluator.Exec(exprarg.Value.Code, null, null, accblk);

            // If the return value is an unresolved sql table then resolve it now
            // before exiting the local variable scope (which it may need)
            if (ret is RelationValue && !(ret.AsTable() is DataTableLocal))
            {
                ret = RelationValue.Create(DataTableLocal.Convert(ret.AsTable()));
            }
            _catvars = _catvars.PopScope();
            Logger.WriteLine(3, "[Do {0}]", ret);
            return(ret);
        }
Пример #7
0
 public TypedValue Fold2(TypedValue defarg, CodeValue expr, PointerValue accblkarg, NumberValue accidarg)
 {
     return(null);
 }
Пример #8
0
 static PointerValue()
 {
     Default = new PointerValue {
         Value = new byte[0]
     };
 }
Пример #9
0
        // Evaluation engine for ByteCode
        TypedValue Run(ByteCode bcode, TypedValue aggregate, AccumulatorBlock accblock)
        {
            TypedValue retval = null;
            var        reader = PersistReader.Create(bcode.bytes);

            while (reader.More)
            {
                var opcode = reader.ReadOpcode();
                switch (opcode)
                {
                // Known literal, do not translate into value
                case Opcodes.LDVALUE:
                    PushStack(reader.ReadValue());
                    break;
                // Known catalog variable, look up value
                //case Opcodes.LDCAT:
                //  var catnam = reader.ReadString();
                //  var catval = CatVars.GetValue(catnam);
                //  Logger.Assert(catval != null, $"{opcode}:{catnam}");
                //  if (catval.DataType is DataTypeCode)
                //    catval = this.Exec((catval as CodeValue).Value.Code);
                //  _stack.Push(catval);
                //  break;

                // Catalog variable, look up value (could be code)
                case Opcodes.LDCAT:
                    var catnam = reader.ReadString();
                    var catval = CatVars.GetValue(catnam);
                    Logger.Assert(catval != null, $"{opcode}:{catnam}");
                    _stack.Push(catval);
                    break;

                // Catalog variable, must be code, evaluate
                case Opcodes.LDCATV:
                    var ctvnam = reader.ReadString();
                    var ctvval = CatVars.GetValue(ctvnam) as CodeValue;
                    Logger.Assert(ctvval != null, $"{opcode}:{ctvnam}");
                    _stack.Push(this.Exec((ctvval as CodeValue).Value.Code));
                    break;

                // Catalog variable, must be code, as code value
                case Opcodes.LDCATR:
                    var ctrnam = reader.ReadString();
                    var ctrval = CatVars.GetValue(ctrnam) as CodeValue;
                    Logger.Assert(ctrval != null, $"{opcode}:{ctrnam}");
                    PushStack(CodeValue.Create(ExpressionEval.Create(this, ctrval.Value)));
                    break;

                // Load value obtained using lookup by name
                case Opcodes.LDFIELD:
                    var fldval = TypedValue.Empty;
                    var fldnam = reader.ReadString();
                    var fldok  = LookupValue(fldnam, ref fldval);
                    Logger.Assert(fldok, $"{opcode}:{fldnam}");
                    PushStack(fldval);
                    break;

                // Load aggregate value or use specified start value if not available
                case Opcodes.LDAGG:
                    var aggval = reader.ReadValue();
                    PushStack(aggregate ?? aggval);
                    break;

                // load accumulator by index, or fixed value if not available
                case Opcodes.LDACC:
                    var accnum = reader.ReadInteger();
                    var accval = reader.ReadValue();
                    PushStack(accblock == null ? accval : accblock[accnum]);
                    break;

                // Load a segment of code for later call, with this evaluator packaged in
                case Opcodes.LDSEG:
                    var segexp = reader.ReadExpr();
                    var segval = CodeValue.Create(ExpressionEval.Create(this, segexp));
                    PushStack(segval);
                    break;

                case Opcodes.LDLOOKUP:
                    var lkpobj = PointerValue.Create(_lookups.Peek() as object);
                    PushStack(lkpobj);
                    break;

                case Opcodes.LDACCBLK:
                    var acbobj = PointerValue.Create(accblock as object);
                    PushStack(acbobj);
                    break;

                case Opcodes.LDCOMP:
                    var cmpudt = _stack.Pop() as UserValue;
                    var cmpval = cmpudt.GetComponentValue(reader.ReadString());
                    PushStack(cmpval);
                    break;

                case Opcodes.LDFIELDT:
                    var fdttup = _stack.Pop() as TupleValue;
                    var fdtval = fdttup.GetFieldValue(reader.ReadString());
                    PushStack(fdtval);
                    break;

                // Call a function, fixed or variable arg count
                case Opcodes.CALL:
                case Opcodes.CALLV:
                case Opcodes.CALLVT:
                    var calname   = reader.ReadString();
                    var calmeth   = typeof(Builtin).GetMethod(calname);
                    var calnargs  = reader.ReadByte();
                    var calnvargs = reader.ReadByte();
                    var calargs   = new object[calnargs];
                    var calargx   = calargs.Length - 1;
                    if (opcode == Opcodes.CALLV)
                    {
                        var vargs = new CodeValue[calnvargs];
                        for (var j = vargs.Length - 1; j >= 0; --j)
                        {
                            vargs[j] = _stack.Pop() as CodeValue;
                        }
                        calargs[calargx--] = vargs;
                    }
                    else if (opcode == Opcodes.CALLVT)
                    {
                        var vargs = new TypedValue[calnvargs];
                        for (var j = vargs.Length - 1; j >= 0; --j)
                        {
                            vargs[j] = _stack.Pop() as TypedValue;
                        }
                        calargs[calargx--] = vargs;
                    }
                    for (; calargx >= 0; --calargx)
                    {
                        calargs[calargx] = _stack.Pop();
                    }
                    var ret = calmeth.Invoke(_builtin, calargs) as TypedValue;
                    _stack.Push(ret);
                    //if (ret.DataType != DataTypes.Void)
                    //  _stack.Push(ret);
                    break;

                case Opcodes.EOS:
                    retval = _stack.Pop();
                    //retval = (_stack.Count > 0) ? _stack.Pop() : VoidValue.Void;
                    break;

                default:
                    throw new NotImplementedException(opcode.ToString());
                }
            }
            if (retval == null)
            {
                retval = _stack.Pop();
            }
            //Logger.Assert(retval != null, "stack");
            return(retval);
        }