// Serialise reading a value // must include type to know column order :BUG public static TypedValue FromBinary(byte[] buffer, DataType datatype) { using (var reader = PersistReader.Create(buffer)) { var value = reader.ReadValue(); Logger.Assert(value.DataType.Equals(datatype), value); return(value); } }
// Load from byte array public TypedValue Load(byte[] buffer) { Logger.WriteLine(4, "Loading data"); using (var reader = new BinaryReader(new MemoryStream(buffer))) { var r = PersistReader.Create(reader); return(r.Load()); } }
public PersistReader Reader(string name) { var path = Path.Combine(_basepath, name + "." + VariableExtension); if (!File.Exists(path)) { return(null); } var reader = new BinaryReader(File.Open(path, FileMode.Open)); return(PersistReader.Create(reader)); }
public static CatalogEntry FromBinary(byte[] buffer) { using (var reader = PersistReader.Create(buffer)) { var name = reader.ReadString(); var kind = (EntryKinds)reader.ReadByte(); var flags = (EntryFlags)reader.ReadByte(); var datatype = reader.ReadDataType(); TypedValue value = (kind == EntryKinds.Type) ? null : reader.ReadValue(); return(new CatalogEntry { Name = name, Kind = kind, Flags = flags, DataType = datatype, Value = value }); } }
// Peek file stream to get type public DataType Peek(string name) { var path = Path.Combine(_basepath, name + "." + VariableExtension); if (!File.Exists(path)) { return(null); } Logger.WriteLine(4, "Peeking {0}", name); using (var reader = new BinaryReader(File.Open(path, FileMode.Open))) { var r = PersistReader.Create(reader); return(r.Peek()); } }
// Load from file stream public TypedValue Load(string name) { Logger.WriteLine(4, "Load {0}", name); var path = Path.Combine(_basepath, name + "." + VariableExtension); if (!File.Exists(path)) { return(TypedValue.Empty); } using (var reader = new BinaryReader(File.Open(path, FileMode.Open))) { var r = PersistReader.Create(reader); var value = r.Load(); Logger.WriteLine(3, "[Load {0} {1}]", name, value); return(value); } }
// 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); }