/// <summary> /// Runs the named macro. /// </summary> public void RunMacro(string s) { try { string sFile = GetMacroFile(); VM vm = new VM(); vm.InitializeVM(); vm.RegisterDotNetType(typeof(HeronEditor)); vm.RegisterDotNetType(typeof(CodeEditControl)); vm.RegisterDotNetType(typeof(Preferences)); //vm.RegisterAssembly(Assembly.GetExecutingAssembly()); vm.RegisterCommonWinFormTypes(); ModuleDefn m = vm.LoadModule(sFile); vm.LoadDependentModules(sFile); vm.ResolveTypes (); ModuleInstance mi = m.Instantiate(vm, new HeronValue[] { }, null) as ModuleInstance; vm.RunMeta(mi); HeronValue f = mi.GetFieldOrMethod("RunMacro"); if (f == null) { throw new Exception("Could not find a 'Main' method to run"); } f.Apply(vm, new HeronValue[] { DotNetObject.Marshal(this), DotNetObject.Marshal(s) }); } catch (Exception e) { MessageBox.Show("Error during macro: " + e.Message); } }
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() < 2) return sv; HeronValue[] output = new HeronValue[ii.InternalCount()]; ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = Config.maxThreads; var p = Partitioner.Create(1, ii.InternalCount()); HeronValue result = ii.InternalAt(0); object resultLock = new Object(); Parallel.ForEach( p, po, () => { LoopParams lp = new LoopParams(); lp.op = new OptimizationParams(); lp.acc = lp.op.AddNewAccessor(a); lp.acc2 = lp.op.AddNewAccessor(b); lp.vm = vm.Fork(); lp.expr = yield.Optimize(lp.op); return lp; }, (Tuple<int, int> range, ParallelLoopState state, LoopParams lp) => { if (range.Item1 == range.Item2) return lp; lp.acc.Set(ii.InternalAt(range.Item1)); for (int i = range.Item1 + 1; i < range.Item2; ++i) { lp.acc2.Set(ii.InternalAt(i)); lp.acc.Set(lp.vm.Eval(lp.expr)); } // Update the result lock (resultLock) { lp.acc2.Set(result); result = lp.vm.Eval(lp.expr); } return lp; }, (LoopParams lp) => { } ); return new ArrayValue(new HeronValue[] { result }, sv.GetElementType()); }
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); }
/// <summary> /// Sets the value on the named field. Does not automatically add a field if missing. /// </summary> /// <param name="name"></param> /// <param name="val"></param> public override void SetField(string name, HeronValue val) { if (fields.HasName(name)) fields[name] = val; else if (GetBase() != null) GetBase().SetField(name, val); else throw new Exception("Field '" + name + "' does not exist"); }
private void PushArgs(VM vm, HeronValue[] args) { int n = fun.formals.Count; Debug.Assert(n == args.Length); for (int i = 0; i < n; ++i) { vm.AddVar(fun.formals[i], args[i]); } }
/// <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 AnyValue(HeronValue obj) { AnyValue av = (obj as AnyValue); if (av != null) { this.obj = av.obj; this.type = av.type; } else { this.obj = obj; this.type = obj.Type; } }
/// <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; }
public bool HasKey(HeronValue index) { CheckIndexType(index); return values.ContainsKey(index.GetHashCode()); }
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 override HeronValue GetAtIndex(HeronValue index) { CheckIndexType(index); return values[index.GetHashCode()]; }
public void Add(HeronValue record) { CheckRecordCompatibility(record); if (record is RecordValue) { RecordValue rec = record as RecordValue; int n = GetIndexValue(rec).GetHashCode(); values.Add(n, rec); } else { ListValue list = record as ListValue; if (list == null) throw new Exception("Can only add lists or records to a table"); RecordValue rec = new RecordValue(layout, list.InternalList()); int n = GetIndexValue(rec).GetHashCode(); values.Add(n, rec); } }
public override void SetAtIndex(HeronValue index, HeronValue val) { if (index is StringValue) { SetValue((index as StringValue).GetValue(), val); } else if (index is IntValue) { SetValue((index as IntValue).GetValue(), val); } else { throw new Exception("Can only index records using strings or integers"); } }
public void SetValue(string s, HeronValue val) { int n = GetFieldIndex(s); if (n < 0) throw new Exception("record does not have field: " + s); values[n] = val; }
public override HeronValue Instantiate(VM vm, HeronValue[] args, ModuleInstance m) { if (m != null) throw new Exception("A module cannot belong to a module"); ModuleInstance r = new ModuleInstance(this); AddFields(r, m); foreach (Import i in imports) { ModuleDefn importModDef = vm.LookupModuleDefn(i.module); HeronValue[] importArgs = vm.EvalList(i.args).ToArray(); ModuleInstance importInstance = importModDef.Instantiate(vm, args, null) as ModuleInstance; if (importInstance == null) throw new Exception("Failed to create loaded module instance"); r.imports.Add(i.alias, importInstance); } CallConstructor(vm, args, m, r); return r; }
/// <summary> /// Convenience function for invoking methods without arguments /// </summary> /// <param name="self"></param> /// <param name="s"></param> /// <returns></returns> public HeronValue Invoke(HeronValue self, string s) { return Invoke(self, s, new HeronValue[] { }); }
public void InitializeVM() { globalModule = new ModuleDefn(null, "_global_", "_internal_"); RegisterPrimitives(); program = new ProgramDefn("_program_", globalModule); // Clear all the frames frames.Clear(); result = null; // Push an empty first frame and scope PushNewFrame(null, null, null); PushScope(); }
public void SetValue(int n, HeronValue val) { values[n] = val; }
/// <summary> /// Called by a return statement. Sets the function result, and sets a flag to indicate /// to executing statement groups that execution should terminate. /// </summary> /// <param name="ret"></param> public void Return(HeronValue ret) { Debug.Assert(!bReturning, "internal error, returning flag was not reset"); bReturning = true; result = ret; }
public override HeronValue GetAtIndex(HeronValue index) { if (index is StringValue) { return GetValue((index as StringValue).GetValue()); } else if (index is IntValue) { return GetValue((index as IntValue).GetValue()); } else { throw new Exception("Can only index records using strings or integers"); } }
/// <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 void SetField(string name, HeronValue val) { if (HasKey(name)) SetValue(name, val); else SetValue(name, val); }
public void SetVar(string s, HeronValue o) { Debug.Assert(o != null); frames.Peek().SetVar(s, o); }
public void Remove(HeronValue index) { CheckIndexType(index); int n = index.GetHashCode(); values.Remove(n); }
/// <summary> /// Assigns a value to the "nth" variable. /// </summary> /// <param name="n"></param> /// <param name="o"></param> public void SetVar(int n, HeronValue o) { Debug.Assert(o != null); frames.Peek().SetVar(n, o); }
public override void SetAtIndex(HeronValue index, HeronValue val) { CheckRecordCompatibility(val); CheckIndexType(index); values[index.GetHashCode()] = val as RecordValue; }
/// <summary> /// Assigns a value to a field. /// </summary> /// <param name="name"></param> /// <param name="val"></param> public new void SetField(string s, HeronValue o) { Debug.Assert(o != null); frames.Peek().SetField(s, o); }
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()); }
/// <summary> /// Creates a new variable name in the current scope. /// </summary> /// <param name="s"></param> /// <param name="o"></param> public void AddVar(VarDesc v, HeronValue x) { frames.Peek().AddVar(v, x); }
public HeronValue GetColumn(HeronValue column) { int nCol = -1; if (column is StringValue) nCol = layout.GetFieldIndex((column as StringValue).GetValue()); else if (column is IntValue) nCol = (column as IntValue).ToInt(); else throw new Exception("Can only retrieve columns by name (String) or index (Int)"); return new ListValue(GetValues(nCol), layout.GetTypes()[nCol]); }
/// <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; }