Esempio n. 1
0
        internal static DLR.Expression GenerateIdentifierAssign(
            AplusScope scope, Identifier target, DLR.Expression value, bool isStrand = false, bool needCallback = true)
        {
            Aplus runtime = scope.GetRuntime();
            DLR.Expression result = null;

            if (scope.IsMethod)
            {
                string qualifiedName = target.BuildQualifiedName(runtime.CurrentContext);

                // If the generation is inside of a method
                // check if it has the variablename as function parameter
                DLR.Expression functionParameter = scope.FindIdentifier(target.Name);
                if (functionParameter != null)
                {
                    // Found variable as a function parameter, do a simple assign
                    // the variable is already defined in AST.UserDefFunction
                    return DLR.Expression.Assign(functionParameter, value);
                }

                DLR.Expression functionScopeParam = scope.GetModuleExpression();
                DLR.Expression globalScopeParam = scope.Parent.GetModuleExpression();

                switch (target.Type)
                {
                    case IdentifierType.UnQualifiedName:
                        // Need to check if we are inside an eval block:
                        if (scope.IsEval)
                        {
                            // Code is inside an eval block, we behave slightly differently!

                            #region description about what are we doing in this case

                            //
                            // Check if the variable exists in the function's scope
                            //  |-> Exists: set that variable's value
                            //  |-> otherwise: set the global variable's value
                            //
                            // if(((IDictionary<String, Object>)($FunctionScope).ContainsKey($VARIABLE))
                            // {
                            //      $FunctionScope.$VARIABLE = $VALUE;
                            // }
                            // else
                            // {
                            //      $GlobalScope.$VARIABLE = $VALUE;
                            // }
                            //
                            #endregion

                            result = DLR.Expression.Condition(
                                // Check if the varaible exists in the function scope
                                DLR.Expression.Call(
                                    DLR.Expression.Convert(functionScopeParam, typeof(IDictionary<string, object>)),
                                    typeof(IDictionary<string, object>).GetMethod("ContainsKey"),
                                    DLR.Expression.Constant(target.Name)
                                ),
                                // found the variable in function scope, so assign a value to it
                                DLR.Expression.Block(
                                    needCallback
                                    ? DLR.Expression.Assign(scope.CallbackInfo.QualifiedName, DLR.Expression.Constant(qualifiedName))
                                    : (DLR.Expression)DLR.Expression.Empty(),
                                    DLR.Expression.Dynamic(
                                        runtime.SetMemberBinder(target.Name),
                                        typeof(object),
                                        functionScopeParam,
                                        value
                                    ),
                                    value
                                ),
                                // did NOT found the variable in the function scope
                                // perform the assignment in the global scope
                                BuildGlobalAssignment(scope, runtime, globalScopeParam, target, value, isStrand, needCallback)
                            );

                        }
                        else if (target.IsEnclosed)
                        {
                            result = BuildGlobalAssignment(scope, runtime, globalScopeParam, target, value, isStrand, needCallback);
                        }
                        else
                        {
                            // Simple case, we are inside a user defined function, but not inside an eval block
                            result =
                                DLR.Expression.Block(
                                    needCallback
                                    ? DLR.Expression.Assign(scope.CallbackInfo.QualifiedName, DLR.Expression.Constant(qualifiedName))
                                    : (DLR.Expression)DLR.Expression.Empty(),
                                    DLR.Expression.Dynamic(
                                    runtime.SetMemberBinder(target.Name),
                                    typeof(object),
                                    functionScopeParam,
                                    value
                                    )
                                );
                        }
                        break;

                    case IdentifierType.QualifiedName:
                    case IdentifierType.SystemName:
                    default:
                        // Do an assignment on the global scope
                        result = BuildGlobalAssignment(scope, runtime, globalScopeParam, target, value, isStrand, needCallback);
                        break;
                }
            }
            else
            {
                result = BuildGlobalAssignment(scope, runtime, scope.GetModuleExpression(), target, value, isStrand, needCallback);
            }


            return DLR.Expression.Convert(result, typeof(AType));
        }
Esempio n. 2
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            Aplus runtime = scope.GetRuntime();
            // Default result
            LinkedList<DLR.Expression> codeBlock = new LinkedList<DLR.Expression>();
            codeBlock.AddLast(DLR.Expression.Constant(Utils.ANull()));

            switch (this.command)
            {
                case "$off":
                    Environment.Exit(0);
                    break;

                case "$laod": // Compatibility with original A+ interpreter
                case "$load":
                    IDictionary<string, AType> items =
                        runtime.ContextLoader.FindContextElements(this.argument);

                    if (items.Count > 0)
                    {
                        foreach (KeyValuePair<string, AType> item in items)
                        {
                            codeBlock.AddFirst(
                                VariableHelper.SetVariable(
                                    runtime,
                                    scope.GetModuleExpression(),
                                    new string[] { this.argument, item.Key },
                                    DLR.Expression.Constant(item.Value)
                                )
                            );
                        }
                    }
                    else
                    {
                        string path = Util.GetPath(runtime, ASymbol.Create(this.argument), ".a+");
                        if (File.Exists(path))
                        {
                            // TODO: Save working directory and restore.
                            // Save the previous context.
                            string previousContext = runtime.CurrentContext;

                            // Create the AST from file 
                            // TODO: fix the third function info argument
                            Node fileAST = Parse.LoadFile(path, runtime.LexerMode, null);
                            // And generate the DLR tree
                            codeBlock.AddFirst(fileAST.Generate(scope));

                            // Restore the previous context
                            runtime.CurrentContext = previousContext;
                        }
                        else
                        {
                            codeBlock.Clear();
                            codeBlock.AddFirst(
                                DLR.Expression.Constant(Helpers.BuildString(String.Format("Invalid file: {0}", this.argument)))
                            );
                        }
                    }
                    break;

                case "$mode":
                    if (this.argument != null)
                    {
                        codeBlock.AddFirst(
                            DLR.Expression.Call(
                                scope.RuntimeExpression,
                                typeof(Aplus).GetMethod("SwitchLexerMode"),
                                DLR.Expression.Constant(this.argument)
                             )
                         );
                    }
                    else
                    {
                        codeBlock.Clear();
                        codeBlock.AddFirst(DLR.Expression.Constant(Runtime.Helpers.BuildString(runtime.LexerMode.ToString())));
                    }
                    break;

                case "$cx":
                    if (this.argument != null)
                    {
                        runtime.CurrentContext = this.argument;
                    }
                    else
                    {
                        codeBlock.Clear();
                        codeBlock.AddFirst(
                            DLR.Expression.Call(
                                typeof(Runtime.Helpers).GetMethod("BuildString"),
                                DLR.Expression.Property(scope.RuntimeExpression, "CurrentContext")
                            )
                        );
                    }
                    break;

                case "$cxs":
                    codeBlock.Clear();
                    codeBlock.AddFirst(
                        DLR.Expression.Call(
                            typeof(Runtime.SystemCommands).GetMethod("PrintContexts"),
                            scope.GetModuleExpression()
                        )
                    );
                    break;
                case "$pp":
                    int precision = -1;

                    if (this.argument != null && int.TryParse(this.argument, out precision) && precision >= 0)
                    {
                        runtime.SystemVariables["pp"] = AInteger.Create(precision);
                    }
                    else
                    {
                        codeBlock.Clear();
                        codeBlock.AddFirst(DLR.Expression.Constant(runtime.SystemVariables["pp"]));
                    }
                    break;

                case "$stop":
                    if (this.argument != null)
                    {
                        int stopNumber;
                        if (!int.TryParse(this.argument, out stopNumber) || stopNumber > 2 || stopNumber < 0)
                        {
                            stopNumber = 0;
                        }

                        runtime.SystemVariables["stop"] = AInteger.Create(stopNumber);
                    }
                    else
                    {
                        string resultText;
                        switch (runtime.SystemVariables["stop"].asInteger)
                        {
                            default:
                            case 0:
                                resultText = "0 off";
                                break;
                            case 1:
                                resultText = "1 on [warning]";
                                break;
                            case 2:
                                resultText = "2 trace";
                                break;
                        }

                        codeBlock.Clear();
                        codeBlock.AddFirst(DLR.Expression.Constant(Helpers.BuildString(resultText)));
                    }
                    break;

                default:
                    if (this.command.StartsWith("$>"))
                    {
                        string variable = this.command.Substring(2);

                        if (this.argument == null || this.argument.Length == 0 || variable.Length == 0)
                        {
                            Console.WriteLine("incorrect");
                        }
                        else
                        {
                            codeBlock.AddFirst(
                                DLR.Expression.Call(
                                    typeof(SystemCommands).GetMethod("WriteToFile"),
                                    DLR.Expression.Constant(runtime),
                                    DLR.Expression.Constant(variable),
                                    DLR.Expression.Constant(this.argument)
                                )
                            );
                        }
                    }
                    else
                    {
                        Console.WriteLine("Unknown system command: {0} {1}", this.command, this.argument);
                    }
                    break;
            }

            DLR.Expression result = DLR.Expression.Block(codeBlock);

            return result;
        }
Esempio n. 3
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            DLR.Expression result;
            Aplus          runtime = scope.GetRuntime();

            if (this.Type == IdentifierType.SystemName && runtime.SystemFunctions.ContainsKey(this.Name))
            {
                // Check if the name is a system function's name and we have such system function
                // and return it
                result = DLR.Expression.Constant(runtime.SystemFunctions[this.Name]);

                return(result);
            }

            DLR.Expression variableContainer = scope.GetModuleExpression();
            string[]       contextParts      = CreateContextNames(runtime.CurrentContext);

            // Check if the scope is a method
            if (scope.IsMethod)
            {
                DLR.Expression parentVariableContainer = scope.Parent.GetModuleExpression();

                // Check for variable in method scope
                // (maybe the variable is defined in the method header)
                DLR.Expression localVariable = scope.FindIdentifier(this.variableName);
                if (localVariable != null)
                {
                    // Found a variable defined in the method's header
                    return(localVariable);
                }

                if (this.type == IdentifierType.UnQualifiedName)
                {
                    // 1). we check if the variable exists in the function's scope
                    // 2). check if the variable exits in the current context (error if not found)
                    //
                    // if(((IDictionary<String, Object>)($FunctionScope).ContainsKey($VARIABLE))
                    // {
                    //      return $FunctionScope.$VARIABLE;
                    // }
                    // else
                    // {
                    //      return $GlobalScope.$VARIABLE
                    // }
                    //
                    DLR.Expression getVariable = DLR.Expression.Condition(
                        DLR.Expression.Call(
                            DLR.Expression.Convert(variableContainer, typeof(IDictionary <string, object>)),
                            typeof(IDictionary <string, object>).GetMethod("ContainsKey"),
                            DLR.Expression.Constant(this.variableName)
                            ),
                        // True case:
                        DLR.Expression.Dynamic(
                            runtime.GetMemberBinder(this.variableName),
                            typeof(object),
                            variableContainer
                            ),
                        // False case:
                        BuildGlobalAccessor(scope, runtime, parentVariableContainer, contextParts),
                        // resulting type
                        typeof(object)
                        );

                    result = DLR.Expression.Dynamic(
                        runtime.ConvertBinder(typeof(AType)),
                        typeof(AType),
                        getVariable
                        );

                    return(result);
                }
                else if (this.type == IdentifierType.QualifiedName)
                {
                    // Found a variable like: .var
                    // for this check the parent's variables
                    variableContainer = parentVariableContainer;
                    // Fallback to the non-method case
                }
            }

            result = Tools.CloneMemoryMappedFile(BuildGlobalAccessor(scope, runtime, variableContainer, contextParts));

            return(result);
        }
Esempio n. 4
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            Aplus runtime = scope.GetRuntime();
            // Default result
            LinkedList <DLR.Expression> codeBlock = new LinkedList <DLR.Expression>();

            codeBlock.AddLast(DLR.Expression.Constant(Utils.ANull()));

            switch (this.command)
            {
            case "$off":
                Environment.Exit(0);
                break;

            case "$laod":     // Compatibility with original A+ interpreter
            case "$load":
                IDictionary <string, AType> items =
                    runtime.ContextLoader.FindContextElements(this.argument);

                if (items.Count > 0)
                {
                    foreach (KeyValuePair <string, AType> item in items)
                    {
                        codeBlock.AddFirst(
                            VariableHelper.SetVariable(
                                runtime,
                                scope.GetModuleExpression(),
                                new string[] { this.argument, item.Key },
                                DLR.Expression.Constant(item.Value)
                                )
                            );
                    }
                }
                else
                {
                    string path = Util.GetPath(runtime, ASymbol.Create(this.argument), ".a+");
                    if (File.Exists(path))
                    {
                        // TODO: Save working directory and restore.
                        // Save the previous context.
                        string previousContext = runtime.CurrentContext;

                        // Create the AST from file
                        // TODO: fix the third function info argument
                        Node fileAST = Parse.LoadFile(path, runtime.LexerMode, null);
                        // And generate the DLR tree
                        codeBlock.AddFirst(fileAST.Generate(scope));

                        // Restore the previous context
                        runtime.CurrentContext = previousContext;
                    }
                    else
                    {
                        codeBlock.Clear();
                        codeBlock.AddFirst(
                            DLR.Expression.Constant(Helpers.BuildString(String.Format("Invalid file: {0}", this.argument)))
                            );
                    }
                }
                break;

            case "$mode":
                if (this.argument != null)
                {
                    codeBlock.AddFirst(
                        DLR.Expression.Call(
                            scope.RuntimeExpression,
                            typeof(Aplus).GetMethod("SwitchLexerMode"),
                            DLR.Expression.Constant(this.argument)
                            )
                        );
                }
                else
                {
                    codeBlock.Clear();
                    codeBlock.AddFirst(DLR.Expression.Constant(Runtime.Helpers.BuildString(runtime.LexerMode.ToString())));
                }
                break;

            case "$cx":
                if (this.argument != null)
                {
                    runtime.CurrentContext = this.argument;
                }
                else
                {
                    codeBlock.Clear();
                    codeBlock.AddFirst(
                        DLR.Expression.Call(
                            typeof(Runtime.Helpers).GetMethod("BuildString"),
                            DLR.Expression.Property(scope.RuntimeExpression, "CurrentContext")
                            )
                        );
                }
                break;

            case "$cxs":
                codeBlock.Clear();
                codeBlock.AddFirst(
                    DLR.Expression.Call(
                        typeof(Runtime.SystemCommands).GetMethod("PrintContexts"),
                        scope.GetModuleExpression()
                        )
                    );
                break;

            case "$pp":
                int precision = -1;

                if (this.argument != null && int.TryParse(this.argument, out precision) && precision >= 0)
                {
                    runtime.SystemVariables["pp"] = AInteger.Create(precision);
                }
                else
                {
                    codeBlock.Clear();
                    codeBlock.AddFirst(DLR.Expression.Constant(runtime.SystemVariables["pp"]));
                }
                break;

            case "$stop":
                if (this.argument != null)
                {
                    int stopNumber;
                    if (!int.TryParse(this.argument, out stopNumber) || stopNumber > 2 || stopNumber < 0)
                    {
                        stopNumber = 0;
                    }

                    runtime.SystemVariables["stop"] = AInteger.Create(stopNumber);
                }
                else
                {
                    string resultText;
                    switch (runtime.SystemVariables["stop"].asInteger)
                    {
                    default:
                    case 0:
                        resultText = "0 off";
                        break;

                    case 1:
                        resultText = "1 on [warning]";
                        break;

                    case 2:
                        resultText = "2 trace";
                        break;
                    }

                    codeBlock.Clear();
                    codeBlock.AddFirst(DLR.Expression.Constant(Helpers.BuildString(resultText)));
                }
                break;

            default:
                if (this.command.StartsWith("$>"))
                {
                    string variable = this.command.Substring(2);

                    if (this.argument == null || this.argument.Length == 0 || variable.Length == 0)
                    {
                        Console.WriteLine("incorrect");
                    }
                    else
                    {
                        codeBlock.AddFirst(
                            DLR.Expression.Call(
                                typeof(SystemCommands).GetMethod("WriteToFile"),
                                DLR.Expression.Constant(runtime),
                                DLR.Expression.Constant(variable),
                                DLR.Expression.Constant(this.argument)
                                )
                            );
                    }
                }
                else
                {
                    Console.WriteLine("Unknown system command: {0} {1}", this.command, this.argument);
                }
                break;
            }

            DLR.Expression result = DLR.Expression.Block(codeBlock);

            return(result);
        }
Esempio n. 5
0
        public override DLR.Expression Generate(AplusScope scope)
        {
            DLR.Expression result;
            Aplus runtime = scope.GetRuntime();

            if (this.Type == IdentifierType.SystemName && runtime.SystemFunctions.ContainsKey(this.Name))
            {
                // Check if the name is a system function's name and we have such system function
                // and return it
                result = DLR.Expression.Constant(runtime.SystemFunctions[this.Name]);

                return result;
            }

            DLR.Expression variableContainer = scope.GetModuleExpression();
            string[] contextParts = CreateContextNames(runtime.CurrentContext);

            // Check if the scope is a method
            if (scope.IsMethod)
            {
                DLR.Expression parentVariableContainer = scope.Parent.GetModuleExpression();

                // Check for variable in method scope
                // (maybe the variable is defined in the method header)
                DLR.Expression localVariable = scope.FindIdentifier(this.variableName);
                if (localVariable != null)
                {
                    // Found a variable defined in the method's header
                    return localVariable;
                }

                if (this.type == IdentifierType.UnQualifiedName)
                {
                    // 1). we check if the variable exists in the function's scope
                    // 2). check if the variable exits in the current context (error if not found)
                    //
                    // if(((IDictionary<String, Object>)($FunctionScope).ContainsKey($VARIABLE))
                    // {
                    //      return $FunctionScope.$VARIABLE;
                    // }
                    // else
                    // {
                    //      return $GlobalScope.$VARIABLE
                    // }
                    //
                    DLR.Expression getVariable = DLR.Expression.Condition(
                        DLR.Expression.Call(
                            DLR.Expression.Convert(variableContainer, typeof(IDictionary<string, object>)),
                            typeof(IDictionary<string, object>).GetMethod("ContainsKey"),
                            DLR.Expression.Constant(this.variableName)
                        ),
                        // True case:
                        DLR.Expression.Dynamic(
                            runtime.GetMemberBinder(this.variableName),
                            typeof(object),
                            variableContainer
                        ),
                        // False case:
                        BuildGlobalAccessor(scope, runtime, parentVariableContainer, contextParts),
                        // resulting type
                        typeof(object)
                    );

                    result = DLR.Expression.Dynamic(
                        runtime.ConvertBinder(typeof(AType)),
                        typeof(AType),
                        getVariable
                    );

                    return result;
                }
                else if (this.type == IdentifierType.QualifiedName)
                {
                    // Found a variable like: .var
                    // for this check the parent's variables
                    variableContainer = parentVariableContainer;
                    // Fallback to the non-method case
                }

            }

            result = Tools.CloneMemoryMappedFile(BuildGlobalAccessor(scope, runtime, variableContainer, contextParts));

            return result;
        }