diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -50,7 +50,7 @@
 	$(RM) html
 
 
-VERSION = 0.4.9
+VERSION = 0.4.9.1
 DISTDIR = alms-$(VERSION)
 TARBALL = $(DISTDIR).tar.gz
 
diff --git a/TODO b/TODO
new file mode 100644
--- /dev/null
+++ b/TODO
@@ -0,0 +1,6 @@
+ - find a more systematic way to generate and print errors
+ - modify the lexer to get more precise source locations
+ - some termination checking for type operators
+ - remove direct dependency of Parser on Sigma (! patterns)
+ - row types for protocols
+ - type inference
diff --git a/alms.cabal b/alms.cabal
--- a/alms.cabal
+++ b/alms.cabal
@@ -1,5 +1,5 @@
 Name:           alms
-Version:        0.4.9
+Version:        0.4.9.1
 Copyright:      2010, Jesse A. Tov
 Cabal-Version:  >= 1.8
 License:        BSD3
@@ -12,7 +12,8 @@
 Synopsis:       a practical affine language
 Build-type:     Simple
 Data-files:     lib/*.alms examples/*.alms examples/*.sh
-                examples/*.in examples/*.out README Makefile
+                examples/*.in examples/*.out
+                README Makefile
 
 Description:
     Alms is a general-purpose programming language that supports practical
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,44 @@
+## The Cabalized Makefile in the parent directory is the
+## preferred way to build, but sometimes this is convenient.
+
+GHC      = ghc
+EXE      = alms
+EXAMPLES = ../examples
+SRC      = $(HS_SRC) $(HSBOOT_SRC)
+HS_SRC      = *.hs Basis/*.hs Basis/Channel/*.hs Syntax/*.hs Meta/*.hs
+HSBOOT_SRC  = Syntax/*.hs-boot
+
+HCOPTS  = -W -Wall -O0 $(EDITING) $(NOWARN)
+EDITING = -DUSE_READLINE=System.Console.Editline.Readline
+NOWARN  = -fno-warn-unused-do-bind -fno-warn-orphans
+
+$(EXE) $(EXE)-%: $(SRC)
+	$(GHC) -o $@ --make Main.hs $(HCOPTS)
+
+$(EXE)-%:     GHC     = ghc-$*
+$(EXE)-6.8.%: EDITING = -DUSE_READLINE=System.Console.Readline
+
+clean:
+	$(RM) $(HS_SRC:.hs=.hi) $(HS_SRC:.hs=.o)
+	$(RM) $(HSBOOT_SRC:.hs-boot=.hi-boot) $(HSBOOT_SRC:.hs-boot=.o-boot)
+	$(RM) $(EXE) $(EXE)-6.*
+
+wc.%:
+	find .. -name \*."$*" | xargs wc -l
+
+test tests: $(EXE)
+	@$(EXAMPLES)/run-tests.sh ./$(EXE) $(EXAMPLES)
+
+examples: $(EXE)
+	@for i in $(EXAMPLES)/ex*.alms; do \
+	  echo "$$i"; \
+	  head -1 "$$i"; \
+	  ./$(EXE) "$$i"; \
+	  echo; \
+	done
+	@for i in $(EXAMPLES)/*.in; do \
+	  out="`echo $$i | sed 's/\.in$$/.out/'`"; \
+	  src="`echo $$i | sed 's/-[[:digit:]]*\.in$$/.alms/'`"; \
+	  echo "$$i"; \
+	  ./$(EXE) "$$src" < "$$i"; \
+	done
diff --git a/src/Paths.hs b/src/Paths.hs
--- a/src/Paths.hs
+++ b/src/Paths.hs
@@ -33,7 +33,7 @@
 bindir, datadir :: FilePath
 
 bindir     = builddir
-datadir    = dropFileName builddir </> "lib"
+datadir    = dropFileName builddir
 
 getBinDir, getDataDir :: IO FilePath
 getBinDir  = catch (getEnv "alms_bindir") (\_ -> return bindir)
@@ -65,15 +65,18 @@
 almsLibPath = do
   user   <- liftM splitSearchPath (getEnv "ALMS_LIB_PATH")
              `catch` \_ -> return []
-  system <- getDataDir
+  system <- liftM (</> "lib") getDataDir
   build  <- liftM (</> "lib") getBuildDir
   return $ user ++ [ system, build ]
 
+-- | Find an Alms library with the given name
 findAlmsLib :: FilePath -> IO (Maybe FilePath)
 findAlmsLib name = do
   path <- almsLibPath
   findFirstInPath [ name, name <.> "alms" ] path
 
+-- | Find an Alms library with the given name, first looking
+--   relative to the given path
 findAlmsLibRel :: FilePath -> FilePath -> IO (Maybe FilePath)
 findAlmsLibRel name rel = do
   path <- almsLibPath
