Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Thursday, December 5, 2013

Setup Common Lisp Environment

Debian is my main Linux distribution, so usually it is an easy task to setup some programming language development and usage environment. At first, it looks like before for common lisp. I installed sbcl deb package according to the recommendation from cliki (http://www.cliki.net/).

 # apt-get install sbcl sbcl-doc 
 
Then I installed slime and several common lisp deb packages. But clfswm deb package does not work. And I found quicklisp provide much more common lisp systems than debian and it is actively maintained. So I decide to use quicklisp for all common lisp systems, only use sbcl deb package.
It is very easy to install quicklisp (from http://www.quicklisp.org/beta/).

 $ curl -O http://beta.quicklisp.org/quicklisp.lisp
 $ sbcl --load quicklisp.lisp
 * (quicklisp-quickstart:install)
 * (ql:add-to-init-file) 
 
Then you can use (ql:system-apropos) to search systems and install them with (ql:quickload "xxx"). But quicklisp take too long to initialize, so I put quicklisp initialize code in $HOME/.sbclrc into a function (qlsetup) and call it only when I want to install something with quicklisp. To make systems installed with quicklisp avaiable without quicklisp initialization. I add quicklisp software directory into asdf search path. Create a file named $HOME/.config/common-lisp/source-registry.conf.d/33-quicklisp.conf, its contents is:

 (:tree (:home #p"quicklisp/dists/quicklisp/software")) 
 
Then install and configure slime (from https://github.com/quicklisp/quicklisp-slime-helper),

 * (qlsetup) * (ql:quickload "quicklisp-slime-helper") 
 
Add the following to $HOME/.emacs

 (load (expand-file-name "~/quicklisp/slime-helper.el"))
 (setq inferior-lisp-program "sbcl") 
 
Then install hyperspec

 # apt-get install hyperspec 
 

Tuesday, December 3, 2013

Try to use Lisp As My Second Language

Linux kernel programming is my job, so C is my first language. But C is not high level enough for some work such as generating a HTML report from a git repository. So I use python as my second language.
Now I think about using lisp as my second language. Because
  • It is high level enough.
  • It has some interesting features like macro. It is said I can build my own mini-language with it.
  • I want to learn meta-programming and compiler. Lisp macro can be a start point of them.
  • I love Emacs, I need lisp to customize my Emacs.
The two main lisp dialects now are scheme and common lisp. I have learn something about basic scheme (without macro) and common lisp macro (through "On Lisp"). I will start with common lisp, because from google, it seems to be more practical than scheme, which is considered somewhat academic style.

Tuesday, June 23, 2009

Debug bash function interactively


#!/bin/bash

# processing command line parameters
if [ $# -eq 2 ]; then
p1=$1
p2=$2
fi

# setup some environment
export A=a
export B=b

tmpfile=/tmp/myshell-$$-$RANDOM

trap "rm $tmpfile" EXIT

cat <<EOF > $tmpfile
if [ -f /etc/bash.bashrc ]; then
source /etc/bash.bashrc
fi

if [ -f $HOME/.bashrc ]; then
source $HOME/.bashrc
fi

source <shell functions in this file>

export PS1="My Shell$ "
EOF

/bin/bash --rcfile $tmpfile

Shell script parameters - a simpler way


#!/bin/sh

for param in "$@"; do
eval "$param"
done

param1=${param1:-param1}
param2=${param2:-param2}
param3=${param3:-param3}

echo $param1 $param2 $param3

Usage:


param.sh param1=<param1> param2=<param2> param3=<param3>

Saturday, June 13, 2009

Comparison against overflow

Time variables are subject to overflow. So, the comparison statement as follow will return incorrect result if t1 has overflowed and t2 has not overflowed.

unsigned long t1, t2; if (t1 > t2) printf("t1 > t2");

The code as follow can be used to deal with the above issue.

unsigned long t1, t2; if ((long)(t1 - t2) > 0) printf("t1 > t2");

Suppose sizeof(unsigned long) = 4, and t1 < t2, the result of t1 - t2 under the unsigned semantics is (0x100000000 + t1 - t2), because of borrow, if the result < 0x80000000, in signed semantics and complemental code, the result is positive.

Saturday, May 16, 2009

A new method to distinguish between ring buffer full and empty

One design choice for ring buffer implementation is to distinguish
between full buffer and empty buffer. Traditional methods including
waste one entry for full (head + 1 == tail), or use
another flag for full. A new method is implemented as follow:

#define RING_LEN   16
#define RING_LIMIT (2 * RING_LEN - 1)

struct ring_entry
{
...
};

struct ring
{
int head;
int tail;
struct ring_entry entries[RING_LEN];
};

int ring_index(int n)
{
if (n > RING_LEN)
return n - RING_LEN;
else
return n;
};

int ring_get(struct ring *ring, struct ring_entry *entry)
{
/* empty */
if (ring->head == ring->tail)
return 0;

*entry = ring->entries[ring_index(ring->tail)];

ring->tail++;
if (ring->tail > RING_LIMIT)
ring->tail = 0;
return 1;
}

int ring_put(struct ring *ring, struct ring_entry *entry)
{
int ihead, itail;

ihead = ring_index(ring->head);
itail = ring_index(ring->tail);

/* full */
if (ihead == itail && ring->head != ring->tail)
return 0;

ring->entries[ihead] = *entry;

ring->head++;
if (ring->head > RING_LIMIT)
ring->head = 0;
return 1;
}