Пример #1
0
        public InvalidFunctionCall(
            Shell.Types.Function function,
            List <Tuple <int, Shell.Types.IShellData> > arguments
            )
        {
            StringBuilder msg = new StringBuilder();

            msg.Append($"Could not match a definition of Function {function.name} with the following arguments:\n");
            foreach (var arg in arguments)
            {
                msg.Append($"\t {arg.Item1}. {arg.Item2} as {arg.Item2.GetType().Name}\n");
            }
            if (function.definitions.Count == 0)
            {
                msg.Append("No definitions exist");
            }
            else
            {
                msg.Append("The following definitions are available:\n");
            }
            foreach (var lambda in function.definitions)
            {
                msg.Append($"\t {function.name}{lambda}\n");
            }

            Message = msg.ToString();
        }
Пример #2
0
        public Shell.Types.Namespace AsNamespace()
        {
            var system = new Shell.Types.Namespace(typeof(System).Name);

            var libraries = new List <Shell.Types.Namespace>
            {
                (new Shell.Library.Indexable()).AsNamespace(),
                (new Shell.Library.Name()).AsNamespace(),
                (new Shell.Library.Directory()).AsNamespace(),
                (new Shell.Library.Array()).AsNamespace(),
                (new Shell.Library.String()).AsNamespace()
            };

            foreach (var library in libraries)
            {
                library.parent = system;
                system.Set(library.name, library);
            }

            var printfn = new Shell.Types.Function(typeof(Shell.Library.Functions.Print).Name);

            printfn.AddBuiltinLambda(new Shell.Library.Functions.Print());
            system.Set(printfn.name, printfn);

            var printlnnfn = new Shell.Types.Function(typeof(Shell.Library.Functions.PrintLine).Name);

            printlnnfn.AddBuiltinLambda(new Shell.Library.Functions.PrintLine());
            system.Set(printlnnfn.name, printlnnfn);

            system.Set("Path", GetPath());

            var addtopathfn = new Shell.Types.Function(typeof(Shell.Library.Functions.AddToPath).Name);

            addtopathfn.AddBuiltinLambda(new Shell.Library.Functions.AddToPath());
            system.Set(addtopathfn.name, addtopathfn);

            var removefrompathfn = new Shell.Types.Function(typeof(Shell.Library.Functions.RemoveFromPath).Name);

            removefrompathfn.AddBuiltinLambda(new Shell.Library.Functions.RemoveFromPath());
            system.Set(removefrompathfn.name, removefrompathfn);

            var setpathfn = new Shell.Types.Function(typeof(Shell.Library.Functions.SetPath).Name);

            setpathfn.AddBuiltinLambda(new Shell.Library.Functions.SetPath());
            system.Set(setpathfn.name, setpathfn);

            var execfn = new Shell.Types.Function(typeof(Shell.Library.Functions.Exec).Name);

            execfn.AddBuiltinLambda(new Shell.Library.Functions.Exec());
            system.Set(execfn.name, execfn);

            var exitfn = new Shell.Types.Function(typeof(Shell.Library.Functions.Exit).Name);

            exitfn.AddBuiltinLambda(new Shell.Library.Functions.Exit());
            exitfn.AddBuiltinLambda(new Shell.Library.Functions.ExitWithCode());
            system.Set(exitfn.name, exitfn);

            return(system);
        }
Пример #3
0
 /// <summary>
 /// Retrieves the function, creating a new one if necessary
 /// </summary>
 public static Shell.Types.Function Get(State state, string name)
 {
     Shell.Types.Function fn;
     if (state.Names.Exists(name) && state.Names.DefinedAs(name, typeof(Shell.Types.Function)))
     {
         fn = state.Functions.Get(name);
         return(fn);
     }
     fn = new Shell.Types.Function(name);
     state.Functions.Set(name, fn);
     return(fn);
 }
Пример #4
0
        public InvalidFunctionDefinition(
            Shell.Types.Function function,
            Shell.Types.BuiltinLambda definition
            )
        {
            StringBuilder msg = new StringBuilder();

            msg.Append($"A definition of Function {function.name}");
            msg.Append($" with the arguments: {definition} already exists!\n");
            msg.Append("The following definitions are available:\n");
            foreach (var lambda in function.definitions)
            {
                msg.Append($"\t {function.name}{lambda}\n");
            }

            Message = msg.ToString();
        }
Пример #5
0
        public InvalidFunctionDefinition(
            Source src,
            Shell.Types.Function function,
            Shell.Types.Lambda definition
            )
        {
            StringBuilder msg = new StringBuilder();

            msg.Append($"An existing definition of Function {function.name}");
            msg.Append($" conflicts with the definition {definition} at {src}\n");
            msg.Append("The following definitions are available:\n");
            foreach (var lambda in function.definitions)
            {
                msg.Append($"\t {function.name}{lambda}\n");
            }

            Message = msg.ToString();
        }
Пример #6
0
 public void Set(string name, Shell.Types.Function value) => state.CurrentFunctions().Set(name, value);
Пример #7
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);
            }
Пример #8
0
        /// <summary>
        /// namespace : KW_NAMESPACE IDENTIFIER LCURL EOL? namespaced_statement* RCURL ;
        /// namespaced_statement : EOL | namespaced_declaration EOL | namespace EOL | load_namespace EOL ;
        /// namespaced_declaration : IDENTIFIER OP_ASSGN (expression | function) ;
        /// load_namespace : KW_USING STRING (KW_AS IDENTIFIER)? ;
        /// </summary>
        public Namespace(string name, string from, Shell.Generated.ShellParser.Namespace_declarationContext context, Visitor visitor)
        {
            definitionDirectory = from;
            contents            = new Dictionary <string, Types.IShellNamed>();
            this.name           = name;
            if (name == "")
            {
                this.name = context.IDENTIFIER().GetText();
            }
            foreach (var stmt in context.namespaced_statement())
            {
                var nsContext = stmt.namespace_declaration();
                var nsDecl    = stmt.namespaced_declaration();
                var nsLoad    = stmt.load_namespace();

                if (nsContext != null)
                {
                    var ns = new Namespace("", definitionDirectory, nsContext, visitor)
                    {
                        parent = this
                    };
                    Set(ns.name, ns);
                }
                else if (nsDecl != null)
                {
                    string nm = nsDecl.IDENTIFIER().GetText();
                    if (nsDecl.expression() != null)
                    {
                        var value = visitor.VisitExpression(nsDecl.expression());
                        if (value is Shell.Types.IShellData val)
                        {
                            Set(nm, val);
                        }
                        else
                        {
                            throw new Shell.Problems.UnexpectedType(
                                      new Source(nsDecl.expression().Start, nsDecl.expression().Stop),
                                      value, typeof(Shell.Types.IShellData)
                                      );
                        }
                    }
                    else if (nsDecl.function() != null)
                    {
                        if (Exists(nm))
                        {
                            var val = Get(nm);
                            if (val is Shell.Types.Function fn)
                            {
                                fn.AddUserDefinedLambda(nsDecl.function());
                            }
                            else
                            {
                                throw new Shell.Problems.InvalidDefinition(
                                          new Source(nsDecl.function().Start, nsDecl.function().Stop),
                                          nm
                                          );
                            }
                        }
                        else
                        {
                            var fn = new Shell.Types.Function(nm);
                            fn.AddUserDefinedLambda(nsDecl.function());
                            Set(nm, fn);
                        }
                    }
                }
                else if (nsLoad != null)
                {
                    name = Utility.GetString(nsLoad.STRING().GetText(), visitor).contents;
                    string newPath;
                    if (definitionDirectory == "." && name.StartsWith("./"))
                    {
                        newPath = name;
                    }
                    else if (definitionDirectory != "." && name.StartsWith("/"))
                    {
                        newPath = name;
                    }
                    else
                    {
                        if (!(definitionDirectory.EndsWith('/')) && name.StartsWith("./"))
                        {
                            newPath = definitionDirectory + name.Substring(1);
                        }
                        else
                        {
                            newPath = definitionDirectory + name;
                        }
                    }
                    var ns = Utility.LoadNamespace(
                        name,
                        nsLoad.IDENTIFIER() != null ? nsLoad.IDENTIFIER().GetText() : "",
                        visitor
                        );
                    ns.parent = this;
                    Set(ns.name, ns);
                }
            }
        }