Esempio n. 1
0
 public GenericScriptObject(params Object[] args)
 {
     if (args.Length % 2 != 0)
     {
         throw new InvalidProgramException("Generic Script Object must be initialized with pairs");
     }
     for (int i = 0; i < args.Length; i += 2)
     {
         SetProperty(ScriptObject.AsString(args[i]), args[i + 1]);
     }
 }
Esempio n. 2
0
 public String AsString(int depth)
 {
     if (depth < 0)
     {
         return("L" + Count);
     }
     return("L" + Count + "{" + String.Join(", ", this.Select((o) =>
     {
         return ScriptObject.AsString(o, depth - 1);
     })) + " }");
 }
Esempio n. 3
0
 public String AsString(int depth)
 {
     if (depth < 0)
     {
         return(this.GetType().Name);
     }
     else
     {
         return("SO{" + String.Join(", ", (this as ScriptObject).ListProperties().Select((o) =>
         {
             return o.ToString() + ": " + ScriptObject.AsString(this.GetProperty(o.ToString()), depth - 1);
         })) + " }");
     }
 }
Esempio n. 4
0
 public void PrepareEnvironment(Engine engine)
 {
     SetupStandardConsoleFunctions(engine);
     if (SetupHost != null)
     {
         SetupHost(engine);
     }
     engine.AddFunction("run-file", "Load and run a file.",
                        (_context, arguments) =>
     {
         var text = System.IO.File.ReadAllText(ScriptObject.AsString(arguments[0]));
         return(engine.EvaluateString(_context, text, ScriptObject.AsString(arguments[0]), false));
     },
                        Arguments.Arg("name"));
 }
Esempio n. 5
0
        private ScriptObject defunImple(Context context, ScriptList arguments, bool addToScope)
        {
            var functionName = ArgumentType <String>(arguments[0]);

            ScriptList argumentInfo = null;

            try
            {
                argumentInfo = ArgumentType <ScriptList>(arguments[1]);
            }
            catch (ScriptError e)
            {
                context.RaiseNewError(e.Message, context.currentNode);
                return(null);
            }

            var functionBody = ArgumentType <ScriptObject>(arguments[2]);

            var newFunction = Function.MakeFunction(
                functionName,
                argumentInfo,
                "Script-defined function",
                functionBody,
                CopyScope(context.Scope));

            if (arguments[3] != null)
            {
                newFunction["@help"] = ScriptObject.AsString(arguments[3]);
            }

            if (addToScope)
            {
                (newFunction["declaration-scope"] as Scope).PushVariable(functionName, newFunction);
            }

            return(newFunction);
        }
Esempio n. 6
0
 private static object SetObjectProperty(Context context, Object obj, String name, Object value)
 {
     if (obj is ScriptObject)
     {
         try
         {
             (obj as ScriptObject)[name] = value;
         }
         catch (Exception e)
         {
             context.RaiseNewError("System Exception: " + e.Message, context.currentNode);
         }
     }
     else
     {
         var field = obj.GetType().GetField(ScriptObject.AsString(name));
         if (field != null)
         {
             field.SetValue(obj, value);
         }
         else
         {
             var prop = obj.GetType().GetProperty(ScriptObject.AsString(name));
             if (prop != null)
             {
                 prop.SetValue(obj, value, null);
             }
             else
             {
                 context.RaiseNewError("Could not find member with name '" + ScriptObject.AsString(name) + "' on object" +
                                       " of type '" + obj.GetType().ToString() + "'", context.currentNode);
             }
         }
     }
     return(value);
 }
Esempio n. 7
0
        private void SetupVariableFunctions()
        {
            AddFunction("var",
                        "name value : Assign value to a variable named [name].", (context, arguments) =>
            {
                if (specialVariables.ContainsKey(ScriptObject.AsString(arguments[0])))
                {
                    context.RaiseNewError("Can't assign to protected variable name.", context.currentNode);
                }
                else
                {
                    try
                    {
                        context.Scope.ChangeVariable(ScriptObject.AsString(arguments[0]), arguments[1]);
                    }
                    catch (Exception e) { context.RaiseNewError(e.Message, context.currentNode); }
                }
                return(arguments[1]);
            },
                        Arguments.Mutator(Arguments.Lazy("name"), "(@identifier value)"),
                        Arguments.Arg("value"));

            AddFunction("let",
                        "^( ^(\"name\" value ?cleanup-code) ^(...) ) code : Create temporary variables, run code. Optional clean-up code for each variable.",
                        (context, arguments) =>
            {
                var variables = ArgumentType <ScriptObject>(arguments[0]);
                if (!String.IsNullOrEmpty(variables.gsp("@prefix"))) /* Raise warning */ } {
                    var code      = ArgumentType <ScriptObject>(arguments[1]);
                    var cleanUp   = new List <LetVariable>();
                    Object result = null;

                    foreach (var item in variables._children)
                    {
                        var sitem = item as ScriptObject;
                        if (sitem._children.Count <= 1 || sitem._children.Count > 3)
                        {
                            context.RaiseNewError("Bad variable definition in let", context.currentNode);
                            goto RUN_CLEANUP;
                        }

                        var nameObject = sitem._child(0) as ScriptObject;
                        var varName    = "";

                        if (nameObject.gsp("@type") == "token")
                        {
                            varName = nameObject.gsp("@token");
                        }
                        else
                        {
                            varName = AutoBind.StringArgument(Evaluate(context, nameObject, true));
                        }
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            goto RUN_CLEANUP;
                        }

                        var varValue = Evaluate(context, sitem._child(1), false);
                        if (context.evaluationState != EvaluationState.Normal)
                        {
                            goto RUN_CLEANUP;
                        }

                        context.Scope.PushVariable(varName, varValue);
                        cleanUp.Add(new LetVariable
                    {
                        name        = varName,
                        cleanupCode = sitem._children.Count == 3 ? sitem._child(2) : null
                    });
                    }

                    result = Evaluate(context, code, true);

                    RUN_CLEANUP:
                    var pre_state = context.evaluationState;
                    foreach (var item in cleanUp)
                    {
                        if (item.cleanupCode != null)
                        {
                            context.evaluationState = EvaluationState.Normal;
                            Evaluate(context, item.cleanupCode, true, true);
                        }
                        context.Scope.PopVariable(item.name);
                    }
                    context.evaluationState = pre_state;
                    return(result);
},
Esempio n. 8
0
        private void SetupFileFunctions()
        {
            var file_functions = new GenericScriptObject();

            file_functions.SetProperty("open", Function.MakeSystemFunction("open",
                                                                           Arguments.Args("file-name", "mode"), "Opens a file",
                                                                           (context, arguments) =>
            {
                var mode = AutoBind.StringArgument(arguments[1]).ToUpperInvariant();
                if (mode == "READ")
                {
                    return(System.IO.File.OpenText(AutoBind.StringArgument(arguments[0])));
                }
                else if (mode == "WRITE")
                {
                    return(System.IO.File.CreateText(AutoBind.StringArgument(arguments[0])));
                }
                else if (mode == "APPEND")
                {
                    return(System.IO.File.AppendText(AutoBind.StringArgument(arguments[0])));
                }
                else
                {
                    context.RaiseNewError("Invalid mode specifier", context.currentNode);
                }
                return(null);
            }));

            file_functions.SetProperty("close", Function.MakeSystemFunction("close",
                                                                            Arguments.Args("file"), "Close a file.",
                                                                            (context, arguments) =>
            {
                if (arguments[0] is System.IO.StreamReader)
                {
                    (arguments[0] as System.IO.StreamReader).Close();
                }
                else if (arguments[0] is System.IO.StreamWriter)
                {
                    (arguments[0] as System.IO.StreamWriter).Close();
                }
                else
                {
                    context.RaiseNewError("Argument is not a file.", context.currentNode);
                }
                return(null);
            }));

            file_functions.SetProperty("read-line", Function.MakeSystemFunction("read-line",
                                                                                Arguments.Args("file"), "Read a line from a file.",
                                                                                (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamReader;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a read file.", context.currentNode);
                    return(null);
                }
                return(file.ReadLine());
            }));

            file_functions.SetProperty("read-all", Function.MakeSystemFunction("read-all",
                                                                               Arguments.Args("file"), "Read all of a file.",
                                                                               (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamReader;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a read file.", context.currentNode);
                    return(null);
                }
                return(file.ReadToEnd());
            }));

            file_functions.SetProperty("write", Function.MakeSystemFunction("write",
                                                                            Arguments.Args("file", "text"), "Write to a file.",
                                                                            (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamWriter;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a write file.", context.currentNode);
                    return(null);
                }
                file.Write(ScriptObject.AsString(arguments[1]));
                return(null);
            }));

            file_functions.SetProperty("more", Function.MakeSystemFunction("more",
                                                                           Arguments.Args("file"), "Is there more to read in this file?",
                                                                           (context, arguments) =>
            {
                var file = arguments[0] as System.IO.StreamReader;
                if (file == null)
                {
                    context.RaiseNewError("Argument is not a read file.", context.currentNode);
                    return(null);
                }
                if (file.EndOfStream)
                {
                    return(null);
                }
                return(true);
            }));

            AddGlobalVariable("file", c => file_functions);
        }
Esempio n. 9
0
        private void SetupStandardLibrary()
        {
            //types.Add("STRING", new TypeString());
            //types.Add("INTEGER", new TypePrimitive(typeof(int), true));
            //types.Add("LIST", new TypeList());
            //types.Add("OBJECT", new TypePrimitive(typeof(ScriptObject), false));
            //types.Add("CODE", new TypePrimitive(typeof(ScriptObject), false));
            //types.Add("IDENTIFIER", new TypeString());
            //types.Add("FUNCTION", new TypePrimitive(typeof(ScriptObject), false));
            //types.Add("ANYTHING", Type.Anything);
            //types.Add("FLOAT", new TypePrimitive(typeof(float), true));

            //foreach (var type in types)
            //    type.Value.Typename = type.Key;

            specialVariables.Add("null", (c) => { return(null); });
            specialVariables.Add("functions", (c) => { return(new ScriptList(functions.Select((pair) => { return pair.Value; }))); });
            specialVariables.Add("true", (c) => { return(true); });
            specialVariables.Add("false", (c) => { return(null); });
            specialVariables.Add("@scope", (c) => { return(c.Scope); });

            //AddFunction("net-module", "Loads a module from a .net assembly",
            //    (context, arguments) =>
            //    {
            //        NetModule.LoadModule(context, this, ScriptObject.AsString(arguments[0]), ScriptObject.AsString(arguments[1]));
            //        return null;
            //    }, "string assembly", "string module");

            AddFunction("@list", "If the argument is a list, great. If not, now it is.",
                        (context, arguments) =>
            {
                if (arguments[0] == null)
                {
                    return(new ScriptList());
                }
                if (arguments[0] is ScriptList)
                {
                    return(arguments[0]);
                }
                return(new ScriptList(arguments[0]));
            },
                        Arguments.Arg("value"));

            AddFunction("@lazy-list", "Mutates a lazy argument into a list. Effectively makes the ^ optional.",
                        (context, arguments) =>
            {
                var node = arguments[0] as ScriptObject;
                if (node == null)
                {
                    return(new ScriptList());
                }
                var r = new ScriptList();
                foreach (var child in node._children)
                {
                    r.Add(Evaluate(context, child));
                }
                return(r);
            }, Arguments.Arg("arg"));

            AddFunction("@identifier", "Mutates a lazy argument. If it's a token, return as a string. If not, evaluate and return as a string.",
                        (context, arguments) =>
            {
                var arg = arguments[0] as ScriptObject;
                if (arg != null && arg.gsp("@type") == "token")
                {
                    return(arg.gsp("@token"));
                }
                return(ScriptObject.AsString(Evaluate(context, arg, true)));
            }, Arguments.Arg("arg"));

            AddFunction("@identifier-if-token", "Mutates a lazy argument. If it's a token, return as a string. If not, evaluate and return.",
                        (context, arguments) =>
            {
                var arg = arguments[0] as ScriptObject;
                if (arg != null && arg.gsp("@type") == "token")
                {
                    return(arg.gsp("@token"));
                }
                return(Evaluate(context, arg, true));
            }, Arguments.Arg("arg"));

            AddFunction("arg", "create an argument", (context, arguments) =>
            {
                if (arguments[0] is ScriptObject)
                {
                    return(arguments[0]);
                }
                else
                {
                    return(Arguments.Arg(ScriptObject.AsString(arguments[0])));
                }
            }, Arguments.Mutator(Arguments.Lazy("name"), "(@identifier value)"));

            AddFunction("arg-lazy", "create a lazy argument", (context, arguments) =>
            {
                if (arguments[0] is ScriptObject)
                {
                    (arguments[0] as ScriptObject)["@lazy"] = true;
                    return(arguments[0]);
                }
                else
                {
                    return(Arguments.Lazy(Arguments.Arg(ScriptObject.AsString(arguments[0]))));
                }
            }, Arguments.Mutator(Arguments.Lazy("name"), "(@identifier-if-token value)"));

            AddFunction("arg-optional", "create an optional argument", (context, arguments) =>
            {
                if (arguments[0] is ScriptObject)
                {
                    (arguments[0] as ScriptObject)["@optional"] = true;
                    return(arguments[0]);
                }
                else
                {
                    return(Arguments.Optional(Arguments.Arg(ScriptObject.AsString(arguments[0]))));
                }
            }, Arguments.Mutator(Arguments.Lazy("name"), "(@identifier-if-token value)"));

            AddFunction("arg-repeat", "create a repeat argument", (context, arguments) =>
            {
                if (arguments[0] is ScriptObject)
                {
                    (arguments[0] as ScriptObject)["@repeat"] = true;
                    return(arguments[0]);
                }
                else
                {
                    return(Arguments.Repeat(Arguments.Arg(ScriptObject.AsString(arguments[0]))));
                }
            }, Arguments.Mutator(Arguments.Lazy("name"), "(@identifier-if-token value)"));

            AddFunction("arg-mutator", "Add a mutator to an argument", (context, arguments) =>
            {
                if (arguments[0] is ScriptObject)
                {
                    (arguments[0] as ScriptObject)["@mutator"] = arguments[1];
                    return(arguments[0]);
                }
                else
                {
                    var r         = Arguments.Arg(ScriptObject.AsString(arguments[0]));
                    r["@mutator"] = arguments[1];
                    return(r);
                }
            }, Arguments.Mutator(Arguments.Lazy("name"), "(@identifier-if-token value)"), Arguments.Lazy("mutator"));

            AddFunction("eval", "Evaluates it's argument.",
                        (context, arguments) =>
            {
                return(Evaluate(context, arguments[0], true));
            },
                        Arguments.Arg("arg"));

            AddFunction("lastarg", "Returns last argument",
                        (context, arguments) =>
            {
                return((arguments[0] as ScriptList).LastOrDefault());
            },
                        Arguments.Repeat("child"));

            AddFunction("nop", "Returns null.",
                        (context, arguments) => { return(null); },
                        Arguments.Optional(Arguments.Repeat("value")));

            AddFunction("coalesce", "B if A is null, A otherwise.",
                        (context, arguments) =>
            {
                if (arguments[0] == null)
                {
                    return(Evaluate(context, arguments[1], true, false));
                }
                else
                {
                    return(arguments[0]);
                }
            },
                        Arguments.Arg("A"), Arguments.Lazy("B"));

            AddFunction("raise-error", "Raises a new error.",
                        (context, arguments) =>
            {
                context.RaiseNewError(MISP.ScriptObject.AsString(arguments[0]), context.currentNode);
                return(null);
            },
                        Arguments.Arg("message"));

            AddFunction("catch-error", "Evaluate and return A unless error generated; if error Evaluate and return B.",
                        (context, arguments) =>
            {
                var result = Evaluate(context, arguments[0], true, false);
                if (context.evaluationState == EvaluationState.UnwindingError)
                {
                    context.evaluationState = EvaluationState.Normal;
                    return(Evaluate(context, arguments[1], true, false));
                }
                return(result);
            },
                        Arguments.Lazy("good"),
                        Arguments.Lazy("bad"));

            AddFunction("break", "Aborts loops and supplies a return value.",
                        (context, arguments) =>
            {
                context.evaluationState = EvaluationState.UnwindingBreak;
                context.breakObject     = arguments[0];
                return(null);
            }, Arguments.Arg("value"));

            AddFunction("reflect", "Examine an object using .net reflection.",
                        (context, arguments) =>
            {
                var stream = new System.IO.StringWriter();
                if (arguments[0] == null)
                {
                    stream.Write("null\n");
                }
                else
                {
                    stream.Write(arguments[0].GetType().Name + "\n");
                    foreach (var field in arguments[0].GetType().GetFields())
                    {
                        stream.Write("field: " + field.Name + " " + field.FieldType.Name + "\n");
                    }
                    foreach (var method in arguments[0].GetType().GetMethods())
                    {
                        stream.Write("method: " + method.Name + " " + method.ReturnType.Name + "\n");
                    }
                }
                return(stream.ToString());
            }, Arguments.Arg("object"));

            AddFunction("lazy-overloads", "Examine all possible overloads of a lazy binding.",
                        (context, arguments) =>
            {
                var binding = arguments[0] as ScriptObject;
                var stream  = new System.IO.StringWriter();
                if (binding.GetProperty("@lazy-reflection") == null)
                {
                    stream.Write("Not a lazy binding object.");
                }
                else
                {
                    var sourceType = binding.GetProperty("@source-type") as System.Type;
                    var methods    = sourceType.GetMethods().Where((m) => m.Name == binding.gsp("@lazy-reflection"));
                    stream.Write("Methods found:\n");
                    foreach (var method in methods)
                    {
                        stream.Write("args: ");
                        stream.Write(String.Join(" ", method.GetParameters().Select((p) => p.ParameterType.Name)));
                        stream.Write("\n");
                    }
                }
                return(stream.ToString());
            }, Arguments.Arg("object"));

            AddFunction("emitt", "Emit in tight-formatting style.",
                        (context, arguments) =>
            {
                return(TightFormat(arguments[0]));
            }, Arguments.Arg("object", "Meant for use with objects generated via AutoBind."));

            AddFunction("emitf", "Emit a function",
                        (context, arguments) =>
            {
                var stream = new System.IO.StringWriter();
                var obj    = arguments[0] as ScriptObject;
                stream.Write("Name: ");
                stream.Write(obj.gsp("@name") + "\nHelp: " + obj.gsp("@help") + "\nArguments: \n");
                foreach (var arg_ in obj["@arguments"] as ScriptList)
                {
                    stream.Write("   ");
                    var arg = arg_ as ScriptObject;
                    //stream.Write((arg["@type"] as Type).Typename + " ");
                    if (arg["@optional"] != null)
                    {
                        stream.Write("?");
                    }
                    if (arg["@repeat"] != null)
                    {
                        stream.Write("+");
                    }
                    if (arg["@lazy"] != null)
                    {
                        stream.Write("*");
                    }
                    stream.Write(arg["@name"] + "  ");
                    if (arg["@mutator"] != null)
                    {
                        Engine.SerializeCode(stream, arg["@mutator"] as ScriptObject);
                    }
                    if (arg["@help"] != null)
                    {
                        stream.Write(" - " + arg["@help"].ToString());
                    }
                    stream.Write("\n");
                }
                stream.Write("\nBody: ");
                if (obj["@function-body"] is ScriptObject)
                {
                    Engine.SerializeCode(stream, obj["@function-body"] as ScriptObject);
                }
                else
                {
                    stream.Write("System");
                }
                stream.Write("\n");
                return(stream.ToString());
            },
                        Arguments.Arg("func", "Must be a function."));

            AddFunction("serialize", "Serialize an object",
                        (context, arguments) =>
            {
                var stream = new System.IO.StringWriter();
                SerializeObject(stream, arguments[0] as ScriptObject);
                return(stream.ToString());
            },
                        Arguments.Arg("object"));


            SetupVariableFunctions();
            SetupObjectFunctions();
            SetupMathFunctions();
            SetupFunctionFunctions();
            SetupBranchingFunctions();
            SetupLoopFunctions();
            SetupListFunctions();
            SetupStringFunctions();
            SetupEncryptionFunctions();
            SetupFileFunctions();
            SetupRegexFunctions();
        }
Esempio n. 10
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. 11
0
 public static string StringArgument(Object obj)
 {
     return(ScriptObject.AsString(obj));
 }
Esempio n. 12
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. 13
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"));
        }