private void CheckRecordCompatibility(HeronValue record) { if (!(record is RecordValue)) { if (!(record is ListValue)) { throw new Exception(record.ToString() + " is not a valid list or record type"); } ListValue list = record as ListValue; if (layout.IsCompatible(list)) { return; } throw new Exception("The list value is not compatible"); } else { RecordValue rec = record as RecordValue; if (rec.GetLayout() == layout) { return; } // Check then that there are the same exposedFields in "record" that we require. if (layout.IsCompatible(rec)) { return; } throw new Exception("The record layout " + layout.ToString() + " does not contain a super-set of the accepted fields"); } }
public bool SupportsFunction(FunctionDefn f) { HeronValue v = GetFieldOrMethod(f.name); if (v == null) { return(false); } if (v is DotNetMethodValue) { var emv = v as DotNetMethodValue; return(f.Matches(emv.GetMethodInfo())); } else if (v is FunDefnListValue) { var fdlv = v as FunDefnListValue; foreach (FunctionDefn fd in fdlv.GetDefns()) { if (fd.Matches(f)) { return(true); } } } // Unrecognized value type. return(false); }
public void Remove(HeronValue index) { CheckIndexType(index); int n = index.GetHashCode(); values.Remove(n); }
/// <summary> /// Sets the value associated with the named field /// </summary> /// <param name="name"></param> /// <param name="val"></param> public virtual void SetField(string name, HeronValue val) { HeronType t = Type; FieldDefn fi = t.GetField(name); fi.SetValue(this, val); }
/// <summary> /// Converts a HeronValue into the expected type. Checks for legal null /// passing (i.e. assures only nullable types receive nulls), and does type-checking. /// </summary> /// <param name="x"></param> /// <returns></returns> public HeronValue Coerce(HeronValue x) { HeronValue r = x; if (r is NullValue) { if (!type.nullable) { throw new Exception("Passing null to a non-nullable variable " + name); } else { return(r); } } else if (type != null) { r = x.As(type.type); if (r == null) { throw new Exception("Failed to convert variable " + x + " from a " + x.Type.name + " to " + type.name); } } return(r); }
/// <summary> /// A function can be invoked if the 'this' value (called self) is supplied. /// A FunctionObject is created and then called. /// </summary> /// <param name="self"></param> /// <param name="env"></param> /// <param name="funcs"></param> /// <returns></returns> public HeronValue Invoke(HeronValue self, VM vm, HeronValue[] args) { // TODO: in theory we can optimize this FunctionValue fo = new FunctionValue(self, this); return(fo.Apply(vm, args)); }
private void CheckIndexType(HeronValue index) { if (index.As(layout.GetIndexType()) == null) { throw new Exception(index.ToString() + " is not a valid index type, expected " + layout.GetIndexType().ToString()); } }
public override HeronValue InvokeBinaryOperator(VM vm, OpCode opcode, HeronValue val) { float x = GetValue(); float y = val.ToFloat(); switch (opcode) { case OpCode.opAdd: return(vm.MakeTemporary(x + y)); case OpCode.opSub: return(vm.MakeTemporary(x - y)); case OpCode.opMul: return(vm.MakeTemporary(x * y)); case OpCode.opDiv: return(vm.MakeTemporary(x / y)); case OpCode.opMod: return(vm.MakeTemporary(x % y)); case OpCode.opGtEq: return(vm.MakeTemporary(x >= y)); case OpCode.opLtEq: return(vm.MakeTemporary(x <= y)); case OpCode.opGt: return(vm.MakeTemporary(x > y)); case OpCode.opLt: return(vm.MakeTemporary(x < y)); default: return(base.InvokeBinaryOperator(vm, opcode, val)); } }
public override HeronValue Eval(VM vm) { HeronValue result = vm.Eval(expr); vm.Eval(ass); return(result); }
public override bool Equals(Object x) { if (!(x is SeqValue)) { return(false); } IteratorValue e1 = GetIterator(); IteratorValue e2 = (x as SeqValue).GetIterator(); bool b1 = e1.MoveNext(); bool b2 = e2.MoveNext(); // While both lists have data. while (b1 && b2) { HeronValue v1 = e1.GetValue(); HeronValue v2 = e2.GetValue(); if (!v1.Equals(v2)) { return(false); } b1 = e1.MoveNext(); b2 = e2.MoveNext(); } // If one of b1 or b2 is true, then we didn't get to the end of list // so we have different sized lists. if (b1 || b2) { return(false); } return(true); }
/// <summary> /// Convenience function for invoking a method on an object /// </summary> /// <param name="self"></param> /// <param name="s"></param> /// <param name="funcs"></param> /// <returns></returns> public HeronValue Invoke(HeronValue self, string s, HeronValue[] args) { HeronValue f = self.GetFieldOrMethod(s); HeronValue r = f.Apply(this, new HeronValue[] { }); return(r); }
public override HeronValue Invoke(VM vm, HeronValue self, HeronValue[] args) { int nParams = method.GetParameters().Length; if (nParams != args.Length) { throw new Exception("Incorrect number of arguments " + args.Length + " expected " + nParams); } Object[] newArgs = new Object[args.Length]; for (int i = 0; i < nParams; ++i) { ParameterInfo pi = method.GetParameters()[i]; Type pt = pi.ParameterType; Type at = args[i].GetType(); HeronValue hv = args[i] as HeronValue; if (!pt.IsAssignableFrom(at)) { if (hv == null) { throw new Exception("Could not cast parameter " + i + " from " + at + " to " + pt); } newArgs[i] = hv.Unmarshal(); } else { newArgs[i] = hv; } } return(DotNetObject.Marshal(method.Invoke(self, newArgs))); }
private void GetFreeVars(VM vm, Statement st, Stack <string> boundVars, Scope result) { // InternalCount and store the names defined by this statement int nNewVars = 0; foreach (string name in st.GetDefinedNames()) { ++nNewVars; boundVars.Push(name); } // Iterate over all names used by expressions in the statement foreach (string name in st.GetUsedNames()) { // Is this not a boundVar, and not already marked as a free var if (!boundVars.Contains(name) && !result.HasName(name)) { // Throws an exception if the name is not found HeronValue v = vm.LookupName(name); result.Add(new VarDesc(name), v); } } // Recurse over all sub statements, getting the free vars foreach (Statement child in st.GetSubStatements()) { GetFreeVars(vm, child, boundVars, result); } // Pop all variables added by this variable for (int i = 0; i < nNewVars; ++i) { boundVars.Pop(); } }
public override HeronValue Eval(VM vm) { HeronValue o = self.Eval(vm); HeronValue i = index.Eval(vm); return(o.GetAtIndex(i)); }
public override void Eval(VM vm) { HeronValue initVal = initial.Eval(vm); VarDesc desc = new VarDesc(name); using (vm.CreateScope()) { vm.AddVar(desc, initVal); while (true) { HeronValue condVal = vm.Eval(condition); bool b = condVal.ToBool(); if (!b) { return; } vm.Eval(body); if (vm.ShouldExitScope()) { return; } vm.Eval(next); } } }
public override Expression Optimize(OptimizationParams op) { Expression opt_rvalue = rvalue.Optimize(op); if (lvalue is Name) { Name nm = lvalue as Name; Accessor acc = op.GetAccessor(nm.name); if (acc == null) { return(this); } else { return(new OptimizedExpression((VM vm) => { HeronValue x = opt_rvalue.Eval(vm); acc.Set(x); return x; })); } } else { return(new Assignment(lvalue.Optimize(op), opt_rvalue)); } }
public override HeronValue Eval(VM vm) { HeronValue[] argvals = args.Eval(vm); HeronValue f = funexpr.Eval(vm); return(f.Apply(vm, argvals)); }
/// <summary> /// Converts from a HeronValue to a specific System.Net type /// </summary> /// <param name="t"></param> /// <param name="v"></param> /// <returns></returns> public static Object Unmarshal(Type t, HeronValue v) { Object o = v.Unmarshal(); Debug.Assert(o.GetType().Equals(t)); return(o); }
/// <summary> /// Returns local fields or methods declared, inherited, or /// even those imported. Consumers of a module should only /// ever call "GetExportedFieldOrMethod" /// </summary> /// <param name="name"></param> /// <returns></returns> public override HeronValue GetFieldOrMethod(string name) { if (imports.ContainsKey(name)) { return(imports[name]); } HeronValue r = base.GetFieldOrMethod(name); if (r != null) { return(r); } List <HeronValue> candidates = new List <HeronValue>(); foreach (ModuleInstance m in imports.Values) { HeronValue tmp = m.GetExportedFieldOrMethod(name); if (tmp != null) { candidates.Add(tmp); } } if (candidates.Count > 1) { throw new Exception("Found mulitple module instances containing definition of " + name); } if (candidates.Count == 1) { return(candidates[0]); } return(null); }
public override HeronValue InvokeBinaryOperator(VM vm, OpCode opcode, HeronValue val) { int x = GetValue(); int y = val.ToInt(); switch (opcode) { case OpCode.opAdd: return(vm.MakeTemporary(x + y)); case OpCode.opSub: return(vm.MakeTemporary(x - y)); case OpCode.opMul: return(vm.MakeTemporary(x * y)); case OpCode.opDiv: return(vm.MakeTemporary(x / y)); case OpCode.opMod: return(vm.MakeTemporary(x % y)); case OpCode.opShr: return(vm.MakeTemporary(x >> y)); case OpCode.opShl: return(vm.MakeTemporary(x << y)); case OpCode.opGtEq: return(vm.MakeTemporary(x >= y)); case OpCode.opLtEq: return(vm.MakeTemporary(x <= y)); case OpCode.opGt: return(vm.MakeTemporary(x > y)); case OpCode.opLt: return(vm.MakeTemporary(x < y)); case OpCode.opRange: return(new RangeEnumerator(this as IntValue, val as IntValue)); default: return(base.InvokeBinaryOperator(vm, opcode, val)); } }
public HeronValue LookupName(string s) { HeronValue r = CurrentFrame.LookupName(s); if (r != null) { return(r); } if (CurrentModuleDef != null) { foreach (HeronType t in CurrentModuleDef.GetTypes()) { if (t.name == s) { return(new TypeValue(t)); } } } if (GlobalModule != null) { foreach (HeronType t in GlobalModule.GetTypes()) { if (t.name == s) { return(new TypeValue(t)); } } } throw new Exception("Could not find '" + s + "' in the environment"); }
public Accessor AddNewAccessor(string name, HeronValue val) { Accessor acc = new Accessor(val); accessors.Add(name, acc); return(acc); }
/// <summary> /// Evaluates the map operation /// </summary> /// <param name="vm">Current state of virtual machine</param> /// <returns>An ArrayValue containing new values</returns> public override HeronValue Eval(VM vm) { SeqValue sv = vm.Eval(list) as SeqValue; if (sv == null) { throw new Exception("Expected list: " + list.ToString()); } // internal structure for indexing lists IInternalIndexable ii = sv.GetIndexable(); if (ii.InternalCount() == 0) { return(sv); } // Array of values used for output of map operations HeronValue[] output = new HeronValue[ii.InternalCount()]; // Create a parallel options object to limit parallelism ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = Config.maxThreads; // Create a partitioner var partitioner = Partitioner.Create(0, ii.InternalCount()); Parallel.ForEach( // Breaks the for loop up into sub-ranges partitioner, // Parellel options po, // Initialization of thread-local variables () => { LoopParams lp = new LoopParams(); lp.op = new OptimizationParams(); lp.acc = lp.op.AddNewAccessor(name); lp.vm = vm.Fork(); lp.expr = yield.Optimize(lp.op); return(lp); }, // Loop body (Tuple <int, int> range, ParallelLoopState state, LoopParams lp) => { for (int i = range.Item1; i < range.Item2; ++i) { lp.acc.Set(ii.InternalAt(i)); output[i] = lp.vm.Eval(lp.expr); } return(lp); }, // Finalization function (LoopParams lp) => { } ); return(new ArrayValue(output, sv.GetElementType())); }
public override HeronValue Invoke(VM vm, HeronValue self, HeronValue[] args) { Trace.Assert(self == null); Object[] os = HeronDotNet.ObjectsToDotNetArray(args); Object o = this.self.GetSystemType().InvokeMember(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, os); return(DotNetObject.Marshal(o)); }
/// <summary> /// Returns the return result, and sets it to null. /// </summary> /// <returns></returns> public HeronValue GetAndResetResult() { HeronValue r = result; result = null; bReturning = false; return(r); }
public override HeronValue[] ToArray() { HeronValue[] r = new HeronValue[list.Count]; for (int i = 0; i < list.Count; ++i) { r[i] = DotNetObject.Marshal(list[i]); } return(r); }
public void Add(VarDesc v, HeronValue x) { x = v.Coerce(x); int n = Count; vars.Add(v); values.Add(x); lookup.Add(v.name, n); }
public override HeronValue[] ToArray() { HeronValue[] a = new HeronValue[InternalCount()]; for (int i = 0; i < cnt; ++i) { a[i + from] = list.InternalAt(i); } return(a); }
public override HeronValue GetAtIndex(HeronValue index) { IntValue iv = index as IntValue; if (iv == null) { throw new Exception("Can only use index lists using integers"); } return(DotNetObject.Marshal(list[iv.GetValue()])); }
public override void SetAtIndex(HeronValue index, HeronValue val) { IntValue iv = index as IntValue; if (iv == null) { throw new Exception("Can only use index lists using integers"); } list[iv.GetValue()] = val.Unmarshal(); }