random-state.net

Curios, oddities, vagaries and anomalies -- all to amuse the old and delight the young. Lisp hacks sold during intermission.

files/  images/  tmp/  pubkey.asc  rss.xml

Log

...more at Flickr

Quick Notes #
hacking, February 5th 2008

The only valid measurement of code quality: WTFM

Getting Git series will continue later this week, but in the meanwhile I would like to bring to your attention an oft-forgotten output operator in Common Lisp: WRITE. It is perfect for both REPL and code in many cases, since you don't need to bind printer control variables around it -- just pass the ones you care about as keywords. Similarly, you don't have to worry about it munging variables your callers may care about.

Presenting ESRAP 0.1. It is a simple packrat parser for Common Lisp. It's been almost a year since I wrote it, and it seems unlikely that I'll work more on it in near future. In its current state it is neither particularly optimized or polished, nor does it have a great deal of fancy features, but it did what I needed it to do at the time, and I figured someone else might find it a more useful starting point for their own needs then CL-PEG. The feature list reads:

  • dynamic redefinition of nonterminals
  • inline grammars
  • semantic predicates
  • simple introspective facilities

Examples:

(parse '(or "foo" "bar") "foo") ⇒ "foo", NIL

(add-rule 'foo+ (make-instance 'rule 
                 :expression '(+ "foo"))) 
  ⇒ FOO+

(parse 'foo+ "foofoofoo") 
  ⇒ ("foo" "foo" "foo"), NIL

(add-rule 'decimal
           (make-instance 'rule
            :expression '(+ (or "0" "1" "2" "3" 
                                "4" "5" "6" "7" 
                                "8" "9"))
            :transform 
            (lambda (list) 
              (parse-integer (format nil "~{~A~}" 
                                     list)))))
  ⇒ DECIMAL

(parse '(oddp decimal) "123") ⇒ 123, NIL

(handler-case
    (parse '(oddp decimal) "124")
  (error (e)
    (format t "~&oops: ~A~%" e))) ⇒ NIL
; output
oops: Expression (ODDP DECIMAL) failed at 0.

(parse 'foo+ "foofoofoobar" :junk-allowed t) 
  ⇒ ("foo" "foo" "foo"), 9

(parse '(evenp decimal) "123" :junk-allowed t) 
  ⇒ NIL, 0

(add-rule 'foos-or-decimal
          (make-instance 'rule
           :expression '(or foo+ decimal)))
  ⇒ FOOS-OR-DECIMAL

(describe-grammar 'foos-or-decimal) ⇒ NIL
; output
Grammar FOOS-OR-DECIMAL:
   FOOS-OR-DECIMAL <- (OR FOO+ DECIMAL)
   FOO+    <- (+ "foo")
   DECIMAL <- (+ (OR "0" "1" "2" "3" "4" "5" "6" "7" "8" "9"))

Existence of bugs is guaranteed. Licence is zero-clause MIT.

Nikodemus Siivola, <nikodemus@random-state.net>
Fleminginkatu 7 A 14, 00530 Helsinki, Finland
+358 44 2727 526

Hacks

Some of my potentially useful hacks include

  • Anaphora is a collection of anaphoric macros from Hell for Common Lisp.
  • Upstream is a collection of command line tools (clnet, gna, savannah, and sfnet) for pulling Common-lisp.net, Gna!, Savannah, and SourceForge hosted projects from CVS without needing to remember magic incantations.
  • Hyperdoc is a proposal and implementation for hyperdocumentation support in Common Lisp.
  • Linedit is a readline-style input library for Common Lisp.
  • Osicat is a lightweight operating system interface library for Common Lisp.
  • trivial-template.lisp is a really really trivial template hack.
  • Esrap is a simple packrat parser for Common Lisp.

I'm also a developer on SBCL, an open source compiler and runtime system for ANSI Common Lisp, and I run a company called Steel Bank Studio, that provides commercial support and development for SBCL. Yes, Steel Bank Studio is my full-time job. No, I don't think I'll get rich.

Creative Commons License Unless otherwise noted, contents of this website are licensed under a Creative Commons Attribution 2.5 License.