Exemplo n.º 1
0
 private static Scope CopyScope(Scope scope)
 {
     var r = new Scope();
     foreach (var v in scope.variables)
         r.variables.Add(v.Key, new ScriptList(v.Value[v.Value.Count - 1]));
     return r;
 }
Exemplo n.º 2
0
        public void SerializeEnvironment(System.IO.TextWriter to, Scope scope)
        {
            var globalFunctions = new List<ScriptObject>();
            var objects = new List<ObjectRecord>();
            var lambdas = new List<ObjectRecord>();

            //Build list of global non-system functions
            foreach (var func in functions)
            {
                if (Function.IsSystemFunction(func.Value)) continue;
                globalFunctions.Add(func.Value);
            }

            //Filter objects into objects and lambda list
            foreach (var func in globalFunctions)
                EnumerateObject(func["@declaration-scope"] as ScriptObject, globalFunctions, objects, lambdas);
            EnumerateObject(scope, globalFunctions, objects, lambdas);

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

            to.WriteLine("(lastarg");

            //Emit global functions
            foreach (var func in globalFunctions)
                EmitFunction(func, "defun", to, false, 0);

            //Create and emit lambda functions.
            to.WriteLine("(let ^(\n   ^(\"lambdas\" ^(");
            foreach (var func in lambdas)
            {
                to.Write("      ");
                EmitFunction(func.obj, "lambda", to, false, 0);
            }
            to.WriteLine(")\n   )\n   ^(\"objects\" (array " + objects.Count + " (record)))\n)\n(lastarg\n");

            //Set function declaration scopes.
            foreach (var func in globalFunctions)
            {
                to.WriteLine("(set " + func.gsp("@name") + " \"@declaration-scope\" ");
                EmitObjectProperty(to, func["@declaration-scope"], globalFunctions, objects, lambdas, 1);
                to.WriteLine(")\n");
            }

            for (int i = 0; i < lambdas.Count; ++i)
            {
                var func = lambdas[i];
                to.WriteLine("(set (index lambdas " + i + ") \"@declaration-scope\" ");
                EmitObjectProperty(to, func.obj["@declaration-scope"], globalFunctions, objects, lambdas, 1);
                to.WriteLine(")\n");
            }
            //Emit remaining objects
            foreach (var obj in objects)
                EmitObjectRoot(to, obj.obj, globalFunctions, objects, lambdas);

            //Emit footer
            var thisIndex = IndexIn(scope, objects);
            to.Write("(index objects " + thisIndex + "))))");
        }
Exemplo n.º 3
0
 public void PushScope(Scope scope)
 {
     scope.parentScope = Scope; scopeStack.Add(scope);
 }
Exemplo n.º 4
0
 public void ReplaceScope(Scope scope)
 {
     scopeStack.Clear();
     PushScope(scope);
 }
Exemplo n.º 5
0
        private void SetupEnvironmentFunctions(Engine mispEngine)
        {
            mispEngine.AddFunction("save-environment", "", (context, arguments) =>
            {
                Engine.ReportSerializationError = (str) => Write(str + "\n");
                var file = new System.IO.StreamWriter(arguments[0].ToString());
                mispEngine.SerializeEnvironment(file, context.Scope);
                file.Close();
                return true;
            }, Arguments.Arg("file"));

            mispEngine.AddFunction("load-environment", "", (context, arguments) =>
            {
                var newContext = new Context();
                var newEngine = new Engine();

                PrepareEnvironment(newEngine);

                if (arguments[2] != null)
                {
                    newEngine.Evaluate(newContext, arguments[2], true, true);
                    if (newContext.evaluationState == EvaluationState.UnwindingError)
                    {
                        Write("Prime error:\n");
                        Write(MISP.Console.PrettyPrint2(newContext.errorObject, 0));
                        return false;
                    }
                }

                var result = newEngine.EvaluateString(newContext,
                    System.IO.File.ReadAllText(arguments[0].ToString()), arguments[0].ToString()) as ScriptObject;

                if (newContext.evaluationState != EvaluationState.UnwindingError)
                {
                    var environment = AddEnvironment(arguments[1].ToString(), newEngine, newContext);
                    if (environment.name == this.environment.name)
                        this.environment = environment;
                    SetupEnvironmentFunctions(newEngine);
                    var scope = new Scope();
                    foreach (var prop in result.ListProperties())
                        scope.PushVariable(prop as String, result.GetLocalProperty(prop as String));
                    newContext.ReplaceScope(scope);

                    Write("Loaded.\n");
                    return true;
                }
                else
                {
                    Write("Error:\n");
                    Write(MISP.Console.PrettyPrint2(newContext.errorObject, 0));
                    return false;
                }
            }, Arguments.Arg("file"), Arguments.Arg("name"), Arguments.Optional(Arguments.Lazy("prime")));
        }
Exemplo n.º 6
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;
        }
Exemplo n.º 7
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);
        }