Beispiel #1
0
        public override SValue Evaluate(ExecEnvironment env)
        {
            var dict = this.dict.Evaluate(env);

            for (var i = 0; i < keys.Count; i++)
            {
                if (dict is SDict)
                {
                    var key = this.keys[i].Evaluate(env) as SString;
                    if (key == null)
                    {
                        throw new VMException("it only take a string as the key", headAtom);
                    }

                    var d = dict.Get <Dictionary <String, SValue> >();
                    var k = key.Get <String>();

                    if (!d.ContainsKey(k))
                    {
                        d[k] = new SNull();
                    }

                    d[k].RefDict    = dict as SDict;
                    d[k].RefDictKey = k;
                    d[k].RefList    = null;

                    dict = d[k];
                }
                else if (dict is SList)
                {
                    var index = this.keys[i].Evaluate(env) as SNumber;
                    if (index == null)
                    {
                        throw new VMException("it only take a number as the index", headAtom);
                    }

                    var l   = dict.Get <List <SValue> >();
                    var idx = (int)index.Get <Decimal>();

                    if (idx >= l.Count)
                    {
                        throw new VMException("index out of range", headAtom);
                    }

                    l[idx].RefList      = dict as SList;
                    l[idx].RefListIndex = idx;
                    l[idx].RefDict      = null;

                    dict = l[idx];
                }
                else
                {
                    throw new VMException("it only take a list or a dict as the first argument", headAtom);
                }
            }

            return(dict);
        }
Beispiel #2
0
        public override SValue Evaluate(ExecEnvironment env)
        {
            var body = this.body.Evaluate(env) as SClosure;

            if (body == null)
            {
                throw new VMException("the second argument must be a lambda or a named function", headAtom);
            }

            SValue        _list  = this.list.Evaluate(env);
            List <SValue> values = new List <SValue>();
            SList         list   = new SList(values);

            bool whileLoop      = false;
            bool condAlwaysTrue = false;

            if (_list is SList)
            {
                list   = _list as SList;
                values = list.Get <List <SValue> >();
                if (values.Count == 0)
                {
                    whileLoop      = true;
                    condAlwaysTrue = true;
                }
            }
            else if (_list is SBool)
            {
                whileLoop      = true;
                condAlwaysTrue = false;
            }
            else
            {
                throw new VMException("the first argument must be a list or a bool", headAtom);
            }

            if (whileLoop)
            {
                while (condAlwaysTrue || this.list.Evaluate(env).Get <bool>())
                {
                    var ret = execLoop(body, new SNull(), 0);
                    if (ret.Is <bool>() && !ret.Get <bool>())
                    {
                        break;
                    }
                }
            }
            else
            {
                for (var i = 0; i < values.Count; i++)
                {
                    var ret = execLoop(body, values[i], i);
                    if (ret.Is <bool>() && !ret.Get <bool>())
                    {
                        break;
                    }
                }
            }


            return(new SBool(true));
        }