diff --git a/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs b/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs index c713d79..340cde0 100644 --- a/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs +++ b/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs @@ -47,6 +47,21 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { this["any"] = e.eval("(lambda (fc l) (apply or (map fc l)))"); this["all"] = e.eval("(lambda (fc l) (apply and (map fc l)))"); this["append"] = e.eval("(lambda (l i) (if (null l) i (cons (car l) (append (cdr l) i))))"); + this["reverse"] = e.eval( + """ + (lambda + (lst) + (let + (rev-helper + (lambda + (l acc) + (if + (null l) + acc + (rev-helper (cdr l) (cons (car l) acc))))) + (rev-helper lst '()))) + """ + ); this["qsort"] = e.eval( """ (lambda @@ -418,7 +433,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { Executor new_e = new Executor(new SubEnvironment(e.environment), e.builtins, e.builtinsLater); foreach (var pair in args.SkipLast(1)) { if (pair is not Cons pair_cons) { - throw new ApplicationException("No expression for let*"); + throw new ApplicationException($"All arguments but the last have to be a list of two items, got {pair}"); } Symbol refname = (Symbol) pair_cons.Item1; Expression exp = ((Cons) pair_cons.Item2).Item1; @@ -431,7 +446,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { List<(Symbol, Expression)> vars = new List<(Symbol, Expression)>(); foreach (var pair in args.SkipLast(1)) { if (pair is not Cons pair_cons) { - throw new ApplicationException(""); + throw new ApplicationException($"All arguments but the last have to be a list of two items, got {pair}"); } Symbol refname = (Symbol) pair_cons.Item1; Expression exp_ = ((Cons) pair_cons.Item2).Item1; @@ -447,7 +462,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { if (args.First() is Cons proc_args_) { proc_args = proc_args_.ToList().Select(x => (Symbol) x); } else if (args.First() == Boolean.FALSE) { proc_args = new List(); } else { - throw new ApplicationException(""); + throw new ApplicationException($"Expexted an argument list, but got {args.First()}"); } return new Procedure(proc_args, args.Skip(1).First(), true); } @@ -456,7 +471,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { if (args.First() is Cons proc_args_) { proc_args = proc_args_.ToList().Select(x => (Symbol) x); } else if (args.First() == Boolean.FALSE) { proc_args = new List(); } else { - throw new ApplicationException(""); + throw new ApplicationException($"Expexted an argument list, but got {args.First()}"); } return new Procedure(proc_args, args.Skip(1).First(), false); }