# README
Gmnlisp
The Gmnlisp is a small Lisp implementation in Go. The functions are the subset of ISLisp's. It is developed to embbed to the applications for customizing.
Examples
1. Execute Lisp code in string with parameters
package main
import (
"context"
"fmt"
"os"
"github.com/hymkor/gmnlisp"
)
func main() {
lisp := gmnlisp.New()
lisp = lisp.Let(gmnlisp.Variables{
gmnlisp.NewSymbol("a"): gmnlisp.Integer(1),
gmnlisp.NewSymbol("b"): gmnlisp.Integer(2),
})
value, err := lisp.Interpret(context.TODO(), "(+ a b)")
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
return
}
fmt.Println(value.String())
}
$ go run examples/example1.go
3
gmnlisp.New
returns the new Lisp interpretor instance (*gmnlisp.World
).gmnlisp.NewSymbol
is the symbol constructor.gmnlisp.NewSymbol("a")
always returns the same value no matter how many times you call it.gmnlisp.Variables
is the symbol-map type. It is the alias ofmap[gmnlisp.Symbol]gmnlisp.Node
.Node
is the interface-type that all objects in the Lisp have to implement..Let
makes a new instance including the given namespace.
lisp.Let(gmnlisp.Variables{
gmnlisp.NewSymbol("a"): gmnlisp.Integer(1),
gmnlisp.NewSymbol("b"): gmnlisp.Integer(2),
}).Interpret(context.Background(),"(c)")
is same as (let ((a 1) (b 1)) (c))
2. Execute Lisp-code and give call-back function written in Go
package main
import (
"context"
"fmt"
"os"
"github.com/hymkor/gmnlisp"
)
func sum(ctx context.Context, w *gmnlisp.World, args []gmnlisp.Node) (gmnlisp.Node, error) {
a, err := gmnlisp.ExpectClass[gmnlisp.Integer](ctx, w, args[0])
if err != nil {
return nil, err
}
b, err := gmnlisp.ExpectClass[gmnlisp.Integer](ctx, w, args[1])
if err != nil {
return nil, err
}
return a + b, nil
}
func main() {
lisp := gmnlisp.New()
lisp = lisp.Flet(
gmnlisp.Functions{
gmnlisp.NewSymbol("sum"): &gmnlisp.Function{C: 2, F: sum},
})
result, err := lisp.Interpret(context.Background(), `(sum 1 2)`)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
return
}
fmt.Printf("(sum 1 2)=%v\n", result)
}
$ go run examples/example2.go
(sum 1 2)=3
a,err := gmnlisp.ExpectClass[gmnlisp.Integer](ctx,w,x)
is similar as
a,ok := x.(gmnlisp.Integer)
but, ExpectClass can call error-handler defined by user when x is not Integer
The user defined normal functions have to get the three parameters.
- The 1st: context.Context that is given to the method .Interpret()
- The 2nd: *gmnlisp.World on which the instance runs.
- The 3rd: []gmnlisp.Node the parameters given by caller. They are already evaluated.
gmnlisp.Function
wraps the normal function as Lisp object.
F
: the function itselfC
: when the number of the parameter is not same as this, the error will be raised. If it does not have to be checked, omit it.
To get unevaluted parameters, the function's definition should be as below.
func FUNCNAME(c context.Context,w *World,args Node)(Node,error){...}
- The parameters are given as a list not an array.
- Use
gmnlisp.SpecialF(FUNCNAME)
instead ofgmnlisp.Function{F:FUNCNAME}
Support Types
Type(Lisp) | Type(Go) |
---|---|
t | gmnlisp._TrueType |
nil | gmnlisp._NullType |
<integer> | gmnlisp.Integer == int64 |
<float> | gmnlisp.Float == float64 |
<string> | gmnlisp.String == string |
<symbol> | gmnlisp.Symbol == int |
<cons> | *gmnlisp.Cons == struct{ Car,Cdr: gmnlisp.Node } |
<character> | gmnlisp.Rune == rune |
(keyword) | gmnlisp.Keyword |
(array) | *gmnlisp.Array |
(hashtable) | gmnlisp._Hash == map[gmnlisp.Node]gmnlisp.Node |
gmnlisp.Node
is the root interface.
All objects used in Lisp code have to satisfy it.
gmnlisp.Symbol
is the unique number associated to string.
- string to gmnlisp.Symbol
sbl := gmnlisp.NewSymbol("foo")
- Symbol to string
sbl.String()
Support functions
Gmnlisp's functions are subset of ISLisp.
Items without checkboxes are not standard functions
1 Scope, Conventions and Compliance
2 Classes
3 Scope and Extent
3.1 The lexical Principle
3.2 Scope of Identifiers
3.3 Some Specific Scope Rules
3.4 Extent
- block
- dynamic-let
- flet
- for
- labels
- let
- let*
- tagbody
- with-error-output
- with-open-input-file
- with-open-io-file
- with-open-output-file
- with-standard-input
- with-standard-output
4 Forms and Evaluation
4.1 Forms
4.2 Function Application Forms
4.3 Special Forms
- and
- assure
- block
- case
- case-using
- catch
- class
- cond
- convert
- dynamic
- dynamic-let
- flet
- for
- function
- &rest
- #'FUNCTION
- go
- if
- ignore-errors
- labels
- lambda
- let
- let*
- or
- progn
- quote
- return-from
- setf
- setq
- tagbody
- the
- throw
- unwind-protect
- while
- with-error-output
- with-handler
- with-open-input-file
- with-open-io-file
- with-open-output-file
- with-standard-input
- with-standard-output
4.4 Defining Forms
- defclass
- :initarg
- :initform
- :accessor
- :reader
- :writer
- :boundp
- defconstant (defined same as defglobal for dummy)
- defdynamic
- defgeneric
- defglobal
- defmacro
- defmethod
- defun
4.5 Macro Forms
4.6 The Evaluation Model
4.7 Functions
- functionp
- function
- lambda
- labels
- flet
- apply
- funcall
4.8 Defining Operators
- defconstant
- defglobal
- defdynamic
- defun
5 Predicates
5.1 Boolean Values
- t
- nil
5.2 Class Predicates
- basic-array-p
- basic-array*-p
- basic-vector-p
- characterp
- consp
- floatp
- functionp
- general-array*-p
- general-vector-p
- generic-function-p
- integerp
- listp
- null
- numberp
- streamp
- stringp
- symbolp
- atom OBJ
- evenp OBJ
- minusp OBJ
- oddp OBJ
- plusp OBJ
- zerop OBJ
5.3 Equality
- eq
- eql
- equal
- equalp
5.4 Logical Connectives
- not
- and
- or
6 Control Structure
6.1 Constants
- (quote)
- 'OBJ
6.2 Variables
- setq
- setf
- let
- let*
6.3 Dynamic Variables
- dynamic
- dynamic-let
6.4 Conditional Expressions
- if
- cond
- case
- case-using
- when
- unless
6.5 Sequencing Forms
- progn
- prog1
- prog2
6.6 Iteration
- while
- for
- dolist
- dotimes
6.7 Non-Local Exits
6.7.1 Establishing and Invoking Non-Local Exits
- block
- return-from
- catch
- throw
- tagbody
- go
- return
6.7.2 Assuring Data Consistency during Non-Local Exists
- unwind-protect
7 Objects
7.1 Defining Classes
- defclass
- generic-function-p
7.2 Generic Functions
7.2.1 Defining Generic Functions
- defgeneric
- :rest, &rest
7.2.2 Defining Methods for Generic Functions
- defmethod
- :rest, &rest
7.3 Calling Generic Functions
7.3.4 Calling More General Methods
- call-next-method
- next-method-p
7.4 Object Creation and Initialization
- create
- :initarg
- :initform
- :accessor
- :reader
- :writer
- :boundp
- initialize-object
7.5 Class Enquiry
- class-of
- instancep
- subclassp
- class
8 Macros
- defmacro
- 'form
- `form
- ,@form
9 Declarations and Coercions
- the
- assure
- convert
- (convert OBJ <float>)
- (convert OBJ <integer>)
- (convert OBJ <list>)
- (convert OBJ <string>)
- (convert OBJ <symbol>)
10 Symbol classes
- symbolp
10.2 Symbol Properties
- property
- set-property , setf
- remove-property
10.3 Unnamed Symbols
- gensym
11 Number class
11.1 Number class
- numberp
- parse-number
- =
- /=
- >=
- <=
- >
- <
- +
- *
- -
- reciproca1
- quotient
- max
- min
- abs
- exp
- log
- expt
- sqrt
- sin
- cos
- tan
- atan
- atan2
- sinh
- cosh
- tanh
- atanh
- 1+
- 1-
- incf
- decf
11.2 Float class
- *pi*
- *most-positive-float*
- *most-negative-float*
- floatp
- float
- floor
- ceiling
- truncate
- round
11.3 Integer class
- integerp
- div
- mod
- gcd
- lcm
- isqrt
- rem
- most-postive-fixnum
- most-negative-fixnum
12 Character class
- characterp
- char=
- char/=
- char<
- char>
- char<=
- char>=
13 List class
13.1 Cons
- consp
- cons OBJ
- car
- cdr
- set-car, (setf (car CONS) OBJ)
- set-cdr, (setf (cdr CONS) OBJ)
13.2 Null class
- null
13.3 List operations
- listp
- create-list
- list
- reverse
- nreverse
- append
- member
- mapcar
- mapc
- maplist
- mapl
- mapcan
- mapcon
- assoc
- last
14 Arrays
14.1 Array Classes
14.2 General Arrays
14.3 Array Operations
- basic-array-p
- basic-array*-p
- general-array*-p
- create-array
- aref
- garef
- set-aref , (setf (aref BASIC-ARRAY Z*) OBJ)
- set-garef , (setf (garef BASIC-ARRAY Z*) OBJ)
- array-dimensions
- #(...) , #2a((...) (...)) , #3a(((.. ..))) ...
15 Vector
- basic-vector-p
- general-vector-p
- create-vector
- vector
16 String class
- stringp
- create-string
- string=
- string/=
- string<
- string>
- string>=
- string<=
- char-index
- string-index
- string-append
17 Sequence Functions
- length
- elt
- set-elt, (setf (elt SEQ Z) OBJ)
- subseq
- map-into
18 Stream class
- streamp
- open-stream-p
- input-stream-p
- output-stream-p
- standard-input
- standard-output
- error-output
- with-standard-input
- with-standard-output
- with-error-output
18.1 Streams to files
- open-input-file
- open-output-file
- open-io-file
- with-open-input-file
- with-open-output-file
- with-open-io-file
- close
- finish-output
18.2 Other streams
- create-string-input-stream
- create-string-output-stream
- get-output-stream-string
19 Input and Output
19.1 Argument conventions for input functions
- read
- read-char
- preview-char
- read-line
- stream-ready-p
- format
- format-char
- format-float
- format-fresh-line
- format-integer
- format-object
- format-tab
19.2 Charactoer I/O
19.3 Binary I/O
- read-byte
- write-byte
20 Files
- probe-file
- file-position
- set-file-position
- file-length
21 Condition System
21.1 Condition
21.2 Signaling and handling condtions
21.2.1 Operations relating to condition signaling
- error
- cerror
- signal-condition
21.2.2 Operations relating to condition handling
- ignore-error
- report-condition
- condition-continuable
- continue-condition
- with-handler
21.3 Data associated with condition classes
21.3.1 Arithmetic errors
- arithmetic-error-operation
- arithmetic-error-operands
21.3.2 Domain errors
- domain-error-object
- domain-error-expected-class
21.3.3 Parse errors
- parse-error-string
- parse-error-expected-class
21.3.4 Simple errors
- simple-error-format-string
- simple-error-format-arguments
21.3.5 Stream errors
- stream-error-stream
- undefined-entity-name
- undefined-entity-namespace
21.4 Error identification
- <program-error>
- arity-error
- immutable-binding
- improper-argument-binding
- index-out-of-range
- <storage-exhausted>
- cannot-create-array
- cannot-create-array
- cannot-create-cons
- cannot-create-list
- cannot-create-sequence
- cannot-create-string
- cannot-create-vector
- <parse-error>, cannot-parse-number
- <control-error>, control-error
- <devision-by-zero>, division-by-zero
- <domain-error>
- not-an-input-stream
- not-an-output-stream
- <end-of-stream>, end-of-stream
- <undefined-entity> , undefined-entity
- <unbound-variable> , unbound-variable
- <undefined-function>, undefined-function
22 Miscellaneous
- identify
- get-universal-time
- get-internal-real-time
- get-internal-run-time
- internal-time-units-per-second
Hash-table
(let ((h1 (make-hash-table)))
(setf (gethash 'width h1) 600)
(gethash 'width h1)
(hash-table-count h1)
(remhash 'width h1)
(clrhash h1)
)
Quit
- (exit)
- (quit)
- (abort)
References
Documents (English)
- ISLISP - Wikipedia
- ISLisp Home Page
- www.islisp.info: Home
- Programming Language ISLISP Working Draft 23.0
Documents (Japanese)
Other implementations of ISLisp
Language | Windows | Linux | |
---|---|---|---|
OK!ISLisp | C | Supported | ? |
iris | Go | Supported | Supported |
Easy-ISLisp | C | Supported |