diff --git a/Jellyfin.Plugin.SmartPlaylist/Lisp/Compiler/Parser.cs b/Jellyfin.Plugin.SmartPlaylist/Lisp/Compiler/Parser.cs index baf4531..7dda9c4 100644 --- a/Jellyfin.Plugin.SmartPlaylist/Lisp/Compiler/Parser.cs +++ b/Jellyfin.Plugin.SmartPlaylist/Lisp/Compiler/Parser.cs @@ -244,7 +244,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler { } public override bool Equals(Expression other) { if (other is List other_l) { - return _expressions == other_l._expressions; + return _expressions.SequenceEqual(other_l._expressions); } return false; } diff --git a/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs b/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs index e2a4e74..6d09b4a 100644 --- a/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs +++ b/Jellyfin.Plugin.SmartPlaylist/Lisp/Interpreter.cs @@ -213,20 +213,12 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { throw new ApplicationException(); } private static Expression _eq(IList args) { - Expression first = args[0]; - switch (first) { - case Integer i: - return _cmp((a, b) => a == b, args.Select(x => (Integer) x).ToList()); - } - throw new ApplicationException(); + bool r = _cmp((a, b) => a == b, args); + return new Compiler.Boolean(r); } private static Expression _ne(IList args) { - Expression first = args[0]; - switch (first) { - case Integer i: - return _cmp((a, b) => a != b, args.Select(x => (Integer) x).ToList()); - } - throw new ApplicationException(); + bool r = _cmp((a, b) => a != b, args); + return new Compiler.Boolean(r); } private static Expression _abs(IList args) { Expression first = args[0]; @@ -423,6 +415,9 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp { case Procedure p: return p; case List list: + if (list.expressions.Count == 0) { + return list; + } // do we really want to allow shadowing of builtins? if (list.expressions[0].GetType() == typeof(Symbol)) { return eval(EvalFunction((Symbol) list.expressions[0], list.expressions.Skip(1).ToList())); diff --git a/Tests/Tests.cs b/Tests/Tests.cs index 301a80a..4b13199 100644 --- a/Tests/Tests.cs +++ b/Tests/Tests.cs @@ -125,6 +125,12 @@ namespace Tests e = new Executor().eval("(or nil 4)"); Assert.Equal("4", e.ToString()); + + e = new Executor().eval("(= (1 2) (1 2))"); + Assert.Equal(e.ToString(), "t"); + + e = new Executor().eval("(= (1 2 3) (1 2))"); + Assert.Equal(e.ToString(), "nil"); } [Fact] public static void ObjectTest() { @@ -158,6 +164,13 @@ namespace Tests r = e.eval("(begin (define fact (lambda (n) (if (<= n 1) 1 (* n (fact (- n 1)))))) (fact 10))"); Assert.Equal(string.Format("{0}", r), "3628800"); + + r = e.eval("(begin (define find (lambda (item list) (if (= list ()) nil (if (= item (car list)) (car list) (find item (cdr list)))))) (find 3 (1 2 3 4)))"); + Assert.Equal(string.Format("{0}", r), "3"); + + e = new Executor(); + r = e.eval("(begin (define find (lambda (item list) (if (= list ()) nil (if (= item (car list)) (car list) (find item (cdr list)))))) (find 0 (1 2 3 4)))"); + Assert.Equal(string.Format("{0}", r), "nil"); } } }