Example #1
0
 public IShellReturnable Execute(ShellBaseVisitor <IShellReturnable> visitor)
 {
     return(visitor.VisitStatement_block(statement_block));
 }
Example #2
0
            /// <summary>
            /// Sets up, executes, and then cleans up function calls.
            /// </summary>
            /// <remark>
            /// Set name to "" if the function is namespaced.
            /// </remark>
            public static Shell.Types.IShellReturnable ExecuteFunction(
                ShellBaseVisitor <Shell.Types.IShellReturnable> visitor,
                State state,
                Shell.Types.Function function,
                List <Tuple <int, Shell.Types.IShellData> > unnamedArgs
                )
            {
                Shell.Types.IShellReturnable returnValue;
                if (unnamedArgs == null)
                {
                    unnamedArgs = new List <Tuple <int, Types.IShellData> >();
                }

                var lambda = function.SelectLambda(unnamedArgs);

                if (lambda == null)
                {
                    throw new Shell.Problems.InvalidFunctionCall(function, unnamedArgs);
                }
                var args = lambda.NameArguments(unnamedArgs);

                string argString = "";

                if (args.Count > 0)
                {
                    var sb = new StringBuilder(" ");
                    for (int i = 0; i < args.Count; i++)
                    {
                        sb.Append($"{args[i].Item2}:{args[i].Item3}");
                        if (i + 1 != args.Count)
                        {
                            sb.Append(" ");
                        }
                    }
                    argString = sb.ToString();
                }

                // pre-setup for state
                state.ENTER_CONTEXT($"{function.name}{argString}");

                // allow the function to call itself through its own identifier
                state.Functions.Set(function.name, function);

                // set up state with arguments in context
                foreach (var arg in args)
                {
                    if (arg.Item3 is Shell.Types.Property prop)
                    {
                        if (lambda is Shell.Types.BuiltinLambda)
                        {
                            state.Variables.Set(arg.Item2, prop);
                        }
                        else
                        {
                            state.Variables.Set(arg.Item2, prop.Value);
                        }
                    }
                    else
                    {
                        state.Variables.Set(arg.Item2, arg.Item3);
                    }
                }

                if (lambda is Shell.Types.UserDefinedLambda udLambda)
                {
                    returnValue = udLambda.Execute(visitor);
                }
                else
                {
                    returnValue = ((Shell.Types.BuiltinLambda)lambda).Execute(state, args);
                }

                //cleanup
                if (state.HasReturned())
                {
                    logger.Debug($"{function.name} returned {returnValue}");
                    state.EndReturn();
                }
                state.EXIT_CONTEXT();

                return(returnValue);
            }