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(); }
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); }
/// <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); }
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(); }
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(); }
public void Set(string name, Shell.Types.Function value) => state.CurrentFunctions().Set(name, value);
/// <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); }
/// <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); } } }