License
Copyright (c) 2006 Jon Watte, All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the .Software.), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies of the Software or substantial portions of the Software.
THE SOFTWARE IS PROVIDED .AS IS., WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Welcome to XNA-Lisp
Welcome to XNA-Lisp, the simple Lisp interpreter for Microsoft XNA.
It is written by Jon Watte and released under the MIT open source license
(as seen above). It is a small Lisp interpreter intended for use for high-
level functions in games written in Microsoft XNA, or other C#-dependent
platforms.
To use it simply build this file as an assembly named LispLib, and add it to
your project. You can then execute text Lisp code through the Interpreter.Eval
function.
You would think that a Lisp library for .NET would use System.Reflection.Emit,
and attempt to be a first clas .NET language. That would be cool, but this
library is targeted towards integration with the XNA framework, and XNA on
on Xbox 360 does not support Reflection.Emit. Thus, this traditional, data
structures driven LISP interpreter, which isn't exactly fast, but is fast
enough for game scripting needs.
This dialect of LISP uses slightly more quoting than your typical LISP.
This allows for additional dynamic coolness, because it allows evaluation
of things like variable name targets. A plan for the next version is also
to add "object" as a native type (implemented as a dictionary/map), and
to use consed pair for object field access: (object.field). The place to
make that determination is marked in the code below. The object itself would
be implemented as a separate Context, sandwiched between global and local
scope. Something will have to be done about "this" as well, and likely a
set-this to complement set-local.
To integrate with a game, the game should subclass LispLib.Interpreter.Function
and override object Apply(Pair args, Context ctx). args will be a list of the
arguments passed to the function call, and ctx will be the context from which
the function is called. (It will typically be the global context -- you don't
inherit local variables from callers).
The implementation in release 1 is only moderately tested, so please feel free
to send any bug reports my way.
xna-lisp at mindcontrol period org (Jon Watte).
Also make sure to check out
http://www.mindcontrol.org/~hplus/xna/lisp.html for
possibly newer updates. This implementation is intended for XNA Game Studio version 1, and ought to
work on Xbox 360 as well as Windows (but has not yet been tested as such).
XNA is a trademark of Microsoft, and no ownership claim is intended or implied.
Download
Sample usage
Here's a very small snippet of code that instantiates the interpreter and
feeds it some text to execute:
Interpreter i = new Interpreter();
Interpreter.Pair a = i.Eval("'(foo (bar baz))") as Interpreter.Pair;
Interpreter.Pair b = i.Eval("'(foo (bar baq))") as Interpreter.Pair;
Console.WriteLine("(listz,listq): {0}", Interpreter.Collate(a, b));
object obj = i.Eval("1 \n \"foo\" \n () \n '() \n '(foo bar baz) \n (set ('foo (lambda (x y) (+ x y))))");
Console.WriteLine("{0}", obj);
obj = i.Eval("(define ('x 3))");
obj = i.Eval("(println \"x = \" x)");
obj = i.Eval("(println \"foo(2,5) = \" (foo 2 5))");
obj = i.Eval("(println (map (lambda (x) (* x 1.1e1)) '(0 1 2 3.3)))");
Feedback
If you have something to say, good or bad, please post a message
here.
Also feel free to browse the same for additional information.