예제 #1
0
        public override SValue Evaluate(ExecEnvironment env)
        {
            var arguments = SExpression.EvalSExpressions(this.arguments, env);
            var subObj    = arguments[0];

            try
            {
                if (subObj is SString)
                {
                    SString subStr = subObj as SString;

                    if (arguments.Count == 2)
                    {
                        return(new SString(subStr.Get <string>().Substring(
                                               (int)arguments[1].Get <Decimal>()
                                               )));
                    }
                    else
                    {
                        return(new SString(subStr.Get <string>().Substring(
                                               (int)arguments[1].Get <Decimal>(),
                                               (int)arguments[2].Get <Decimal>()
                                               )));
                    }
                }
                else if (subObj is SList)
                {
                    SList subList = subObj as SList;
                    if (arguments.Count == 2)
                    {
                        return(new SList(subList.Get <List <SValue> >().Skip(
                                             (int)arguments[1].Get <Decimal>()
                                             ).ToList()));
                    }
                    else
                    {
                        return(new SList(subList.Get <List <SValue> >().Skip(
                                             (int)arguments[1].Get <Decimal>()).Take(
                                             (int)arguments[2].Get <Decimal>()
                                             ).ToList()));
                    }
                }
                else
                {
                    throw new VMException("the first argument must be a string or a list", headAtom);
                }
            }
            catch
            {
                throw new VMException("invalid arguments", headAtom);
            }
        }
예제 #2
0
        public override SValue Evaluate(ExecEnvironment env)
        {
            SValue ret = new SBool(false);

            foreach (var e in SExpression.EvalSExpressions(arguments, env))
            {
                ret = e;
                Console.Write(printSValue(e, env, 2));
            }
            Console.Write(delim);

            return(ret);
        }
예제 #3
0
파일: Core.cs 프로젝트: coyove/EugineCSharp
        public override SValue Evaluate(ExecEnvironment env)
        {
            arguments = SExpression.EvalSExpressions(argumentExprs, env);

            try {
                switch (func)
                {
                case "<":   return(new SBool(compareNumber(new int[] { -1 }, env)));

                case "<=":  return(new SBool(compareNumber(new int[] { -1, 0 }, env)));

                case ">":   return(new SBool(compareNumber(new int[] { 1 }, env)));

                case ">=":  return(new SBool(compareNumber(new int[] { 1, 0 }, env)));

                case "==":  return(new SBool(objectEquality(true, env)));

                case "<>":  return(new SBool(objectEquality(false, env)));

                case "&&":  return(new SBool(compareBool("and", env)));

                case "||":  return(new SBool(compareBool("or", env)));

                case "+":   return(tryPlus(env));

                case "-":
                case "*":
                case "/":
                case "%":
                    var r = arguments[0].Evaluate(env);
                    if (!r.Is <Decimal>())
                    {
                        throw new VMException("it only apply to numbers", headAtom);
                    }

                    var host = r.Get <Decimal>();
                    for (var i = 1; i < arguments.Count(); i++)
                    {
                        var v1 = arguments[i].Evaluate(env);

                        if (v1.Is <Decimal>())
                        {
                            switch (func)
                            {
                            case "-": host -= v1.Get <Decimal>(); break;

                            case "*": host *= v1.Get <Decimal>(); break;

                            case "/":
                            case "%":
                                Decimal tmp = v1.Get <Decimal>();
                                if (tmp != 0)
                                {
                                    if (func == "/")
                                    {
                                        host /= tmp;
                                    }
                                    else
                                    {
                                        host %= tmp;
                                    }
                                }
                                else
                                {
                                    throw new VMException("divided by 0", headAtom);
                                }
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                        }
                        else
                        {
                            throw new VMException("it only apply to numbers", headAtom);
                        }
                    }

                    return(new SNumber(host));

                default:
                    throw new NotImplementedException();
                }
            }
            catch (System.OverflowException)
            {
                throw new VMException("arithmetic operation failed due to overflow", headAtom);
            }
        }
예제 #4
0
파일: Call.cs 프로젝트: coyove/EugineCSharp
        public override SValue Evaluate(ExecEnvironment env)
        {
            var      newEnv = new ExecEnvironment();
            SValue   _closure;
            SClosure closure = null;

            if (lambdaObject == null)
            {
                if (env.ContainsKey(closureName))
                {
                    _closure = env[closureName].Evaluate(env);
                    closure  = _closure as SClosure;
                }
                else
                {
                    _closure         = new SString(closureName);
                    env[closureName] = _closure;
                }
            }
            else
            {
                _closure = lambdaObject.Evaluate(env);
                closure  = _closure as SClosure;
            }

            List <SValue> arguments = SExpression.EvalSExpressions(this.arguments, env);

            if (closure == null)
            {
                List <SValue> ret = new List <SValue>();
                ret.Add(_closure);
                foreach (var a in arguments)
                {
                    ret.Add(a);
                }

                return(new SList(ret));
            }

            if (closure.Arguments.Count() > arguments.Count())
            {
                var argNames = closure.Arguments.Skip(arguments.Count);
                return(new SClosure(
                           env, argNames.ToList(), new SECall(
                               closure,
                               arguments.ConvertAll(a => (SExpression)a)
                               .Concat(argNames.Select(a => new SEVariable(a, headAtom, tailCompound))).ToList(),
                               headAtom, tailCompound
                               )
                           ));
            }

            // prepare the executing environment
            for (int i = 0; i < closure.Arguments.Count(); i++)
            {
                string argName = closure.Arguments[i];

                if (argName.Length > 3 && argName.Substring(argName.Length - 3) == "...")
                {
                    argName         = argName.Substring(0, argName.Length - 3);
                    newEnv[argName] = new SList(arguments.Skip(i).ToList());
                    break;
                }
                else
                {
                    newEnv[argName] = arguments[i];
                }
            }

            newEnv["~parent"] = new SDict(closure.InnerEnv);
            newEnv["~atom"]   = new SObject(headAtom);

            newEnv.ParentEnv = closure.InnerEnv;
            return(closure.Body.Evaluate(newEnv));
        }