예제 #1
0
 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");
     }
 }
예제 #2
0
        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);
        }
예제 #3
0
        public void Remove(HeronValue index)
        {
            CheckIndexType(index);
            int n = index.GetHashCode();

            values.Remove(n);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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));
        }
예제 #7
0
 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());
     }
 }
예제 #8
0
        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));
            }
        }
예제 #9
0
        public override HeronValue Eval(VM vm)
        {
            HeronValue result = vm.Eval(expr);

            vm.Eval(ass);
            return(result);
        }
예제 #10
0
        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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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)));
        }
예제 #13
0
        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();
            }
        }
예제 #14
0
        public override HeronValue Eval(VM vm)
        {
            HeronValue o = self.Eval(vm);
            HeronValue i = index.Eval(vm);

            return(o.GetAtIndex(i));
        }
예제 #15
0
        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);
                }
            }
        }
예제 #16
0
        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));
            }
        }
예제 #17
0
        public override HeronValue Eval(VM vm)
        {
            HeronValue[] argvals = args.Eval(vm);
            HeronValue   f       = funexpr.Eval(vm);

            return(f.Apply(vm, argvals));
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
        /// <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);
        }
예제 #20
0
        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));
            }
        }
예제 #21
0
        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");
        }
예제 #22
0
        public Accessor AddNewAccessor(string name, HeronValue val)
        {
            Accessor acc = new Accessor(val);

            accessors.Add(name, acc);
            return(acc);
        }
예제 #23
0
        /// <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()));
        }
예제 #24
0
        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));
        }
예제 #25
0
        /// <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);
        }
예제 #26
0
 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);
 }
예제 #27
0
        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);
        }
예제 #28
0
 public override HeronValue[] ToArray()
 {
     HeronValue[] a = new HeronValue[InternalCount()];
     for (int i = 0; i < cnt; ++i)
     {
         a[i + from] = list.InternalAt(i);
     }
     return(a);
 }
예제 #29
0
        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()]));
        }
예제 #30
0
        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();
        }