Esempio n. 1
0
        internal static bool CheckPrefix(ScriptObject node)
        {
            if (allowed == null)
            {
                var allTypes = new string[] { "node", "stringexpression", "memberaccess", "string", "number", "token" };
                allowed = new Dictionary<string, List<string>>();
                foreach (var type in allTypes) allowed.Add(type, new List<string>());

                allowed["node"].Add("$");
                allowed["node"].Add("^");
                allowed["node"].Add("*");
                allowed["node"].Add("#");
                allowed["node"].Add(":");

                allowed["token"].Add("$");
                allowed["token"].Add("#");
                allowed["token"].Add(":");

                allowed["string"].Add("*");
                allowed["string"].Add(":");

                allowed["stringexpression"].Add("*");
                allowed["stringexpression"].Add(":");
            }

            if (String.IsNullOrEmpty(node.gsp("@prefix"))) return true;
            if (allowed.ContainsKey(node.gsp("@type"))) return allowed[node.gsp("@type")].Contains(node.gsp("@prefix"));
            return false;
        }
Esempio n. 2
0
 public static void SerializeCode(System.IO.TextWriter to, ScriptObject root, int indent = -1)
 {
     if (root.gsp("@type") == "string")
         to.Write(root.gsp("@prefix") + "\"" + root.gsp("@token") + "\"");
     else if (root.gsp("@type") == "stringexpression")
     {
         to.Write(root.gsp("@prefix"));
         to.Write("\"");
         foreach (var item in root._children)
         {
             if ((item as ScriptObject).gsp("@type") == "string")
                 to.Write((item as ScriptObject).gsp("@token"));
             else
                 SerializeCode(to, item as ScriptObject);
         }
         to.Write("\"");
     }
     else if (root.gsp("@type") == "node")
     {
         to.Write(root.gsp("@prefix") + "(");
         foreach (var item in root._children)
         {
             //if (indent >= 0)
             //{
             //    to.Write("\n" + new String(' ', indent * 3));
             //    SerializeCode(to, item as ScriptObject, indent + 1);
             //}
             //else
                 SerializeCode(to, item as ScriptObject);
             to.Write(" ");
         }
         to.Write(")");
     }
     else if (root.gsp("@type") == "memberaccess")
     {
         SerializeCode(to, root._child(0) as ScriptObject);
         to.Write(root.gsp("@token"));
         SerializeCode(to, root._child(1) as ScriptObject);
     }
     else if (root.gsp("@type") == "dictionaryentry")
     {
         to.Write(root.gsp("@prefix") + "[");
         foreach (var item in root._children)
         {
             SerializeCode(to, item as ScriptObject);
             to.Write(" ");
         }
         to.Write("]");
     }
     else
     {
         to.Write(root.gsp("@token"));
     }
 }
Esempio n. 3
0
 public void EmitFunction(ScriptObject func, string type, System.IO.TextWriter to, bool recall = false, int indent = -1)
 {
     to.Write((recall ?  "" : "(") + type + " " + func.gsp("@name") + " ^(");
     var arguments = func["@arguments"] as ScriptList;
     foreach (var arg in arguments)
     {
         if (indent >= 0) to.Write("\n   ");
         emitArgumentSpec(arg as ScriptObject, to);
     }
     if (indent >= 0) to.Write("\n");
     to.Write(") ");
     Engine.SerializeCode(to, func["@function-body"] as ScriptObject, indent);
     if (!recall)
         to.Write((indent >= 0 ? "\n" : "") + " \"" + func.gsp("@help") + "\")\n");
 }
Esempio n. 4
0
        public static ScriptObject GetArgumentInfo(ScriptObject func, Context context, int index)
        {
            var arguments = func["@arguments"] as ScriptList;
            if (arguments == null) return null;

            if (index >= arguments.Count)
            {
                if (arguments.Count > 0 && (arguments[arguments.Count - 1] as ScriptObject)["@repeat"] != null)
                    return arguments[arguments.Count - 1] as ScriptObject;
                else
                {
                    context.RaiseNewError("Argument out of bounds", null);
                    return null;
                }
            }
            else
                return arguments[index] as ScriptObject;
        }
Esempio n. 5
0
 public void RaiseNewError(String message, ScriptObject location)
 {
     errorObject     = new GenericScriptObject("message", message, "location", location, "stack-trace", new ScriptList());
     evaluationState = EvaluationState.UnwindingError;
 }
Esempio n. 6
0
 public void RaiseNewError(String message, ScriptObject location)
 {
     errorObject = new GenericScriptObject("message", message, "location", location, "stack-trace", new ScriptList());
     evaluationState = EvaluationState.UnwindingError;
 }
Esempio n. 7
0
 public GenericScriptObject(ScriptObject cloneFrom)
 {
     foreach (var str in cloneFrom.ListProperties())
         SetProperty(str as String, cloneFrom.GetProperty(str as String));
 }
Esempio n. 8
0
 private void EmitFunctionListItem(ScriptObject item)
 {
     Write(item.gsp("@name"));
     if (item.gsp("@name").Length < 16)
         Write(new String(' ', 16 - item.gsp("@name").Length));
     Write(item.gsp("@help") + "\n");
 }
Esempio n. 9
0
 public static ScriptObject Optional(ScriptObject arg)
 {
     arg["@optional"] = true;
     return arg;
 }
Esempio n. 10
0
 private static void EmitObject(
     System.IO.TextWriter to,
     ScriptObject obj,
     List<ScriptObject> globalFunctions,
     List<ObjectRecord> objects,
     List<ObjectRecord> lambdas,
     int depth,
     bool ignoreFunctions = false)
 {
     to.WriteLine("(record ");
     EmitObjectProperties(to, obj, globalFunctions, objects, lambdas, depth + 1, ignoreFunctions);
     to.Write(")");
 }
Esempio n. 11
0
 private static bool AddRef(ScriptObject obj, List<ObjectRecord> list)
 {
     var spot = list.FirstOrDefault((o) => { return Object.ReferenceEquals(o.obj, obj); });
     if (spot != null) { spot.referenceCount++; return false; }
     else
     {
         list.Add(new ObjectRecord { obj = obj, referenceCount = 1 });
         return true;
     }
 }
Esempio n. 12
0
 public static bool IsFunction(ScriptObject obj)
 {
     if (obj == null) return false;
     return obj["@function-body"] != null;
 }
Esempio n. 13
0
        public Object Evaluate(
            Context context,
            Object what,
            bool ignoreStar     = false,
            bool discardResults = false)
        {
            if (context.evaluationState != EvaluationState.Normal)
            {
                throw new ScriptError("Invalid Context", null);
            }
            if (context.callDepth >= context.maximumCallDepth)
            {
                context.RaiseNewError("Overflow.", null);
                return(null);
            }

            context.callDepth += 1; //All exit points must decrement depth.

            if (what is String)
            {
                var r = EvaluateString(context, what as String, "", discardResults);
                context.callDepth -= 1;
                return(r);
            }
            else if (!(what is ScriptObject))
            {
                context.callDepth -= 1;
                return(what);
            }

            var node = what as ScriptObject;

            context.currentNode = node;

            if (context.limitExecutionTime && (DateTime.Now - context.executionStart > context.allowedExecutionTime))
            {
                context.RaiseNewError("Timeout.", node);
                context.callDepth -= 1;
                return(null);
            }

            if (node.gsp("@prefix") == "*" && !ignoreStar) //Object is a quoted node
            {
                context.callDepth -= 1;
                return(node);
            }

            var type = node.gsp("@type");

            if (String.IsNullOrEmpty(type))
            {
                context.callDepth -= 1;
                return(node);
            } //Object is not evaluatable code.

            object result = null;

            if (type == "string")
            {
                result = node["@token"];
            }
            else if (type == "stringexpression")
            {
                if (discardResults) //Don't bother assembling the string expression.
                {
                    foreach (var piece in node._children)
                    {
                        if ((piece as ScriptObject).gsp("@type") == "string")
                        {
                            continue;
                        }
                        else
                        {
                            Evaluate(context, piece);
                            if (context.evaluationState != EvaluationState.Normal)
                            {
                                context.callDepth -= 1;
                                return(null);
                            }
                        }
                    }
                    result = null;
                }
                else
                {
                    if (node._children.Count == 1) //If there's only a single item, the result is that item.
                    {
                        result = Evaluate(context, node._child(0));
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            context.callDepth -= 1;
                            return(null);
                        }
                    }
                    else
                    {
                        var resultString = String.Empty;
                        foreach (var piece in node._children)
                        {
                            resultString += ScriptObject.AsString(Evaluate(context, piece));
                            if (context.evaluationState != EvaluationState.Normal)
                            {
                                context.callDepth -= 1;
                                return(null);
                            }
                        }
                        result = resultString;
                    }
                }
            }
            else if (type == "token")
            {
                result = LookupToken(context, node.gsp("@token"));
                if (context.evaluationState != EvaluationState.Normal)
                {
                    context.callDepth -= 1;
                    return(null);
                }
            }
            else if (type == "memberaccess")
            {
                var lhs = Evaluate(context, node._child(0));
                if (context.evaluationState != EvaluationState.Normal)
                {
                    context.callDepth -= 1; return(null);
                }
                String rhs = "";

                if ((node._child(1) as ScriptObject).gsp("@type") == "token")
                {
                    rhs = (node._child(1) as ScriptObject).gsp("@token");
                }
                else
                {
                    rhs = ScriptObject.AsString(Evaluate(context, node._child(1), false));
                }
                if (context.evaluationState != EvaluationState.Normal)
                {
                    context.callDepth -= 1; return(null);
                }

                if (lhs == null)
                {
                    result = null;
                }
                else if (lhs is ScriptObject)
                {
                    result = (lhs as ScriptObject).GetProperty(ScriptObject.AsString(rhs));
                    if (node.gsp("@token") == ":")
                    {
                        context.Scope.PushVariable("this", lhs);
                        result = Evaluate(context, result, true, false);
                        context.Scope.PopVariable("this");
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            context.callDepth -= 1; return(null);
                        }
                    }
                }
                else
                {
                    var field = lhs.GetType().GetField(ScriptObject.AsString(rhs));
                    if (field != null)
                    {
                        result = field.GetValue(lhs);
                    }
                    else
                    {
                        var prop = lhs.GetType().GetProperty(ScriptObject.AsString(rhs));
                        if (prop != null)
                        {
                            result = prop.GetValue(lhs, null);
                        }
                        else
                        {
                            var members = lhs.GetType().FindMembers(System.Reflection.MemberTypes.Method,
                                                                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance,
                                                                    new System.Reflection.MemberFilter((minfo, obj) => { return(minfo.Name == obj.ToString()); }),
                                                                    ScriptObject.AsString(rhs));
                            if (members.Length != 0)
                            {
                                result = new GenericScriptObject(
                                    "@lazy-reflection", ScriptObject.AsString(rhs),
                                    "@source-object", lhs,
                                    "@source-type", lhs.GetType());
                            }
                            else
                            {
                                result = null;
                            }
                        }
                    }
                }
            }
            else if (type == "node")
            {
                if (!ignoreStar && node.gsp("@prefix") == "*")
                {
                    result = node;
                }
                else
                {
                    bool eval = node.gsp("@prefix") != "^";

                    var arguments = new ScriptList();

                    foreach (var child in node._children)
                    {
                        evaluateNodeChild(eval, child, arguments, context);
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            context.callDepth -= 1;
                            return(null);
                        }
                    }

                    if (node.gsp("@prefix") == "^")
                    {
                        result = arguments;
                    }
                    else
                    {
                        if (arguments.Count > 0 && Function.IsFunction(arguments[0] as ScriptObject))
                        {
                            result = Function.Invoke((arguments[0] as ScriptObject), this, context,
                                                     new ScriptList(arguments.GetRange(1, arguments.Count - 1)));
                            if (context.evaluationState != EvaluationState.Normal)
                            {
                                if (context.evaluationState == EvaluationState.UnwindingError)
                                {
                                    context.PushStackTrace((arguments[0] as ScriptObject).gsp("@name"));
                                }
                                context.callDepth -= 1;
                                return(null);
                            }
                        }
                        else if (arguments.Count > 0 &&
                                 arguments[0] is ScriptObject &&
                                 (arguments[0] as ScriptObject).GetProperty("@lazy-reflection") != null)
                        {
                            var sObj          = arguments[0] as ScriptObject;
                            var argumentTypes = arguments.GetRange(1, arguments.Count - 1).Select(
                                (obj) => obj.GetType()).ToArray();
                            var sourceObject = sObj.GetProperty("@source-object");
                            var method       = (sObj.GetProperty("@source-type") as System.Type)
                                               .GetMethod(sObj.gsp("@lazy-reflection"), argumentTypes);
                            if (method == null)
                            {
                                throw new ScriptError("Could not find overload for " +
                                                      sObj.gsp("@lazy-reflection") + " that takes argument types " +
                                                      String.Join(", ", argumentTypes.Select((t) => t.Name)) + " on type " +
                                                      sObj.GetProperty("@source-type").ToString(), what as ScriptObject);
                            }
                            result = method.Invoke(sourceObject, arguments.GetRange(1, arguments.Count - 1).ToArray());
                        }
                        else if (arguments.Count > 0)
                        {
                            result = arguments[0];
                        }
                        else
                        {
                            result = null;
                        }
                    }
                }
            }
            else if (type == "root")
            {
                var results = new ScriptList();
                foreach (var child in node._children)
                {
                    results.Add(Evaluate(context, child, false, false));
                    if (context.evaluationState != EvaluationState.Normal)
                    {
                        context.callDepth -= 1;
                        return(null);
                    }
                }
                return(results);
            }
            else if (type == "number")
            {
                try
                {
                    if (node.gsp("@token").Contains('.'))
                    {
                        result = Convert.ToSingle(node.gsp("@token"));
                    }
                    else
                    {
                        var numberString = node.gsp("@token");
                        if (numberString.StartsWith("0x"))
                        {
                            result = Convert.ToInt32(numberString.Substring(2), 16);
                        }
                        else if (numberString.StartsWith("0b"))
                        {
                            var accumulator = 0;
                            foreach (var c in numberString.Substring(2))
                            {
                                accumulator <<= 1;
                                if (c == '1')
                                {
                                    accumulator += 1;
                                }
                            }
                            result = accumulator;
                        }
                        else
                        {
                            result = Int32.Parse(numberString);
                        }
                    }
                }
                catch (Exception e)
                {
                    context.RaiseNewError("Number format error.", node);
                    { context.callDepth -= 1; return(null); }
                }
            }
            else if (type == "char")
            {
                context.callDepth -= 1;
                return(node.gsp("@token")[0]);
            }
            else
            {
                context.RaiseNewError("Internal evaluator error.", node);
                { context.callDepth -= 1; return(null); }
            }

            if (node.gsp("@prefix") == ":" && !ignoreStar)
            {
                result = Evaluate(context, result);
            }
            if (context.evaluationState != EvaluationState.Normal)
            {
                context.callDepth -= 1; return(null);
            }
            ;
            if (node.gsp("@prefix") == ".")
            {
                result = LookupToken(context, ScriptObject.AsString(result));
            }
            context.callDepth -= 1;
            return(result);
        }
Esempio n. 14
0
        private void SetupStringFunctions()
        {
            AddFunction("split", "Split a string into pieces", (context, arguments) =>
            {
                var pieces = AutoBind.StringArgument(arguments[0]).Split(
                    new String[] { AutoBind.StringArgument(arguments[1]) },
                    Int32.MaxValue, StringSplitOptions.RemoveEmptyEntries);
                var r = new ScriptList(pieces);
                return(r);
            }, Arguments.Arg("string"), Arguments.Arg("split-chars"));

            AddFunction("strlen", "string : Returns length of string.",
                        (context, arguments) =>
            {
                return(ScriptObject.AsString(arguments[0]).Length);
            }, Arguments.Arg("string"));

            AddFunction("strind",
                        "string n : Returns nth element in string.",
                        (context, arguments) =>
            {
                var index = arguments[1] as int?;
                if (index == null || !index.HasValue)
                {
                    return(null);
                }
                if (index.Value < 0)
                {
                    return(null);
                }
                var str = ScriptObject.AsString(arguments[0]);
                if (index.Value >= str.Length)
                {
                    return(null);
                }
                return(str[index.Value]);
            },
                        Arguments.Arg("string"),
                        Arguments.Arg("n"));

            AddFunction("substr", "Returns a portion of the input string.",
                        (context, arguments) =>
            {
                var str   = ScriptObject.AsString(arguments[0]);
                var start = AutoBind.IntArgument(arguments[1]);
                if (arguments[2] == null)
                {
                    return(str.Substring(start));
                }
                else
                {
                    return(str.Substring(start, AutoBind.IntArgument(arguments[2])));
                }
            },
                        Arguments.Arg("string"),
                        Arguments.Arg("start"),
                        Arguments.Optional("length"));

            AddFunction("strcat", "Concatenate many strings into one.",
                        (context, arguments) =>
            {
                var r = new StringBuilder();
                foreach (var obj in AutoBind.ListArgument(arguments[0]))
                {
                    r.Append(ScriptObject.AsString(obj));
                }
                return(r.ToString());
            },
                        Arguments.Repeat("item"));

            AddFunction("itoa", "Change a number to the string representation.",
                        (context, arguments) =>
            {
                return(arguments[0].ToString());
            },
                        Arguments.Arg("i"));

            AddFunction("atoi", "",
                        (context, arguments) =>
            {
                return(Convert.ToInt32(arguments[0]));
            },
                        Arguments.Arg("i"));

            AddFunction("unescape", "", (context, arguments) =>
            {
                return(Console.UnescapeString(ScriptObject.AsString(arguments[0])));
            },
                        Arguments.Arg("string"));

            AddFunction("format", "Format a string.",
                        (context, arguments) =>
            {
                return(String.Format(AutoBind.StringArgument(arguments[0]),
                                     AutoBind.ListArgument(arguments[1]).ToArray()));
            },
                        Arguments.Arg("format-string"),
                        Arguments.Optional(Arguments.Repeat("value")));
        }
Esempio n. 15
0
        public static Object Invoke(ScriptObject func, Engine engine, Context context, ScriptList arguments)
        {
            var name         = func.gsp("@name");
            var argumentInfo = func["@arguments"] as ScriptList;

            if (context.trace != null)
            {
                context.trace(new String('.', context.traceDepth) + "Entering " + name + "\n");
                context.traceDepth += 1;
            }

            var newArguments = new ScriptList();

            //Check argument types
            if (argumentInfo.Count == 0 && arguments.Count != 0)
            {
                context.RaiseNewError("Function expects no arguments.", context.currentNode);
                return(null);
            }

            int argumentIndex = 0;

            for (int i = 0; i < argumentInfo.Count; ++i)
            {
                var info = argumentInfo[i] as ScriptObject;
                if (info == null)
                {
                    throw new ScriptError("Invalid argument descriptor on function object", context.currentNode);
                }
                if (info["@repeat"] != null)
                {
                    var list = new ScriptList();
                    while (argumentIndex < arguments.Count)     //Handy side effect: If no argument is passed for an optional repeat
                    {                                           //argument, it will get an empty list.
                        list.Add(MutateArgument(arguments[argumentIndex], info, engine, context));
                        //list.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex]));
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            return(null);
                        }
                        ++argumentIndex;
                    }
                    newArguments.Add(list);
                }
                else
                {
                    if (argumentIndex < arguments.Count)
                    {
                        newArguments.Add(MutateArgument(arguments[argumentIndex], info, engine, context));
                        //newArguments.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex]));
                        if (context.evaluationState == EvaluationState.UnwindingError)
                        {
                            return(null);
                        }
                    }
                    else if (info["@optional"] != null)
                    {
                        newArguments.Add(MutateArgument(null, info, engine, context));
                    }
                    else
                    {
                        context.RaiseNewError("Not enough arguments to " + name, context.currentNode);
                        return(null);
                    }
                    ++argumentIndex;
                }
            }
            if (argumentIndex < arguments.Count)
            {
                context.RaiseNewError("Too many arguments to " + name, context.currentNode);
                return(null);
            }


            Object r = null;

            if (func["@function-body"] is ScriptObject)
            {
                var declarationScope = func["@declaration-scope"];
                if (declarationScope is GenericScriptObject)
                {
                    var newScope = new Scope();
                    foreach (var valueName in (declarationScope as GenericScriptObject).properties)
                    {
                        newScope.PushVariable(valueName.Key, valueName.Value);
                    }
                    func["@declaration-scope"] = newScope;
                }

                context.PushScope(func["@declaration-scope"] as Scope);

                for (int i = 0; i < argumentInfo.Count; ++i)
                {
                    context.Scope.PushVariable((argumentInfo[i] as ScriptObject).gsp("@name"), newArguments[i]);
                }

                r = engine.Evaluate(context, func["@function-body"], true);

                for (int i = 0; i < argumentInfo.Count; ++i)
                {
                    context.Scope.PopVariable((argumentInfo[i] as ScriptObject).gsp("@name"));
                }

                context.PopScope();
            }
            else
            {
                try
                {
                    r = (func["@function-body"] as Func <Context, ScriptList, Object>)(context, newArguments);
                }
                catch (Exception e)
                {
                    context.RaiseNewError("System Exception: " + e.Message, context.currentNode);
                    return(null);
                }
            }


            if (context.trace != null)
            {
                context.traceDepth -= 1;
                context.trace(new String('.', context.traceDepth) + "Leaving " + name +
                              (context.evaluationState == EvaluationState.UnwindingError ?
                               (" -Error: " + context.errorObject.GetLocalProperty("message").ToString()) :
                               "") +
                              (context.evaluationState == EvaluationState.UnwindingBreak ? " -Breaking" : "") +
                              "\n");
            }

            return(r);
        }
Esempio n. 16
0
 public static string StringArgument(Object obj)
 {
     return(ScriptObject.AsString(obj));
 }
Esempio n. 17
0
 public static ScriptObject Repeat(ScriptObject arg)
 {
     arg["@repeat"] = true;
     return arg;
 }
Esempio n. 18
0
        private static ScriptList children(ScriptObject obj)
        {
            var list = obj["@children"];
            if (list == null)
            {
                list = new ScriptList();
                obj["@children"] = list;
            }

            return list as ScriptList;
        }
Esempio n. 19
0
 private static void EmitObjectProperties(
     System.IO.TextWriter to,
     ScriptObject obj,
     List<ScriptObject> globalFunctions,
     List<ObjectRecord> objects,
     List<ObjectRecord> lambdas,
     int depth,
     bool ignoreFunctions = false)
 {
     foreach (var propertyName in obj.ListProperties())
     {
         to.Write("\n" + new String(' ', depth * 3) + "(" + propertyName as String + " ");
         var value = obj.GetLocalProperty(propertyName as String);
         EmitObjectProperty(to, value, globalFunctions, objects, lambdas, depth, ignoreFunctions);
         to.Write(")");
     }
 }
Esempio n. 20
0
 private static bool isType(ScriptObject obj, String type)
 {
     return obj.gsp("@type") == type;
 }
Esempio n. 21
0
        private static void EnumerateObject(
            ScriptObject obj,
            List<ScriptObject> globalFunctions,
            List<ObjectRecord> objects,
            List<ObjectRecord> lambdas,
            bool ignoreFunctions = false)
        {
            if (obj == null) return;

            if (Function.IsFunction(obj))
            {
                if (ignoreFunctions) return;
                //System function?
                if (Function.IsSystemFunction(obj)) return;
                //Lambda function?
                if (globalFunctions.Contains(obj)) return;
                if (AddRef(obj, lambdas))
                    EnumerateObject(obj["declaration-scope"] as ScriptObject, globalFunctions, objects, lambdas, ignoreFunctions);
            }
            else
            {
                foreach (var prop in obj.ListProperties())
                {
                    var value = obj.GetLocalProperty(prop as String);
                    if (value is ScriptObject)
                    {
                        if (AddRef(value as ScriptObject, objects))
                            EnumerateObject(value as ScriptObject, globalFunctions, objects, lambdas, ignoreFunctions);
                    }
                    else if (value is ScriptList)
                    {
                        foreach (var item in value as ScriptList)
                        {
                            if (item is ScriptObject)
                                if (AddRef(item as ScriptObject, objects))
                                    EnumerateObject(item as ScriptObject, globalFunctions, objects, lambdas, ignoreFunctions);
                        }
                    }

                }
            }
        }
Esempio n. 22
0
        private static void emitArgumentSpec(ScriptObject arg, System.IO.TextWriter to)
        {
            if (arg["@mutator"] == null && arg["@optional"] == null && arg["@repeat"] == null && arg["@lazy"] == null)
            {
                to.Write("(arg " + arg["@name"] + ")");
                return;
            }

            if (arg["@mutator"] != null) to.Write("(arg-mutator ");
            if (arg["@optional"] != null) to.Write("(arg-optional ");
            if (arg["@repeat"] != null) to.Write("(arg-repeat ");
            if (arg["@lazy"] != null) to.Write("(arg-lazy ");
            to.Write(arg["@name"]);
            if (arg["@lazy"] != null) to.Write(")");
            if (arg["@repeat"] != null) to.Write(")");
            if (arg["@optional"] != null) to.Write(")");
            if (arg["@mutator"] != null)
            {
                to.Write(" ");
                SerializeCode(to, arg["@mutator"] as ScriptObject);
                to.Write(")");
            }
        }
Esempio n. 23
0
        public void SerializeObject(System.IO.TextWriter to, ScriptObject obj)
        {
            if (obj == null)
            {
                to.WriteLine("(null)");
                return;
            }

            var objects = new List<ObjectRecord>();

            EnumerateObject(obj, null, objects, null, true);

            //Filter out objects with just a single reference
            objects = new List<ObjectRecord>(objects.Where((o) => { return o.referenceCount > 1; }));
            AddRef(obj, objects);

            //Create and emit lambda functions.
            to.WriteLine("(let ((\"objects\" (array " + objects.Count + " (record))))");
            to.WriteLine("  (lastarg\n");

            //Emit remaining objects
            foreach (var _obj in objects)
                EmitObjectRoot(to, _obj.obj, null, objects, null, true);

            //Emit footer
            var thisIndex = IndexIn(obj, objects);
            to.WriteLine("      (index objects " + thisIndex + ")");
            to.WriteLine("  )");
            to.WriteLine(")");
        }
Esempio n. 24
0
 public static bool IsSystemFunction(ScriptObject obj)
 {
     if (obj == null) return false;
     return obj["@function-body"] is Func<Context, ScriptList, Object>;
 }
Esempio n. 25
0
 public TimeoutError(ScriptObject generatedBy) : base("Execution timed out.", generatedBy)
 {
 }
Esempio n. 26
0
 private static void EmitObjectRoot(
     System.IO.TextWriter to,
     ScriptObject obj,
     List<ScriptObject> globalFunctions,
     List<ObjectRecord> objects,
     List<ObjectRecord> lambdas,
     bool ignoreFunctions = false)
 {
     var index = IndexIn(obj, objects);
     to.WriteLine("(multi-set (index objects " + index + ") ");
     EmitObjectProperties(to, obj, globalFunctions, objects, lambdas, 1, ignoreFunctions);
     to.Write(")\n");
 }
Esempio n. 27
0
        public static ScriptObject MakeFunction(
            String name, 
            ScriptList arguments,
            String help,
            ScriptObject body,
            ScriptObject declarationScope,
            bool copyScope = false)
        {
            if (copyScope)
            {
                var newScope = new Scope();
                foreach (var prop in declarationScope.ListProperties())
                    newScope.PushVariable(prop as String, declarationScope.GetLocalProperty(prop as String));
                declarationScope = newScope;
            }

            return new GenericScriptObject(
                "@name", name,
                "@arguments", arguments,
                "@help", help,
                "@function-body", body,
                "@declaration-scope", declarationScope);
        }
Esempio n. 28
0
 private static int IndexIn(ScriptObject obj, List<ObjectRecord> list)
 {
     for (int i = 0; i < list.Count; ++i)
         if (list[i].obj == obj) return i;
     return -1;
 }
Esempio n. 29
0
 private static Object MutateArgument(Object argument, ScriptObject argumentDescripter, Engine engine, Context context)
 {
     var mutator = argumentDescripter["@mutator"];
     if (mutator == null) return argument;
     context.Scope.PushVariable("value", argument);
     var result = engine.Evaluate(context, mutator, true);
     context.Scope.PopVariable("value");
     return result;
 }
Esempio n. 30
0
        public void ExecuteCode(ScriptObject obj)
        {
            try
            {
                environment.context.ResetTimer();
                environment.context.evaluationState = EvaluationState.Normal;
                var result = environment.engine.Evaluate(environment.context, obj, true, false);

                if (environment.context.evaluationState != EvaluationState.UnwindingError)
                {
                    if (!noEcho) Write(MISP.Console.PrettyPrint2(result, 0) + "\n");
                }
                else
                {
                    Write("Error:\n");
                    Write(MISP.Console.PrettyPrint2(environment.context.errorObject, 0));
                }

                if (!environment.context.CheckScope())
                    Write("Error: Scopes not properly cleaned.\n");

                noEcho = false;
            }
            catch (Exception e)
            {
                Write(e.Message + "\n");
            }
        }
Esempio n. 31
0
        public static Object Invoke(ScriptObject func, Engine engine, Context context, ScriptList arguments)
        {
            var name = func.gsp("@name");
            var argumentInfo = func["@arguments"] as ScriptList;

            if (context.trace != null)
            {
                context.trace(new String('.', context.traceDepth) + "Entering " + name +"\n");
                context.traceDepth += 1;
            }

            var newArguments = new ScriptList();
            //Check argument types
            if (argumentInfo.Count == 0 && arguments.Count != 0)
            {
                context.RaiseNewError("Function expects no arguments.", context.currentNode);
                return null;
            }

                int argumentIndex = 0;
                for (int i = 0; i < argumentInfo.Count; ++i)
                {
                    var info = argumentInfo[i] as ScriptObject;
                    if (info == null)
                        throw new ScriptError("Invalid argument descriptor on function object", context.currentNode);
                    if (info["@repeat"] != null)
                    {
                        var list = new ScriptList();
                        while (argumentIndex < arguments.Count) //Handy side effect: If no argument is passed for an optional repeat
                        {                                       //argument, it will get an empty list.
                            list.Add(MutateArgument(arguments[argumentIndex], info, engine, context));
                            //list.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex]));
                            if (context.evaluationState != EvaluationState.Normal) return null;
                            ++argumentIndex;
                        }
                        newArguments.Add(list);
                    }
                    else
                    {
                        if (argumentIndex < arguments.Count)
                        {
                            newArguments.Add(MutateArgument(arguments[argumentIndex], info, engine, context));
                            //newArguments.Add((info["@type"] as Type).ProcessArgument(context, arguments[argumentIndex]));
                            if (context.evaluationState == EvaluationState.UnwindingError) return null;
                        }
                        else if (info["@optional"] != null)
                            newArguments.Add(MutateArgument(null, info, engine, context));
                        else
                        {
                            context.RaiseNewError("Not enough arguments to " + name, context.currentNode);
                            return null;
                        }
                        ++argumentIndex;
                    }
                }
                if (argumentIndex < arguments.Count)
                {
                    context.RaiseNewError("Too many arguments to " + name, context.currentNode);
                    return null;
                }

            Object r = null;

            if (func["@function-body"] is ScriptObject)
            {
                var declarationScope = func["@declaration-scope"];
                if (declarationScope is GenericScriptObject)
                {
                    var newScope = new Scope();
                    foreach (var valueName in (declarationScope as GenericScriptObject).properties)
                        newScope.PushVariable(valueName.Key, valueName.Value);
                    func["@declaration-scope"] = newScope;
                }

                context.PushScope(func["@declaration-scope"] as Scope);

                for (int i = 0; i < argumentInfo.Count; ++i)
                    context.Scope.PushVariable((argumentInfo[i] as ScriptObject).gsp("@name"), newArguments[i]);

                r = engine.Evaluate(context, func["@function-body"], true);

                for (int i = 0; i < argumentInfo.Count; ++i)
                    context.Scope.PopVariable((argumentInfo[i] as ScriptObject).gsp("@name"));

                context.PopScope();
            }
            else
            {
                try
                {
                    r = (func["@function-body"] as Func<Context, ScriptList, Object>)(context, newArguments);
                }
                catch (Exception e)
                {
                    context.RaiseNewError("System Exception: " + e.Message, context.currentNode);
                    return null;
                }
            }

            if (context.trace != null)
            {
                context.traceDepth -= 1;
                context.trace(new String('.', context.traceDepth) + "Leaving " + name +
                    (context.evaluationState == EvaluationState.UnwindingError ?
                    (" -Error: " + context.errorObject.GetLocalProperty("message").ToString()) :
                    "") +
                    (context.evaluationState == EvaluationState.UnwindingBreak ? " -Breaking" : "") +
                    "\n");
            }

            return r;
        }
Esempio n. 32
0
 public ScriptError(String msg, ScriptObject generatedAt)
     : base(msg)
 {
     this.generatedAt = generatedAt;
 }
Esempio n. 33
0
        public static ScriptObject ReorderMemberAccessNode(ScriptObject node)
        {
            //Convert (A (B (C D))) to (((A B) C) D)

            //Create an (A B C D) list.
            var nodeList = new LinkedList<AccessChainNode>();
            for (var n = node; n != null; n = (isType(n, "memberaccess") ? child(n,1) as ScriptObject : null))
            {
                if (isType(n, "memberaccess"))
                    nodeList.AddLast(new AccessChainNode { node = child(n,0), token = n["@token"] });
                else
                    nodeList.AddLast(new AccessChainNode { node = n, token = "" });
            }

            //Each iteration, take the first two nodes and combine them into a new member access node.
            //(A B C D) becomes ((A B) C D), etc.
            while (nodeList.Count > 1)
            {
                var lhs = nodeList.First();
                nodeList.RemoveFirst();
                var rhs = nodeList.First();
                nodeList.RemoveFirst();

                var newNode = new GenericScriptObject("@type", "memberaccess", "@start", (lhs.node as ScriptObject)["@start"],
                    "@source", (lhs.node as ScriptObject)["@source"]);
                newNode["@token"] = lhs.token;
                children(newNode).Add(lhs.node);
                children(newNode).Add(rhs.node);

                nodeList.AddFirst(new AccessChainNode
                {
                    node = newNode,
                    token = rhs.token
                });
            }

            return nodeList.First().node as ScriptObject;
        }
Esempio n. 34
0
 public TimeoutError(ScriptObject generatedBy)
     : base("Execution timed out.", generatedBy)
 {
 }
Esempio n. 35
0
 private static Object child(ScriptObject obj, int index)
 {
     return (obj["@children"] as ScriptList)[index];
 }
Esempio n. 36
0
 public Context(ScriptObject obj)
 {
     Reset();
     foreach (var name in obj.ListProperties())
         Scope.PushVariable(name as String, obj.GetLocalProperty(name as String));
 }
Esempio n. 37
0
        private void SetupObjectFunctions()
        {
            AddFunction("members", "Lists all members of an object",
                        (context, arguments) =>
            {
                var obj = ArgumentType <ScriptObject>(arguments[0]);
                return(obj.ListProperties());
            },
                        Arguments.Arg("object"));

            AddFunction("record", "Create a new record.",
                        (context, arguments) =>
            {
                var obj  = new GenericScriptObject();
                var vars = AutoBind.ListArgument(arguments[0]);
                foreach (var item in vars)
                {
                    var l = ArgumentType <ScriptObject>(item);
                    if (l == null || l._children.Count != 2)
                    {
                        throw new ScriptError("Record expects a list of pairs.", null);
                    }
                    var arg      = l._child(0) as ScriptObject;
                    string mname = "";
                    if (arg != null && arg.gsp("@type") == "token")
                    {
                        mname = arg.gsp("@token");
                    }
                    else
                    {
                        mname = Evaluate(context, arg, true).ToString();
                    }
                    obj.SetProperty(mname, Evaluate(context, l._child(1)));
                }
                return(obj);
            },
                        Arguments.Repeat(Arguments.Lazy("pairs")));

            AddFunction("clone", "Clone a record.",
                        (context, arguments) =>
            {
                var r = new GenericScriptObject(arguments[0] as ScriptObject);
                foreach (var item in arguments[1] as ScriptList)
                {
                    var list = item as ScriptList;
                    if (list == null || list.Count != 2)
                    {
                        throw new ScriptError("Record expects only pairs as arguments.", context.currentNode);
                    }
                    r[ScriptObject.AsString(list[0])] = list[1];
                }
                return(r);
            },
                        Arguments.Arg("object"),
                        Arguments.Mutator(Arguments.Repeat(Arguments.Optional("pairs")), "(@list value)"));

            AddFunction("set", "Set a member on an object.",
                        (context, arguments) =>
            {
                if (arguments[0] == null)
                {
                    return(arguments[2]);
                }
                return(SetObjectProperty(context, arguments[0], ScriptObject.AsString(arguments[1]), arguments[2]));
            },
                        Arguments.Arg("object"),
                        Arguments.Mutator(Arguments.Lazy("name"), "(@identifier-if-token value)"),
                        Arguments.Arg("value"));

            AddFunction("multi-set", "Set multiple members of an object.",
                        (context, arguments) =>
            {
                var obj  = ArgumentType <ScriptObject>(arguments[0]);
                var vars = AutoBind.ListArgument(arguments[1]);
                foreach (var item in vars)
                {
                    var l = ArgumentType <ScriptObject>(item);
                    if (l == null || l._children.Count != 2)
                    {
                        throw new ScriptError("Multi-set expects a list of pairs.", null);
                    }
                    var arg      = l._child(0) as ScriptObject;
                    string mname = "";
                    if (arg != null && arg.gsp("@type") == "token")
                    {
                        mname = arg.gsp("@token");
                    }
                    else
                    {
                        mname = Evaluate(context, arg, true).ToString();
                    }
                    SetObjectProperty(context, obj, mname, Evaluate(context, l._child(1)));
                }
                return(obj);
            },
                        Arguments.Arg("object"),
                        Arguments.Repeat(Arguments.Lazy("pairs")));

            AddFunction("delete", "Deletes a property from an object.",
                        (context, arguments) =>
            {
                var value = (arguments[0] as ScriptObject)[ScriptObject.AsString(arguments[1])];
                if (arguments[0] is Scope)
                {
                    (arguments[0] as Scope).PopVariable(ScriptObject.AsString(arguments[1]));
                }
                else
                {
                    (arguments[0] as ScriptObject).DeleteProperty(ScriptObject.AsString(arguments[1]));
                }
                return(value);
            },
                        Arguments.Arg("object"),
                        Arguments.Arg("property-name"));
        }