Compare commits

..

5 commits

4 changed files with 29 additions and 4 deletions

View file

@ -211,7 +211,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
public override string ToString() { public override string ToString() {
return _value.ToString(); return _value.ToString();
} }
public static Atom FromBase(object o) { public static Expression FromBase(object o) {
switch (o) { switch (o) {
case bool b: case bool b:
return new Boolean(b); return new Boolean(b);
@ -219,6 +219,8 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
return new Integer(i); return new Integer(i);
case string s: case string s:
return new String(s); return new String(s);
case IEnumerable<object> e:
return new List(e.Select(x => Object.FromBase(x)).ToList());
default: default:
return new Object(o); return new Object(o);
} }
@ -267,6 +269,9 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp.Compiler {
public Parser(StringTokenStream tokens) { public Parser(StringTokenStream tokens) {
_sts = tokens; _sts = tokens;
} }
public Parser(string s) {
_sts = StringTokenStream.generate(s);
}
public Expression parse() { public Expression parse() {
Token<string> token = _sts.Get(); Token<string> token = _sts.Get();

View file

@ -65,7 +65,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
return null; return null;
} }
public void Set(string k, Expression v) { public void Set(string k, Expression v) {
Add(k, v); this[k] = v;
} }
public IEnvironment<string, Expression>? Find(string k) { public IEnvironment<string, Expression>? Find(string k) {
@ -76,6 +76,12 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
} }
} }
public class DefaultEnvironment: Environment {
public DefaultEnvironment() {
this["find"] = new Parser("(lambda (item list) (if (= list ()) nil (if (= item (car list)) (car list) (find item (cdr list)))))").parse();
}
}
public class SubEnvironment : Dictionary<string, Expression>, IEnvironment<string, Expression> { public class SubEnvironment : Dictionary<string, Expression>, IEnvironment<string, Expression> {
private IEnvironment<string, Expression> _super; private IEnvironment<string, Expression> _super;
public SubEnvironment(IEnvironment<string, Expression> super) { public SubEnvironment(IEnvironment<string, Expression> super) {
@ -112,6 +118,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
this["<="] = _le; this["<="] = _le;
this["eq?"] = _eq; this["eq?"] = _eq;
this["="] = _eq; this["="] = _eq;
this["!="] = _ne;
this["abs"] = _abs; this["abs"] = _abs;
this["append"] = _append; this["append"] = _append;
this["begin"] = _begin; this["begin"] = _begin;
@ -123,7 +130,6 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
this["haskeys"] = _haskeys; this["haskeys"] = _haskeys;
this["getitems"] = _getitems; this["getitems"] = _getitems;
this["invoke"] = _invoke; this["invoke"] = _invoke;
//this[new Symbol("!=")] = _ne;
} }
private static T _agg<T>(Func<T, T, T> op, IList<T> args) { private static T _agg<T>(Func<T, T, T> op, IList<T> args) {
@ -375,6 +381,11 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
_builtins = builtins; _builtins = builtins;
_builtinsLater = builtinsLater; _builtinsLater = builtinsLater;
} }
public Executor(IEnvironment<string, Expression> environment) {
_environment = environment;
_builtins = new Builtins();
_builtinsLater = new BuiltinsLater();
}
public Executor() { public Executor() {
_environment = new Environment(); _environment = new Environment();
_builtins = new Builtins(); _builtins = new Builtins();
@ -412,6 +423,8 @@ namespace Jellyfin.Plugin.SmartPlaylist.Lisp {
return i; return i;
case Compiler.String s: case Compiler.String s:
return s; return s;
case Compiler.Object o:
return o;
case Procedure p: case Procedure p:
return p; return p;
case List list: case List list:

View file

@ -104,7 +104,7 @@ namespace Jellyfin.Plugin.SmartPlaylist.ScheduledTasks {
private IEnumerable<Guid> FilterPlaylistItems(IEnumerable<BaseItem> items, User user, SmartPlaylistDto smartPlaylist) { private IEnumerable<Guid> FilterPlaylistItems(IEnumerable<BaseItem> items, User user, SmartPlaylistDto smartPlaylist) {
List<Guid> results = new List<Guid>(); List<Guid> results = new List<Guid>();
Expression expression = new Parser(StringTokenStream.generate(smartPlaylist.Program)).parse(); Expression expression = new Parser(StringTokenStream.generate(smartPlaylist.Program)).parse();
Executor executor = new Executor(); Executor executor = new Executor(new DefaultEnvironment());
executor.environment.Set("user", new Lisp_Object(user)); executor.environment.Set("user", new Lisp_Object(user));
foreach (var i in items) { foreach (var i in items) {
executor.environment.Set("item", new Lisp_Object(i)); executor.environment.Set("item", new Lisp_Object(i));

View file

@ -172,5 +172,12 @@ namespace Tests
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)))"); 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"); Assert.Equal(string.Format("{0}", r), "nil");
} }
[Fact]
public static void DefaultEnvironmentTest() {
Executor e = new Executor(new DefaultEnvironment());
Assert.Equal("nil", e.eval("(find 0 (1 2 3 4))").ToString());
Assert.Equal("3", e.eval("(find 3 (1 2 3 4))").ToString());
}
} }
} }