CTAN
Comprehensive TeX Archive Network

Direc­tory macros/latex/contrib/lisp-on-tex

README.md

LISP on

A LISP in­ter­preter writ­ten only with macros. It works as a style file of . LISP on adopts static scop­ing, dy­namic typ­ing, and ea­ger eval­u­a­tion. We can pro­gram eas­ily with LISP on .

Sum­mary

To use LISP on , you should in­clude the lisp-on-tex pack­age.

\usepackage{lisp-on-tex}

If you do it, you can write LISP codes as a ar­gu­ment of \lispinterp.

\lispintrep{
  (\some \LISP 'codes')
  % example
  (\define (\sum \a \b) (\+ \a \b))
}

In LISP on , a sym­bol is a con­trol se­quence; a string is to­kens sur­rounded by quo­ta­tion marks; and an in­te­ger is a 's in­te­ger us­ing colon pre­fix.

In­stal­la­tion

Put all files into your TEXMF tree.

De­tails

Class Op­tions

Op­tion Name Mean­ing
noGC Never us­ing GC (de­fault)
markGC Us­ing Mark-Sweep GC
GCopt=... Pass­ing op­tion to the GC en­gine

Cur­rently, LISP on sup­ports Mark-Sweep GC. If you want to use it, you should use markGC op­tion. You can also con­trol heap size by us­ing GCopt={heapsize=n} where n is greater than 3000. The de­fault heap size is 32768. For ex­am­ple, the code

\usepackage[markGC, GCopt={heapsize=5000}]{lisp-on-tex}

shows that LISP on uses Mark-Sweep GC and the heap size is 5000.

Syn­tax

Kinds Lit­er­als Ex­am­ples
CONS Cell ( obj ... . obj ), ( obj ... ) (\+ :1 :2)
In­te­ger : 's in­te­ger :42, :"3A
String ' 's bal­anced to­kens ' '\foo{bar}baz'
Sym­bol 's con­trol se­quence \cs
Boolean /t or /f
Nil ()
Skip @ 's skip @12pt plus 34cm
Di­men ! 's di­men !56pt

Func­tions and Spe­cial Forms

Def­i­ni­tion

\define : De­fine a sym­bol.


% symbol form
(\define \foo :42) % ()
\foo % :42
% function form
(\define (\foo \n) (\* \n :2))
(\foo :3) % :6

\defineM : De­fine a mu­ta­ble sym­bol.


\setB : Rewrite a mu­ta­ble sym­bol.


% symbol form
(\defineM \foo :42) % ()
\foo % :42
(\setB \foo 'bar')
\foo % 'bar'

\defmacro : De­fine a macro.


\macroexpand : Ex­pand a macro


(\defmacro (\foo \x) (\list (\quote \bar) \x \x \x)) % ()
(\macroexpand (\quote (\foo :1))) % (\bar :1 :1 :1)

\lambda : Create a func­tion.


% normal form
((\lambda (\x) (\+ \x :2)) :3) % :5
% list form
((\lambda \x \x) :1 :2) % (:1 :2)
% remain argument form
((\lambda (\x . \y) \y) :1 :2 :3) % (:2 :3)

\let : De­fine lo­cal sym­bols.


(\define \x 'foo')
(\let ((\x :4) (\y :3)) (\+ \x \y)) % :7
\x % 'foo'

\letM : De­fine mu­ta­ble lo­cal sym­bols.


(\letM ((\x 'foo'))
  (\begin (\setB \x 'bar') \x)) % 'bar'

\letrec : De­fine lo­cal sym­bols re­cur­sively.


(\letrec
  ((\oddQ (\lambda (\n)
             (\lispif (\= \n :0) /f (\evenQ (\- \n :1)))))
   (\evenQ (\lambda (\n)
             (\lispif (\= \n :0) /t (\oddQ (\- \n :1))))))
   (\oddQ :42)) % /f

Con­trol Flow

\lispif : Branch.


(\lispif /t 'true' 'false') % 'true'
(\lispif /f 'true' 'false') % 'false'

\begin : Ex­e­cute ex­pres­sions.


(\letM ((\x :1)) (\begin (\setB \s 'foo') \x))
% 'foo'

\callOCC : One-shot con­tin­u­a­tion.


(\defineM \x 'unchanged')
(\callOCC (\lambda (\c)
             (\begin (\c '\foo ')
                     (\setB \x 'changed')))) % '\foo '
\x % 'unchanged'
(\callOCC (\lambda (\c) :42)) % :42

String Ma­nip­u­la­tions

\concat : Con­cate­nate to­kens.


(\concat '$' '\foo ' '{bar}' '$') % '$\foo {bar}$'

\intTOstring : Con­vert a in­te­ger to 's to­kens.


(\intTOstring :42) % '42'

\group : Group­ing.


(\group '\some {tokens}') % '{\some {tokens}}'

\ungroup : Un­group­ing.


(\ungroup '{\some {tokens}}') % '\some {tokens}' 

\expand : Ex­pand to­kens.


\newcommand\foo[1]{I got #1!}
\lispinterp{
  (\expand '\foo{Foo}') % 'I got Foo!'
}

Arith­meti­cal Func­tions

\+ : Ad­di­tion.


(\+) % :0
(\+ :1 :2) % :3
(\+ :3 :4 :5) % :12

\- : Sub­trac­tion.


(\- :1) % :-1
(\- :3 :2) % :1
(\- :3 :2 :1) % :0

\* : Mul­ti­pli­ca­tion.


(\*) % :1
(\* :2 :3) % :6
(\* :3 :4 :5) % :60

\/ : Divi­sion.


(\/ 2) % :0 (1/2 -> 0)
(\/ 7 2) % :3

\mod : Mo­dulo.


(\mod :42 :23)  % :19
(\mod :3 :2)    % :1
(\mod :3 :-2)   % :1
(\mod :-3 :2)   % :-1
(\mod :-3 :-2)  % :-1

\>, \<, \geq, \leq : Com­par­i­son.


(\> :3 :2)   % /t
(\< :2 :3)   % /t
(\geq :3 :2) % /t
(\geq :3 :3) % /t
(\leq :2 :3) % /t
(\leq :3 :3) % /t

Some pred­i­cates.


(\isZeroQ :0)    % /t
(\positiveQ :42) % /t
(\negativeQ :-2) % /t

\max : Max­i­mum.


(\max :-10 :-5 :0 :5 :10) % :10

\min : Min­i­mum.


(\min :-10 :-5 :0 :5 :10) % :-10

Log­i­cal func­tions

\and, \or, \not : Log­i­cal and, or, not


(\and /t /t) % /t
(\and /t /f) % /f
(\or /t /t)  % /t
(\or /t /f)  % /t
(\not /t)    % /f

Tra­di­tional LISP Func­tions and Spe­cial Forms

\quote : Quote.


(\quote :42) % :42
(\quote (\+ :1 :2)) % (\+ :1 :2)

\cons, \car, \cdr : CONS, CAR, CDR


(\cons :42 'foo') % (:42 . 'foo')
(\car (\quote (:1 :2))) % :1
(\cdr (\quote (:1 :2))) % (:2)

\list : Create a list


(\list :1 :2 (\+ :3 :4)) % (:1 :2 :7)

\length : Get the length of a list.


(\length ()) % :0
(\length (\list :1 :2 'three')) % :3

\map : Map func­tion.


(\define (\f \x \y \z) (\+ \x \y \z))
(\map \f (\list :1 :2 :3)
         (\list :4 :5 :6)
         (\list :7 :8 :9)) % (:12 :15 :18)

\nth : Get the n-th value of a list (start­ing with 0).


(\nth (\list 'foo' 'bar' 'baz') :1) % 'bar'

\= : Equal­ity.


(\= '42' :42) % /f
(\= :23 :23) % /t
(\= (\cons :1 'foo') (\cons :1 'foo')) % /f
(\= 'foo' 'foo') % /t

\texprint : Con­vert a ob­ject to 's to­kens and out­put it to the doc­u­ment


(\texprint (\concat '\foo' (\group '42'))) % return () andoutput \foo{42}
(\texprint :42) % output 42

\print : (For test) out­put a ob­ject as 's to­kens


(\print ()) % output ()
(\print (\quote \foo)) % output \string\foo
(\print :42) % output :42
(\print 'bar') % output 'bar'

Type pred­i­cates


(\symbolQ (\quote \cs))
(\stringQ 'foo')
(\intQ :42)
(\booleanQ /f)
(\dimenQ !12pt)
(\skipQ @12pt plus 1in minus 3mm)
(\pairQ (\cons :1 :2))
(\nilQ ())
(\funcQ \+)
(\closureQ (\lambda () ()))
(\defmacro (\x) ())
(\macroQ \x)
(\listQ ())
(\listQ (\list :1 :2))
(\atomQ :23)
(\atomQ 'bar')
(\procedureQ \+)
(\procedureQ (\lambda () ()))

Utils

\readLaTeXCounter : Read an in­te­ger from


\setcounter{foo}{42}
\lispinterp{
  (\readLaTeXCounter 'foo') % :42
}

\message : Wrap­per of 's mes­sage


(\message 'output') % output "message" to console and return ()

Others

\read : Read a LISP ex­pres­sion from stdin


(\read) % input :42 and return it

\fgets : Read a string from stdin.


(\fgets) % input \some {tokens} and return '\some {tokens}'

Ad­di­tional Pack­ages

Fixed Point Num­bers

The pack­age lisp-mod-fp­num adds fixed point num­bers to LISP on . Load it by \usepackage:

\usepackage{lisp-on-tex}
\usepackage{lisp-mod-fpnum}

Syn­tax

Kinds Lit­er­als Ex­am­ples
Fixed point num­ber +{fpnum:: num­ber } +{fpnum::1.23}

Func­tions

\fpnumTOstring : Con­vert a fixed point num­ber to a string.


(\fpnumTOstring +{fpnum::1.23}) % '1.23'

\fpplus : Ad­di­tion.


(\fpplus +{fpnum::1.2} +{fpnum::1.4}) % 2.59999 (arithmetical error)

\fpminus : Sub­trac­tion.


(\fpminus +{fpnum::4.2} +{fpnum::2.3}) % 1.9

\fpmul : Mul­ti­pli­ca­tion.


(\fpmul +{fpnum::1.2} +{fpnum::1.4}) % 1.67998

\fplt : Com­par­i­son.


(\fplt +{fpnum::1.2} +{fpnum::2.3}) % /t

Reg­u­lar Ex­pres­sions

The pack­age lisp-mod-l3regex is thin wrap­per of l3regex. Load it by \usepackage:

\usepackage{lisp-on-tex}
\usepackage{lisp-mod-l3regex}

Func­tions

\regMatch, \regMatchResult : Match.


(\regMatch 'hoge+' 'hogeeeeeee') % /t
(\regMatchResult '(\w+)\s+is\s+(\w+)\.' 'He is crazy.')
% ('He is crazy.' 'He' 'crazy')

\regExtract : Ex­trac­tion.


(\regExtract '\w+' 'hello regex world') % ('hello' 'regex' 'world')

\regReplaceAll, \regReplaceOnce : Re­place.


(\regReplaceAll '(\w+?)to(\w+?)' '$\1\c{to}\2$' 'AtoB BtoC') % '$A\to B$ $B\to C$'
(\regReplaceOnce 'foo+' '[\0]' 'foooofooooooo') % '[foooo]fooooooo'

\regSplit : Split.


(\regSplit '/' '/path/to/hogehoge') % ('' 'path' 'to' 'hogehoge')

TODOs

  • Writ­ing user man­ual
  • Add func­tions and spe­cial forms

CHANGELOG

Oct. 25, 2015 : 2.0


  • Add GC
  • Re­fine some spe­cial forms like de­fine
  • Add check­ing #args for some func­tions.
  • Add thin wrap­per of l3regex

Jul. 12, 2014 : 1.3


  • Add one shot con­tin­u­a­tions.
  • Add some arith­meti­cal func­tions.
  • De­bug en­vi­ron­ment.

Jan. 03, 2014 : 1.2


  • Added TUG2013's ex­am­ples.
  • Im­proved the per­for­mance.

Aug. 10, 2013 : 1.1


  • Added le­trec and ex­pand.
  • de­bug

Mar. 04, 2013 : 1.0


Li­cence

Mod­i­fied BSD (see LICENCE)


HAKUTA Shizuya <hak7a3@live.jp>

https://bit­bucket.org/hak7a3/lisp-on-tex/

Down­load the con­tents of this pack­age in one zip archive (395.9k).

lisp-on-tex – Ex­e­cute LISP code in a doc­u­ment

The pack­age pro­vides a LISP in­ter­preter writ­ten us­ing macros; it is pro­vided as a pack­age.

The in­ter­preter static scop­ing, dy­namic typ­ing, and ea­ger eval­u­a­tion.

Pack­agelisp-on-tex
Ver­sion2.0
Li­censeBSD Style Li­cense
Copy­right2012–2014 HAKUTA Shizuya
Main­tainerHakuta Shizuya
Con­tained inTeX Live as lisp-on-tex
MiKTeX as lisp-on-tex
Topics ex­e­cute ‘other types’ of lan­guage
...
Guest Book Sitemap Contact Contact Author