|Release Date:||6th December, 2019|
Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
- Philip Greenspun
Now your BlitzMax applications can have one too!
lispmax is a module for BlitzMax that can parse and execute a lispy scripting
lispmax depends on a couple of sub-modules from sodaware.mod.
Once sodaware.mod is installed, navigate to the
sodaware.mod folder and clone
cd /path/to/blitzmax/mod/sodaware.mod/ git clone https://github.com/sodaware/lispmax.mod.git
A quick example
The following lisp expression adds two numbers together:
(+ 10 20)
To run this within BlitzMax using lispmax, we need to do the following:
- Create and initialize a LispMax object - this contains the environment (functions, variables etc)
- Parse the expression - this converts a string containing lisp code into something LispMax can use
- Evaluate the expression - this is where the magic happens
In practice, it looks a little like this:
Framework brl.basic Import sodaware.lispmax ' Create a new LispMax instance. Local lisp:LispMax = New LispMax ' Load built-in and library functions. lisp.initializeEnvironment() ' Parse and evaluate the expression. Local expression:LispMax_Atom = lisp.parseExpression("(+ 10 20)") Local result:LispMax_Atom = lisp.evaluateExpression(expression) ' Print the result. lisp.printExpression(result)
Running the above example will print
LispMax comes with the following functions built-in:
CAR- Get the first part of a pair
CDR- Get the rest of a pair, excluding the CAR
CONS- Create a new pair
NTH- Return the nth item from a list
<- Less than
>- Greater than
EQ?- Check if two atoms are equal.
NIL?- Predicate to check if an atom is a nil
PAIR?- Predicate to check if an atom is a pair.
LISTP- Predicate to check if an atom is a list.
LIST- Create a list.
STRING-UPCASE- Convert a string to uppercase
STRING-DOWNCASE- Convert a string to lowercase
RAND- Generate a random integer
MILLISECS- Get the number of elapsed milliseconds as an integer
PARSE-INTEGER- Parse a string into an integer
DEBUGLOG- Write text to the BlitzMax debuglog
PRINT-EXPRESSION- Convert an expression to a string and print it
Library functions (which are defined in lispmax code, not BlitzMax code) can be
Most of these functions behave the same as their Common Lisp counterparts.
LispMax supports defining functions in BlitzMax, or in lispmax itself.
Adding native BlitzMax functions
The preferred way to add a native function is to create a type that extends
For example, to add a function that always returns the string "Hello, World":
Type MyFunction extends LispMax_Callable Method call:LispMax_Atom(caller:LispMax, args:LispMax_Atom) Return caller.makeString("Hello, World") End Method End Type lisp.addFunction("my-function", new MyFunction)
Native functions are faster than using lispmax code, but they require the application to be recompiled.
Adding lispmax functions
Evaluate the following code from within the LispMax environment.
(define (my-function) "Hello, World")
Alternatively, functions can be added using a more lispy syntax:
(defun my-function () "Always returns the string Hello World" "Hello, World")
Copyright (C) 2017-2019 Phil Newton
LISPMAX is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
LISPMAX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with LISPMAX. If not, see http://www.gnu.org/licenses/.