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) { 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()); }
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> /// This is a second stage of construction needed for closures. /// It computes any free variables in the function, and binds them /// to values /// </summary> /// <param name="vm"></param> public void ComputeFreeVars(VM vm) { freeVars = new Scope(); var boundVars = new Stack<string>(); boundVars.Push(fun.name); foreach (FormalArg arg in fun.formals) boundVars.Push(arg.name); GetFreeVars(vm, fun.body, boundVars, freeVars); }
public static void Start(VM vm) { // Make sure that an exception triggered when evaluating from within debugger // doesn't cause multiple instances of the debugger. if (debugging) return; try { debugging = true; Console.WriteLine(""); Console.WriteLine("You are in the debugger."); Console.WriteLine("Type '?' for instructions and 'x' to exit."); while (true) { string sInput = Console.ReadLine().Trim(); string sCommand = sInput; string sArg = ""; int nSplit = sInput.IndexOf(' '); if (nSplit >= 0) { sCommand = sInput.Substring(0, nSplit); sArg = sInput.Substring(nSplit + 1).Trim(); } switch (sCommand) { case "x": debugging = false; return; case "s": PrintCallStack(vm); break; case "f": PrintCurrentFrame(vm); break; case "af": PrintAllFrames(vm); break; case "e": Evaluate(vm, sArg); break; default: Console.WriteLine("? - prints instructions"); Console.WriteLine("x - leaves debugger"); Console.WriteLine("s - prints call stack"); Console.WriteLine("f - print contents of current frame"); Console.WriteLine("af - prints contents of all frames"); Console.WriteLine("e <expr> - evaluates an expression"); break; } } } finally { debugging = false; } }
/// <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 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; bool[] bools = new bool[ii.InternalCount()]; ParallelOptions po = new ParallelOptions(); po.MaxDegreeOfParallelism = Config.maxThreads; var p = Partitioner.Create(0, ii.InternalCount()); Parallel.ForEach( p, po, () => { LoopParams lp = new LoopParams(); lp.op = new OptimizationParams(); lp.acc = lp.op.AddNewAccessor(name); lp.vm = vm.Fork(); lp.expr = predicate.Optimize(lp.op); return lp; }, (Tuple<int, int> range, ParallelLoopState state, LoopParams lp) => { for (int i = range.Item1; i < range.Item2; ++i) { lp.acc.Set(ii.InternalAt(i)); bools[i] = lp.vm.Eval(lp.expr).ToBool(); } return lp; }, (LoopParams lp) => { } ); List<HeronValue> r = new List<HeronValue>(ii.InternalCount()); for (int i = 0; i < ii.InternalCount(); ++i) if (bools[i]) r.Add(ii.InternalAt(i)); r.Capacity = r.Count; return new ListValue(r, sv.GetElementType()); }
public static void Evaluate(VM vm, string sArg) { if (sArg.Length == 0) { Console.WriteLine("No expression to evaluate"); return; } try { Console.WriteLine("Evaluating expression : " + sArg); HeronValue val = vm.EvalString(sArg); Console.WriteLine("Result : " + val.ToString()); } catch (Exception e) { Console.WriteLine("Error occured : " + e.Message); } }
public override HeronValue Eval(VM vm) { HeronValue a = operand1.Eval(vm); HeronValue b = operand2.Eval(vm); switch (opcode) { case OpCode.opEq: return new BoolValue(a.Equals(b)); case OpCode.opNEq: return new BoolValue(!a.Equals(b)); case OpCode.opIs: { TypeValue tv = b as TypeValue; if (tv == null) throw new Exception("The second argument of the 'is' operator must be a type"); return new BoolValue(a.Is(tv.Type)); } case OpCode.opAs: { HeronType t = b as HeronType; if (t == null) throw new Exception("The 'as' operator expects a type as a right hand argument"); HeronValue r = a.As(t); if (r != null) return r; if (t is InterfaceDefn && a is ClassInstance) { DuckValue dv = new DuckValue(a as ClassInstance, t as InterfaceDefn); return dv; } throw new Exception("Failed to convert " + a.Type.name + " to a " + t.name); }; } return a.InvokeBinaryOperator(vm, opcode, b); }
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 static void PrintAllFrames(VM vm) { foreach (Frame f in vm.GetFrames()) PrintFrame(f); }
public static void PrintCurrentFrame(VM vm) { PrintFrame(vm.CurrentFrame); }
public static void PrintCallStack(VM vm) { foreach (Frame f in vm.GetFrames()) Console.WriteLine(f.SimpleDescription); }
public override void Eval(VM vm) { if (expression != null) { HeronValue result = vm.Eval(expression); vm.Return(result); } else { vm.Return(HeronValue.Void); } }
/// <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 DisposableScope(VM vm) { this.vm = vm; vm.PushScope(); }
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; }
public override HeronValue Apply(VM vm, HeronValue[] args) { Object[] os = HeronDotNet.ObjectsToDotNetArray(args); Object o = self.GetSystemType().InvokeMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod, null, self.Unmarshal(), os); return DotNetObject.Marshal(o); }
public override HeronValue Instantiate(VM vm, HeronValue[] args, ModuleInstance m) { Object[] objs = HeronDotNet.ObjectsToDotNetArray(args); Object o = GetSystemType().InvokeMember(null, BindingFlags.Instance | BindingFlags.Public | BindingFlags.Default | BindingFlags.CreateInstance, null, null, objs); if (o == null) throw new Exception("Unable to construct " + name); return DotNetObject.Marshal(o); }
/// <summary> /// Creates a scope in the environment, containing variables that map to the class field names. /// It is the caller's reponsibility to remove the scope. /// </summary> /// <param name="env"></param> public void PushFieldsAsScope(VM vm) { vm.PushScope(fields); }
public override void Eval(VM vm) { vm.Eval(statement); }
public override void Eval(VM vm) { HeronValue o = condition.Eval(vm); foreach (CaseStatement c in cases) { HeronValue cond = vm.Eval(c.condition); if (o.Equals(cond)) { vm.Eval(c.statement); return; } } if (ondefault != null) { vm.Eval(ondefault); } }
public override HeronValue Instantiate(VM vm, HeronValue[] args, ModuleInstance m) { throw new Exception("Cannot instantiate an interface"); }
public DisposableScope(VM vm, Scope scope) { this.vm = vm; vm.PushScope(scope); }
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); }
public override void Eval(VM vm) { while (true) { HeronValue o = condition.Eval(vm); bool b = o.ToBool(); if (!b) break; vm.Eval(body); if (vm.ShouldExitScope()) break; } }
/// <summary> /// Creates a shallow copy of the VM, so that multiple threads /// can share it. /// </summary> /// <returns></returns> public VM Fork() { VM r = new VM(); r.bReturning = bReturning; r.result = result; r.program = program; r.frames = new List<Frame>(); foreach (Frame f in frames) r.frames.Add(f.Fork()); return r; }
public abstract HeronValue Invoke(VM vm, HeronValue self, HeronValue[] args);
/// <summary> /// Loads, parses, and executes a file. /// </summary> /// <param name="s"></param> static public void RunFile(string sFile) { VM vm = new VM(); vm.InitializeVM(); ModuleDefn m = vm.LoadModule(sFile); vm.LoadDependentModules(sFile); vm.ResolveTypes(); vm.RunModule(m); }
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)); }
public DisposableFrame(VM vm, FunctionDefn def, ClassInstance ci, ModuleInstance mi) { this.vm = vm; vm.PushNewFrame(def, ci, mi); }
public override HeronValue Apply(VM vm, HeronValue[] args) { return(method.Invoke(vm, self, args)); }