diff --git a/Epic/Bytecode.lhs b/Epic/Bytecode.lhs
--- a/Epic/Bytecode.lhs
+++ b/Epic/Bytecode.lhs
@@ -4,9 +4,11 @@
 > import List
 
 > import Epic.Language
+> import Debug.Trace
 
 > type Local = Int
 > type TmpVar = Int
+> type StrVar = Int
 
 Register based - most operations do an action, then put the result in a
 'TmpVar' which is basically a numbered register. There are infinite registers
@@ -19,27 +21,40 @@
 >             | FOREIGN Type TmpVar String [(TmpVar, Type)]
 >             | VAR TmpVar Local
 >             | ASSIGN Local TmpVar
+>             | TMPASSIGN TmpVar TmpVar
+>             | NOASSIGN Local TmpVar -- No-op, but flag not to eval the register
 >             | CON TmpVar Tag [TmpVar]
 >             | UNIT TmpVar
+>             | UNUSED TmpVar
 >             | INT TmpVar Int
 >             | BIGINT TmpVar Integer
 >             | FLOAT TmpVar Float
 >             | BIGFLOAT TmpVar Double
->             | STRING TmpVar String
+>             | STRING TmpVar StrVar
 >             | PROJ TmpVar TmpVar Int -- project into a register
 >             | PROJVAR Local TmpVar Int -- project into a local variable
 >               -- each case branch records which tag it's code for
 >             | CASE TmpVar [(Int, Bytecode)] (Maybe Bytecode)
+>             | INTCASE TmpVar [(Int, Bytecode)] (Maybe Bytecode)
 >             | IF TmpVar Bytecode Bytecode
 >             | OP TmpVar Op TmpVar TmpVar
 >             | LOCALS Int -- allocate space for locals
 >             | TMPS Int -- declare temporary variables
->             | EVAL TmpVar
+>             | CONSTS [String] -- declare constants
+>             | LABEL Int
+>             | WHILE Bytecode Bytecode
+>             | WHILEACC Bytecode TmpVar Bytecode
+>             | BREAKFALSE TmpVar
+>             | JFALSE TmpVar Int
+>             | JUMP Int
+>             | EVAL TmpVar Bool -- Bool is True if update required
+>             | EVALINT TmpVar Bool -- Bool is True if update required
 >             -- | LET TmpVar Local TmpVar
 >             | RETURN TmpVar
 >             | DRETURN -- return dummy value
 >             | ERROR String -- Fatal error, exit
 >             | TRACE String [TmpVar]
+>             | COMMENT String -- handy for adding notes to output
 >   deriving Show
 
 > type Bytecode = [ByteOp]
@@ -49,33 +64,61 @@
 
 > data CompileState = CS { arg_types :: [Type],
 >                          num_locals :: Int,
->                          next_tmp :: Int }
+>                          next_tmp :: Int,
+>                          string_pool :: [String],
+>                          max_tmp :: Int,
+>                          next_label :: Int }
 
 > compile :: Context -> Name -> Func -> FunCode
-> compile ctxt fname fn@(Bind args locals def) = 
->     let cs = (CS (map snd args) (length args) 1)
->         code = evalState (scompile ctxt fname fn) cs in
->         Code (map snd args) code
+> compile ctxt fname fn@(Bind args locals def flags) = 
+>     let cs = (CS (map snd args) (length args) 1 [] 1 0)
+>         code = evalState (scompile ctxt fname fn) cs 
+>         opt = peephole' evalled code in
+>               Code (map snd args) opt
+>   where evalled | elem Strict flags = [] --take locals [0..]
+>                 | otherwise = []
 
 > data TailCall = Tail | Middle
 
 > scompile :: Context -> Name -> Func -> State CompileState Bytecode
-> scompile ctxt fname (Bind args locals def) = 
+> scompile ctxt fname (Bind args locals def _) = 
 >     do -- put (CS args (length args) 1)
->        code <- ecomp Tail def 0 (length args)
+>        code <- ecomp (False, True) Tail def 0 (length args)
 >        cs <- get
 >        return $ (LOCALS (num_locals cs)):
 >                 (TRACE (show fname) [0..(length args)-1]):
->                 (TMPS (next_tmp cs)):code ++[EVAL 0, RETURN 0]
+>                 (TMPS (max_tmp cs)):(CONSTS (string_pool cs)):code ++
+>                   [EVAL 0 True, RETURN 0]
 
 >   where
 
 >     new_tmp :: State CompileState Int
 >     new_tmp = do cs <- get
 >                  let reg' = next_tmp cs
->                  put (cs { next_tmp = reg'+1 } )
+>                  let max = if (reg'+ 1) > max_tmp cs then reg'+1 else max_tmp cs
+>                  put (cs { next_tmp = reg'+1, max_tmp = max } )
 >                  return reg'
 
+>     set_tmp :: Int -> State CompileState ()
+>     set_tmp n = do cs <- get
+>                    put (cs { next_tmp = n } )
+
+>     get_tmp :: State CompileState Int
+>     get_tmp = do cs <- get
+>                  return $ next_tmp cs
+
+>     new_label :: State CompileState Int
+>     new_label = do cs <- get
+>                    let reg' = next_label cs
+>                    put (cs { next_label = reg'+1 } )
+>                    return reg'
+
+>     new_string :: String -> State CompileState Int
+>     new_string s = do cs <- get
+>                       let reg' = string_pool cs
+>                       put (cs { string_pool = reg'++[s] } )
+>                       return (length reg')
+
 Add some locals, return de Bruijn level of first new one.
 
 >     new_locals :: Int -> State CompileState Int
@@ -92,61 +135,125 @@
 particular, when we project from a data structure we store it in the right
 place.
 
->     ecomp :: TailCall -> Expr -> TmpVar -> Int -> 
+>     ecomp :: (Bool, Bool) -> TailCall -> Expr -> TmpVar -> Int -> 
 >              State CompileState Bytecode
->     ecomp tcall (V v) reg vs = 
+>     ecomp lazy tcall (V v) reg vs = 
 >         do return [VAR reg v]
->     ecomp tcall (R x) reg vs = acomp tcall False (R x) [] reg vs
->     ecomp tcall (App f as) reg vs = acomp tcall False f as reg vs
->     ecomp tcall (LazyApp f as) reg vs = acomp tcall True f as reg vs
->     ecomp tcall (Con t as) reg vs = 
->         do (argcode, argregs) <- ecomps as vs
+>     ecomp lazy tcall (R x) reg vs = do
+>       savetmp <- get_tmp
+>       code <- acomp tcall lazy (R x) [] reg vs
+>       set_tmp savetmp
+>       return code
+>     ecomp lazy tcall (App f as) reg vs = do
+>       savetmp <- get_tmp
+>       code <- acomp tcall lazy f as reg vs
+>       set_tmp savetmp
+>       return code
+>     ecomp (lazy, update) tcall (Lazy e) reg vs = ecomp (True, update) tcall e reg vs
+>     ecomp (lazy, update) tcall (Effect e) reg vs = 
+>         do ecode <- ecomp (lazy, False) tcall e reg vs
+>            return (ecode ++ [EVAL reg False])
+>     ecomp lazy tcall (Con t as) reg vs = 
+>         do (argcode, argregs) <- ecomps lazy as vs
 >            return $ argcode ++ [CON reg t argregs]
->     ecomp tcall (Proj con i) reg vs =
+>     ecomp lazy tcall (Proj con i) reg vs =
 >         do reg' <- new_tmp
->            concode <- ecomp Middle con reg' vs
->            return [PROJ reg reg' i]
->     ecomp tcall (Const c) reg vs = ccomp c reg
->     ecomp tcall (Case scrutinee alts) reg vs =
+>            concode <- ecomp lazy Middle con reg' vs
+>            return $ concode ++ [EVAL reg' (snd lazy), PROJ reg reg' i]
+>     ecomp lazy tcall (Const c) reg vs = ccomp c reg
+>     ecomp lazy tcall (Case scrutinee alts) reg vs =
 >         do screg <- new_tmp
->            sccode <- ecomp Middle scrutinee screg vs
->            (altcode, def) <- altcomps tcall (order alts) screg reg vs
->            return $ sccode ++ [EVAL screg, CASE screg altcode def]
->     ecomp tcall (If a t e) reg vs =
+>            sccode <- ecomp lazy Middle scrutinee screg vs
+>            (altcode, def) <- altcomps lazy tcall (order alts) screg reg vs
+>            return $ sccode ++ [EVAL screg (snd lazy), (caseop alts) screg altcode def]
+>     ecomp lazy tcall (If a t e) reg vs =
 >         do areg <- new_tmp
->            acode <- ecomp Middle a areg vs
->            tcode <- ecomp tcall t reg vs
->            ecode <- ecomp tcall e reg vs
->            return $ acode ++ [EVAL areg, IF areg tcode ecode]
->     ecomp tcall (Op op l r) reg vs =
->         do lreg <- new_tmp
+>            acode <- ecomp lazy Middle a areg vs
+>            tcode <- ecomp lazy tcall t reg vs
+>            ecode <- ecomp lazy tcall e reg vs
+>            return $ acode ++ [EVAL areg (snd lazy), IF areg tcode ecode]
+>     ecomp lazy tcall (While t b) reg vs =
+>         do savetmp <- get_tmp
+>            start <- new_label
+>            end <- new_label
+>            treg <- new_tmp
+>            tcode <- ecomp lazy Middle t treg vs
+>            bcode <- ecomp lazy Middle b reg vs
+>            set_tmp savetmp
+>            return $ [WHILE (tcode++[EVAL treg False, BREAKFALSE treg]) 
+>                            (bcode++[EVAL reg False])]
+
+>     ecomp lazy tcall (WhileAcc t acc b) reg vs =
+>         do savetmp <- get_tmp
+>            start <- new_label
+>            end <- new_label
+>            treg <- new_tmp
+>            areg <- new_tmp
+>            tcode <- ecomp lazy Middle t treg vs
+>            acode <- ecomp lazy Middle acc areg vs
+>            bcode <- ecomp lazy Middle b reg vs
+>            set_tmp savetmp
+>            return $ acode ++
+>                     [WHILE (tcode++[EVAL treg False, BREAKFALSE treg]) 
+>                            (bcode++[ADDARGS areg reg [areg], EVAL areg False])]
+>                     ++ [TMPASSIGN reg areg]
+> 
+
+(LABEL start):tcode ++ 
+                     (EVAL treg False):(JFALSE treg end):bcode ++
+                     [EVAL reg False, JUMP start, LABEL end]
+
+>     ecomp lazy tcall (Op op l r) reg vs =
+>         do savetmp <- get_tmp
+>            lreg <- new_tmp
 >            rreg <- new_tmp
->            lcode <- ecomp Middle l lreg vs
->            rcode <- ecomp Middle r rreg vs
->            return $ lcode ++ [EVAL lreg] ++ 
->                     rcode ++ [EVAL rreg, OP reg op lreg rreg]
->     ecomp tcall (Let nm ty val scope) reg vs =
+>            lcode <- ecomp lazy Middle l lreg vs
+>            rcode <- ecomp lazy Middle r rreg vs
+>            set_tmp savetmp
+>            return $ lcode ++ [EVAL lreg (snd lazy)] ++ 
+>                     rcode ++ [EVAL rreg (snd lazy), OP reg op lreg rreg]
+>     ecomp lazy tcall (Let nm ty val scope) reg vs =
 >         do loc <- new_locals 1
 >            reg' <- new_tmp
->            valcode <- ecomp Middle val reg' vs
->            scopecode <- ecomp tcall scope reg (vs+1)
->            return $ valcode ++ (EVAL reg'):(ASSIGN vs reg'):scopecode
->     ecomp tcall (Error str) reg vs = return [ERROR str]
->     ecomp tcall Impossible reg vs = return [ERROR "The impossible happened."]
->     ecomp tcall (ForeignCall ty fn argtypes) reg vs = do
+>            valcode <- ecomp lazy Middle val reg' vs
+>            scopecode <- ecomp lazy tcall scope reg (vs+1)
+>            let assigncode = case ty of
+>                               TyUnit -> [ASSIGN vs reg']
+>                               _ -> [ASSIGN vs reg']
+>            return $ valcode ++ assigncode ++ scopecode
+>     ecomp lazy tcall (Error str) reg vs = return [ERROR str]
+>     ecomp lazy tcall Impossible reg vs = return [ERROR "The impossible happened."]
+>     ecomp lazy tcall (ForeignCall ty fn argtypes) reg vs = do
+>           savetmp <- get_tmp
 >           let (args,types) = unzip argtypes
->           (argcode, argregs) <- ecomps args vs
->           let evalcode = map EVAL argregs
->           return $ argcode ++ evalcode ++ [FOREIGN ty reg fn (zip argregs types)]
+>           (argcode, argregs) <- ecompsEv lazy args vs
+>           -- let evalcode = if (snd lazy) then [] else map (\x -> EVAL x (snd lazy)) argregs
+>           set_tmp savetmp
+>           return $ argcode ++ [FOREIGN ty reg fn (zip argregs types)]
+>     ecomp lazy tcall (LazyForeignCall ty fn argtypes) reg vs = do
+>           savetmp <- get_tmp
+>           let (args,types) = unzip argtypes
+>           (argcode, argregs) <- ecomps lazy args vs
+>           set_tmp savetmp
+>           return $ argcode ++ [FOREIGN ty reg fn (zip argregs types)]
 
->     ecomps :: [Expr] -> Int -> State CompileState (Bytecode, [TmpVar])
->     ecomps e vs = ecomps' [] [] e vs
->     ecomps' code tmps [] vs = return (code, tmps)
->     ecomps' code tmps (e:es) vs =
+>     ecomps :: (Bool, Bool) -> [Expr] -> Int -> State CompileState (Bytecode, [TmpVar])
+>     ecomps lazy e vs = ecomps' lazy [] [] e vs
+>     ecomps' lazy code tmps [] vs = return (code, tmps)
+>     ecomps' lazy code tmps (e:es) vs =
 >         do reg <- new_tmp
->            ecode <- ecomp Middle e reg vs
->            ecomps' (code++ecode) (tmps++[reg]) es vs
+>            ecode <- ecomp lazy Middle e reg vs
+>            ecomps' lazy (code++ecode) (tmps++[reg]) es vs
 
+>     ecompsEv :: (Bool, Bool) -> [Expr] -> Int -> State CompileState (Bytecode, [TmpVar])
+>     ecompsEv lazy e vs = ecompsEv' lazy [] [] e vs
+>     ecompsEv' lazy code tmps [] vs = return (code, tmps)
+>     ecompsEv' lazy code tmps (e:es) vs =
+>         do reg <- new_tmp
+>            ecode <- ecomp lazy Middle e reg vs
+>            let evcode = if (snd lazy) then [] else [EVAL reg (snd lazy)]
+>            ecompsEv' lazy (code++ecode++evcode) (tmps++[reg]) es vs
+
 Compile case alternatives.
 
 >     order :: [CaseAlt] -> [CaseAlt]
@@ -163,12 +270,12 @@
 >     errors x end | x == end = []
 >                  | otherwise = (Alt x [] Impossible):(errors (x+1) end)
 
->     altcomps :: TailCall -> [CaseAlt] -> TmpVar -> TmpVar -> Int ->
+>     altcomps :: (Bool, Bool) -> TailCall -> [CaseAlt] -> TmpVar -> TmpVar -> Int ->
 >                 State CompileState ([(Int, Bytecode)], Maybe Bytecode)
->     altcomps tc [] _ _ vs = return ([], Nothing)
->     altcomps tc (a:as) scrutinee reg vs = 
->         do (t,acode) <- altcomp tc a scrutinee reg vs
->            (ascode, def) <- altcomps tc as scrutinee reg vs
+>     altcomps lazy tc [] _ _ vs = return ([], Nothing)
+>     altcomps lazy tc (a:as) scrutinee reg vs = 
+>         do (t,acode) <- altcomp lazy tc a scrutinee reg vs
+>            (ascode, def) <- altcomps lazy tc as scrutinee reg vs
 >            if (t<0) then return (ascode, Just acode)
 >                     else return ((t,acode):ascode, def)
 
@@ -177,18 +284,24 @@
 
 Return the tag and the code - tag is -1 for default case.
 
->     altcomp :: TailCall -> CaseAlt -> TmpVar -> TmpVar -> Int ->
+>     altcomp :: (Bool, Bool) -> TailCall -> CaseAlt -> TmpVar -> TmpVar -> Int ->
 >                State CompileState (Int, Bytecode)
->     altcomp tc (Alt tag nmargs expr) scrutinee reg vs =
+>     altcomp lazy tc (Alt tag nmargs expr) scrutinee reg vs =
 >         do let args = map snd nmargs
 >            local <- new_locals (length args)
 >            projcode <- project args scrutinee vs 0
->            exprcode <- ecomp tc expr reg (vs+(length args))
+>            exprcode <- ecomp lazy tc expr reg (vs+(length args))
 >            return (tag, projcode++exprcode)
->     altcomp tc (DefaultCase expr) scrutinee reg vs =
->         do exprcode <- ecomp tc expr reg vs
+>     altcomp lazy tc (ConstAlt tag expr) scrutinee reg vs =
+>         do exprcode <- ecomp lazy tc expr reg (vs+(length args))
+>            return (tag, exprcode)
+>     altcomp lazy tc (DefaultCase expr) scrutinee reg vs =
+>         do exprcode <- ecomp lazy tc expr reg vs
 >            return (-1,exprcode)
 
+>     caseop ((ConstAlt _ _):_) = INTCASE
+>     caseop _ = CASE
+
 >     project [] _ _ _ = return []
 >     project (_:as) scr loc arg = 
 >         do let acode = PROJVAR loc scr arg
@@ -197,21 +310,23 @@
 
 Compile an application of a function to arguments
 
->     acomp :: TailCall -> Bool -> Expr -> [Expr] -> TmpVar -> Int ->
+>     acomp :: TailCall -> (Bool, Bool) -> Expr -> [Expr] -> TmpVar -> Int ->
 >              State CompileState Bytecode
 >     acomp tc lazy (R x) args reg vs
->           | lazy == False && arity x ctxt == length args =
->               do (argcode, argregs) <- ecomps args vs
->                  return $ argcode {- ++ map EVAL argregs -} ++ [(tcall tc) reg x argregs]
+>           | fst lazy == False && arity x ctxt == length args =
+>               do (argcode, argregs) <- ecomps lazy args vs
+>                  return $ argcode {- ++ map (\x -> EVAL x (snd lazy)) argregs -}
+>                              ++ [(tcall tc) reg x argregs]
 >           | otherwise =
->               do (argcode, argregs) <- ecomps args vs
->                  return $ argcode ++ [THUNK reg (arity x ctxt) x argregs]
+>               do (argcode, argregs) <- ecomps lazy args vs
+>                  return $ argcode ++ [THUNK reg (arity x ctxt) x argregs] ++ 
+>                           if (not (fst lazy)) then [EVAL reg (snd lazy)] else []
 >      where tcall Tail = TAILCALL
 >            tcall Middle = CALL
->     acomp _ _ f args reg vs
->           = do (argcode, argregs) <- ecomps args vs
->                reg' <- new_tmp
->                fcode <- ecomp Middle f reg' vs
+>     acomp _ lazy f args reg vs
+>           = do reg' <- new_tmp
+>                (argcode, argregs) <- ecomps lazy args vs
+>                fcode <- ecomp lazy Middle f reg' vs
 >                return $ fcode ++ argcode ++ [ADDARGS reg reg' argregs]
 
 >     ccomp (MkInt i) reg = return [INT reg i]
@@ -220,6 +335,44 @@
 >     ccomp (MkFloat f) reg = return [FLOAT reg f]
 >     ccomp (MkBigFloat f) reg = return [BIGFLOAT reg f]
 >     ccomp (MkBool b) reg = return [INT reg (if b then 1 else 0)]
->     ccomp (MkString s) reg = return [STRING reg s]
+>     ccomp (MkString s) reg = do sreg <- new_string s
+>                                 return [STRING reg sreg]
 >     ccomp (MkUnit) reg = return [UNIT reg]
+>     ccomp MkUnused reg = return [UNUSED reg]
 
+
+
+> peephole :: Bytecode -> Bytecode
+> peephole = peephole' []
+
+> peephole' ev [] = []
+> peephole' ev ((CASE t cases mcs):cs)
+>    = CASE t (map (\ (x,c) -> (x, peephole' ev c)) cases) (fmap (peephole' ev) mcs) : peephole' ev cs
+> peephole' ev ((INTCASE t cases mcs):cs)
+>    = INTCASE t (map (\ (x,c) -> (x, peephole' ev c)) cases) (fmap (peephole' ev) mcs) : peephole' ev cs
+> peephole' ev (c: ASSIGN v1 r1: VAR r2 v2: EVAL r3 b: cs)
+>    | v1 == v2 && r3 == r2 = peephole' ev (c : EVAL r1 b: ASSIGN v1 r1 : TMPASSIGN r3 r1 : cs)
+> peephole' ev ((IF v t e):cs) = IF v (peephole' ev t) (peephole' ev e) : peephole' ev cs
+> peephole' ev ((WHILE t b):cs) = WHILE (peephole' ev t) (peephole' ev b) : peephole' ev cs
+> peephole' ev (VAR t v: EVAL t' True: cs')
+>              | t == t' && (not (elem v ev)) = (VAR t v : EVAL t True : peephole' (v:ev) cs')
+> peephole' ev (EVAL v l: EVAL v' l':cs) 
+>              | v == v' && l == l' = peephole' ev ((EVAL v l):cs)
+> peephole' ev (c:EVAL v l:xs) | evalled ev v c 
+>                                  = peephole' ev (c:xs)
+>                              | otherwise = c:peephole' ev (EVAL v l: xs)
+> peephole' ev (c:ASSIGN v r:cs)
+>              | evalled [] r c = c:ASSIGN v r:peephole' (v:ev) cs
+>              | otherwise = c: peephole' ev (ASSIGN v r: cs)
+> peephole' ev (x:xs) = x:peephole' ev xs
+
+> evalled ev v (INT x i) = x==v
+> evalled ev v (OP x _ _ _) = x==v
+> evalled ev v (CON x _ _) = x==v
+> evalled ev v (STRING x _) = x==v
+> evalled ev v (CALL x _ _) = x==v -- functions always eval before return
+> evalled ev v (FOREIGN _ x _ _) = x==v
+> evalled ev v (VAR x l) = x==v && l `elem` ev
+> evalled ev v (UNIT x) = x==v
+> evalled ev v (UNUSED x) = x==v
+> evalled _ _ _ = False
diff --git a/Epic/CodegenC.lhs b/Epic/CodegenC.lhs
--- a/Epic/CodegenC.lhs
+++ b/Epic/CodegenC.lhs
@@ -14,9 +14,13 @@
 >     workers ctxt decs
 >     -- ++ mainDriver
 
+> codegenH :: String -> [Decl] -> String
+> codegenH guard ds = "#ifndef _" ++ guard ++ "_H\n#define _" ++ guard ++ "_H\n\n" ++
+>                     concat (map exportH ds) ++ "\n\n#endif"
+
 > writeIFace :: [Decl] -> String
 > writeIFace [] = ""
-> writeIFace ((Decl name ret (Bind args _ _)):xs) =
+> writeIFace ((Decl name ret (Bind args _ _ _) _ _):xs) =
 >     "extern " ++ showC name ++ " ("++ showextargs (args) ++ ")" ++
 >               " -> " ++ show ret ++ "\n" ++ writeIFace xs
 > writeIFace (_:xs) = writeIFace xs
@@ -38,8 +42,12 @@
 > showargs [x] i = showarg x i
 > showargs (x:xs) i = showarg x i ++ ", " ++ showargs xs (i+1)
 
+> showlist [] = ""
+> showlist [x] = x
+> showlist (x:xs) = x ++ ", " ++ showlist xs
+
 > headers [] = ""
-> headers ((Decl fname ret (Bind args _ _)):xs) =
+> headers ((Decl fname ret (Bind args _ _ _) _ _):xs) =
 >     "void* " ++ thunk fname ++ "(void** block);\n" ++
 >     "void* " ++ quickcall fname ++ "(" ++ showargs args 0 ++ ");\n" ++
 >     headers xs
@@ -52,7 +60,7 @@
 > headers (_:xs) = headers xs
 
 > wrappers [] = ""
-> wrappers ((Decl fname ret (Bind args _ _)):xs) =
+> wrappers ((Decl fname ret (Bind args _ _ _) _ _):xs) =
 >     "void* " ++ thunk fname ++ "(void** block) {\n    return " ++ 
 >     quickcall fname ++ "(" ++
 >     wrapperArgs (length args) ++ ");\n}\n\n" ++
@@ -64,14 +72,15 @@
 > wrapperArgs x = wrapperArgs (x-1) ++ ", block[" ++ show (x-1) ++ "]"
 
 > workers _ [] = ""
-> workers ctxt ((Decl fname ret func@(Bind args locals defn)):xs) =
+> workers ctxt (decl@(Decl fname ret func@(Bind args locals defn _) _ _):xs) =
 >     -- trace (show fname ++ ": " ++ show defn) $
 >     "void* " ++ quickcall fname ++ "(" ++ showargs args 0 ++ ") {\n" ++
->      compileBody (compile ctxt fname func) ++ "\n}\n\n" ++
+>      compileBody (compile ctxt fname func) ++ "\n}\n\n" ++ exportC decl ++
 >     workers ctxt xs
 > workers ctxt (_:xs) = workers ctxt xs
 
 > tmp v = "tmp" ++ show v
+> constv v = "const" ++ show v
 > loc v = "var" ++ show v
 
 > quickcall fn = "_do_" ++ showC fn
@@ -113,35 +122,66 @@
 >                                   ++ ";"
 >    cg (VAR t l) = return $ tmp t ++ " = " ++ loc l ++ ";"
 >    cg (ASSIGN l t) = return $ loc l ++ " = " ++ tmp t ++ ";"
+>    cg (TMPASSIGN t1 t2) = return $ tmp t1 ++ " = " ++ tmp t2 ++ ";"
+>    cg (NOASSIGN l t) = return $ "// " ++ loc l ++ " = " ++ tmp t ++ ";"
 >    cg (CON t tag args) = do sizeneeded (length args)
 >                             return $ constructor t tag args
 >    cg (UNIT t) = return $ tmp t ++ " = MKUNIT;"
+>    cg (UNUSED t) = return $ tmp t ++ " = (void*)(1+42424242*2);"
 >    cg (INT t i) = return $ "ASSIGNINT("++tmp t ++ ", " ++show i++");"
 >    cg (BIGINT t i) = return $ tmp t ++ " = NEWBIGINT(\"" ++show i++"\");"
 >    cg (FLOAT t i) = return $ tmp t ++ " = MKFLOAT("++show i++");"
 >    cg (BIGFLOAT t i) = return $ tmp t ++ " = NEWBIGFLOAT(\""++show i++"\");"
->    cg (STRING t s) = return $ tmp t ++ " = MKSTR("++show s++");"
+>    cg (STRING t st) = return $ "MKSTRm("++tmp t ++ ", " ++ constv st ++ ");"
 >    cg (PROJ t1 t2 i) = return $ tmp t1 ++ " = PROJECT((Closure*)"++tmp t2++", "++show i++");"
 >    cg (PROJVAR l t i) = return $ loc l ++ " = PROJECT((Closure*)"++tmp t++", "++show i++");"
 >    cg (OP t op l r) = return $ doOp t op l r 
 >    cg (LOCALS n) = return $ declare "void* " loc (length args) n
 >    cg (TMPS n) = return $ declare "void* " tmp 0 n
+>    cg (CONSTS n) = return $ declareconsts n 0
+>    cg (LABEL i) = return $ "lbl" ++ show i ++ ":"
+>    cg (BREAKFALSE t) 
+>           = return $ -- "assertInt(" ++ tmp t ++ ");\n" ++
+>                      "if (!GETINT(" ++ tmp t ++ ")) break;"
+>    cg (WHILE t b) = do tcode <- cgs t
+>                        bcode <- cgs b
+>                        return $ "while (1) { " ++ tcode ++ "\n" ++ bcode ++ "}"
+>    cg (WHILEACC t a b) 
+>           = do tcode <- cgs t
+>                bcode <- cgs b
+>                return $ "whileacc (1) { " ++ tcode ++ "\n" ++
+>                       bcode ++ "}"
+>                             
+>    cg (JUMP i) = return $ "goto lbl" ++ show i ++ ";"
+>    cg (JFALSE t i) 
+>           = return $ "assertInt(" ++ tmp t ++ ");\n" ++
+>                      "if (!GETINT(" ++ tmp t ++ ")) goto lbl" ++ show i ++ ";"
 >    cg (CASE v alts def) = do
 >        altscode <- cgalts alts def 0
->        return $ "assert(ISCON("++tmp v++"));\n" ++
+>        return $ "assertCon("++tmp v++");\n" ++
 >                   "switch(TAG(" ++ tmp v ++")) {\n" ++
 >                   altscode
 >                   ++ "}"
+>    cg (INTCASE v alts def) = do
+>        altscode <- cgalts alts def 0
+>        return $ "assertInt("++tmp v++");\n" ++
+>                   "switch(GETINT(" ++ tmp v ++")) {\n" ++
+>                   altscode
+>                   ++ "}"
 >    cg (IF v t e) = do
 >        tcode <- cgs t
 >        ecode <- cgs e
->        return $ "assert(ISINT("++tmp v++"));\n" ++
+>        return $ "assertInt("++tmp v++");\n" ++
 >                 "if (GETINT("++tmp v++")) {\n" ++ tcode ++ "} else {\n" ++
 >                 ecode ++ "}"
->    cg (EVAL v) = return $ tmp v ++ "=(void*)EVAL((VAL)"++tmp v++");"
+>    cg (EVAL v True) = return $ tmp v ++ "=(void*)EVAL((VAL)"++tmp v++");"
+>    cg (EVAL v False) = return $ tmp v ++ "=(void*)EVAL_NOUP((VAL)"++tmp v++");"
+>    cg (EVALINT v True) = return $ tmp v ++ "=(void*)EVALINT((VAL)"++tmp v++");"
+>    cg (EVALINT v False) = return $ tmp v ++ "=(void*)EVALINT_NOUP((VAL)"++tmp v++");"
 >    cg (RETURN t) = return $ "return "++tmp t++";"
 >    cg DRETURN = return $ "return NULL;"
 >    cg (ERROR s) = return $ "ERROR("++show s++");"
+>    cg (COMMENT s) = return $ " // " ++ show s
 >    cg (TRACE s args) = return $ "TRACE {\n\tprintf(\"%s\\n\", " ++ show s ++ ");\n" ++
 >                              concat (map dumpClosure args) ++ " }"
 >        where dumpClosure i 
@@ -174,9 +214,14 @@
 >          = tmp t ++ " = CONSTRUCTOR(" ++
 >            show tag ++ ", 0, 0);"
 >    constructor t tag args 
->        | length args < 3 && length args > 0
->          = tmp t ++ " = CONSTRUCTOR" ++ show (length args) ++ "(" ++
->            show tag ++ targs ", " args ++ ");"
+>        | length args <6 && length args > 0
+>            = "CONSTRUCTOR" ++ show (length args) ++ 
+>              "m(" ++ tmp t ++ ", " ++  show tag ++ targs ", " args ++ ");"
+
+        | length args < 6 && length args > 0
+          = tmp t ++ " = CONSTRUCTOR" ++ show (length args) ++ "(" ++
+            show tag ++ targs ", " args ++ ");"
+
 >    constructor t tag args = argblock "block" args ++ tmp t ++
 >                             " = (void*)CONSTRUCTOR(" ++ 
 >                             show tag ++ ", " ++ 
@@ -196,31 +241,54 @@
 >                           show (length args) ++ 
 >                           ", block);"
 
+> declareconsts [] i = ""
+> declareconsts (s:xs) i = "INITSTRING(const" ++ show i ++ ", " ++ show s ++ ")"
+>                          ++ ";\n" ++ declareconsts xs (i+1)
+
 > declare decl fn start end 
 >     | start == end = ""
->     | otherwise = decl ++ fn start ++";\n" ++
+>     | otherwise = decl ++ fn start ++" = NULL;\n" ++
 >                   declare decl fn (start+1) end
 
 > foreignArgs [] = ""
 > foreignArgs [x] = foreignArg x
 > foreignArgs (x:xs) = foreignArg x ++ ", " ++ foreignArgs xs
 
+> cToEpic var TyString = "MKSTR((char*)(" ++ var ++ "))"
+> cToEpic var TyInt = "MKINT((int)(" ++ var ++ "))"
+> cToEpic var TyPtr = "MKPTR(" ++ var ++ ")"
+> cToEpic var TyBigInt = "MKBIGINT((mpz_t*)(" ++ var ++ "))"
+> cToEpic var TyUnit = "NULL"
+> cToEpic var _ = "(void*)(" ++ var ++")"
+
 > castFrom t TyUnit x = tmp t ++ " = NULL; " ++ x
-> castFrom t TyString rest = tmp t ++ " = MKSTR((char*)(" ++ rest ++ "))"
-> castFrom t TyPtr rest = tmp t ++ " = MKPTR(" ++ rest ++ ")"
-> castFrom t TyInt rest = tmp t ++ " = MKINT((int)(" ++ rest ++ "))"
-> castFrom t TyBigInt rest = tmp t ++ " = MKBIGINT((mpz_t*)(" ++ rest ++ "))"
-> castFrom t _ rest = tmp t ++ " = (void*)(" ++ rest ++ ")"
+> castFrom t TyPtr x = "MKPTRm(" ++ tmp t ++ ", " ++ x ++ ");"
+> castFrom t ty rest = tmp t ++ " = " ++ cToEpic rest ty
 
-> foreignArg (t, TyInt) = "GETINT("++ tmp t ++")"
-> foreignArg (t, TyBigInt) = "*(GETBIGINT("++ tmp t ++"))"
-> foreignArg (t, TyString) = "GETSTR("++ tmp t ++")"
-> foreignArg (t, TyPtr) = "GETPTR("++ tmp t ++")"
-> foreignArg (t, _) = tmp t
 
-> doOp t Plus l r = tmp t ++ " = INTOP(+,"++tmp l ++ ", "++tmp r++");"
+ castFrom t TyString rest = tmp t ++ " = MKSTR((char*)(" ++ rest ++ "))"
+ castFrom t TyPtr rest = tmp t ++ " = MKPTR(" ++ rest ++ ")"
+ castFrom t TyInt rest = tmp t ++ " = MKINT((int)(" ++ rest ++ "))"
+ castFrom t TyBigInt rest = tmp t ++ " = MKBIGINT((mpz_t*)(" ++ rest ++ "))"
+ castFrom t _ rest = tmp t ++ " = (void*)(" ++ rest ++ ")"
+
+> epicToC t TyInt = "GETINT("++ t ++")"
+> epicToC t TyBigInt = "*(GETBIGINT("++ t ++"))"
+> epicToC t TyString = "GETSTR("++ t ++")"
+> epicToC t TyPtr = "GETPTR("++ t ++")"
+> epicToC t _ = t
+
+> foreignArg (t, ty) = epicToC (tmp t) ty
+
+ foreignArg (t, TyInt) = "GETINT("++ tmp t ++")"
+ foreignArg (t, TyBigInt) = "*(GETBIGINT("++ tmp t ++"))"
+ foreignArg (t, TyString) = "GETSTR("++ tmp t ++")"
+ foreignArg (t, TyPtr) = "GETPTR("++ tmp t ++")"
+ foreignArg (t, _) = tmp t
+
+> doOp t Plus l r = tmp t ++ " = ADD("++tmp l ++ ", "++tmp r++");"
 > doOp t Minus l r = tmp t ++ " = INTOP(-,"++tmp l ++ ", "++tmp r++");"
-> doOp t Times l r = tmp t ++ " = INTOP(*,"++tmp l ++ ", "++tmp r++");"
+> doOp t Times l r = tmp t ++ " = MULT("++tmp l ++ ", "++tmp r++");"
 > doOp t Divide l r = tmp t ++ " = INTOP(/,"++tmp l ++ ", "++tmp r++");"
 > doOp t OpEQ l r = tmp t ++ " = INTOP(==,"++tmp l ++ ", "++tmp r++");"
 > doOp t OpGT l r = tmp t ++ " = INTOP(>,"++tmp l ++ ", "++tmp r++");"
@@ -228,3 +296,34 @@
 > doOp t OpGE l r = tmp t ++ " = INTOP(>=,"++tmp l ++ ", "++tmp r++");"
 > doOp t OpLE l r = tmp t ++ " = INTOP(<=,"++tmp l ++ ", "++tmp r++");"
 
+Write out code for an export
+
+> cty TyInt = "int"
+> cty TyChar = "char"
+> cty TyBool = "int"
+> cty TyString = "char*"
+> cty TyUnit = "void"
+> cty _ = "void*"
+
+> ctys [] = ""
+> ctys [x] = ctyarg x
+> ctys (x:xs) = ctyarg x ++ ", " ++ ctys xs
+
+> ctyarg (n,ty) = cty ty ++ " " ++ showuser n
+
+> exportC :: Decl -> String
+> exportC (Decl nm rt (Bind args _ _ _) (Just cname) _) =
+>     cty rt ++ " " ++ cname ++ "(" ++ ctys args ++ ") {\n\t" ++
+>         if (rt==TyUnit) then "" else "return " ++
+>         epicToC (quickcall nm ++ "(" ++ showlist (map conv args) ++ ")") rt ++ 
+>         ";\n\n" ++
+>     "}"
+>   where conv (nm, ty) = cToEpic (showuser nm) ty
+> exportC _ = ""
+
+... and in the header file
+
+> exportH :: Decl -> String
+> exportH (Decl nm rt (Bind args _ _ _) (Just cname) _) =
+>     cty rt ++ " " ++ cname ++ "(" ++ ctys args ++ ");\n"
+> exportH _ = ""
diff --git a/Epic/Compiler.lhs b/Epic/Compiler.lhs
--- a/Epic/Compiler.lhs
+++ b/Epic/Compiler.lhs
@@ -20,11 +20,13 @@
 > import System.IO
 > import System.Directory
 > import System.Environment
+> import Char
 
 > import Epic.Language
 > import Epic.Parser
 > import Epic.Scopecheck
 > import Epic.CodegenC
+> import Epic.Simplify
 
 > import Paths_epic
 
@@ -33,6 +35,7 @@
 >                     | Trace -- ^ Generate trace at run-time (debug)
 >                     | ShowBytecode -- ^ Show generated code
 >                     | ShowParseTree -- ^ Show parse tree
+>                     | MakeHeader FilePath -- ^ Output a .h file too
 >                     | GCCOpt String -- ^ Extra GCC option
 >   deriving Eq
 
@@ -41,6 +44,11 @@
 > addGCC ((GCCOpt s):xs) = s ++ " " ++ addGCC xs
 > addGCC (_:xs) = addGCC xs
 
+> outputHeader :: [CompileOptions] -> Maybe FilePath
+> outputHeader [] = Nothing
+> outputHeader ((MakeHeader f):_) = Just f
+> outputHeader (_:xs) = outputHeader xs
+
 > doTrace opts | elem Trace opts = " -DTRACEON"
 >              | otherwise = ""
 
@@ -70,10 +78,13 @@
 >              Failure err _ _ -> fail err
 >              Success ds -> do
 >                 (tmpn,tmph) <- tempfile
->                 checked <- compileDecls (checkAll ds) tmph
+>                 let hdr = outputHeader opts
+>                 scchecked <- checkAll ds
+>                 let simplified = simplifyAll scchecked
+>                 checked <- compileDecls simplified tmph hdr
 >                 fp <- getDataFileName "evm/closure.h"
 >                 let libdir = trimLast fp
->                 let cmd = "gcc -c -O2 -foptimize-sibling-calls -x c " ++ tmpn ++ " -I" ++ libdir ++ " -o " ++ outf ++ " " ++ addGCC opts ++ doTrace opts
+>                 let cmd = "gcc -c -g -foptimize-sibling-calls -x c " ++ tmpn ++ " -I" ++ libdir ++ " -o " ++ outf ++ " " ++ addGCC opts ++ doTrace opts
 >                 -- putStrLn $ cmd
 >                 -- putStrLn $ fp
 >                 exit <- system cmd
@@ -94,23 +105,28 @@
 >     (stem,_) -> stem
 
 
-> compileDecls (Success (ctxt, decls)) outh
+> compileDecls (ctxt, decls) outh hdr
 >     = do hPutStr outh $ codegenC ctxt decls
+>          case hdr of
+>              Just fpath ->
+>                   do let hout = codegenH (filter isAlpha (map toUpper (getRoot fpath))) decls
+>                      writeFile fpath hout
+>              Nothing -> return ()
 >          hFlush outh
 >          hClose outh
 >          return decls
-> compileDecls (Failure err _ _) _ = fail err
 
 > -- |Link a collection of .o files into an executable
 > link :: [FilePath] -- ^ Object files
 >         -> [FilePath] -- ^ Extra include files for main program
 >         -> FilePath -- ^ Executable filename
+>         -> Bool -- ^ Generate a 'main' (False if externally defined)
 >         -> IO ()
-> link infs extraIncs outf = do
->     mainprog <- mkMain extraIncs 
+> link infs extraIncs outf genmain = do
+>     mainprog <- if genmain then mkMain extraIncs else return ""
 >     fp <- getDataFileName "evm/closure.h"
 >     let libdir = trimLast fp
->     let cmd = "gcc -x c -O2 -foptimize-sibling-calls " ++ mainprog ++ " -x none -L" ++
+>     let cmd = "gcc -x c -g -foptimize-sibling-calls " ++ mainprog ++ " -x none -L" ++
 >               libdir++" -I"++libdir ++ " " ++
 >               (concat (map (++" ") infs)) ++ 
 >               " -levm -lgc -lpthread -lgmp -o "++outf
diff --git a/Epic/Language.lhs b/Epic/Language.lhs
--- a/Epic/Language.lhs
+++ b/Epic/Language.lhs
@@ -40,6 +40,7 @@
 >            | MkString String
 >            | MkBool Bool
 >            | MkUnit
+>            | MkUnused
 >   deriving (Show, Eq)
 
 > data Name = UN String  -- user name
@@ -77,25 +78,31 @@
 > data Expr = V Int -- Locally bound name
 >           | R Name -- Global reference
 >           | App Expr [Expr] -- Function application
->           | LazyApp Expr [Expr] -- Lazy function application
+>           | Lazy Expr -- Lazy function application
+>           | Effect Expr -- Expression with side effects (i.e. don't update when EVALing)
 >           | Con Tag [Expr] -- Constructor, tags, arguments (fully applied)
 >           | Const Const -- a constant
 >           | Proj Expr Int -- Project argument
 >           | Case Expr [CaseAlt]
 >           | If Expr Expr Expr
+>           | While Expr Expr
+>           | WhileAcc Expr Expr Expr
 >           | Op Op Expr Expr -- Infix operator
 >           | Let Name Type Expr Expr -- Let binding
 >           | Error String -- Exit with error message
 >           | Impossible -- Claimed impossible to reach code
 >           | ForeignCall Type String [(Expr, Type)] -- Foreign function call
->   deriving (Show, Eq)
+>           | LazyForeignCall Type String [(Expr, Type)] -- Foreign function call
+>   deriving Eq
 
 > data CaseAlt = Alt { alt_tag :: Tag,
 >                      alt_args :: [(Name, Type)], -- bound arguments
 >                      alt_expr :: Expr -- what to do
 >                    }
+>              | ConstAlt { alt_const :: Int,
+>                           alt_expr :: Expr }
 >              | DefaultCase { alt_expr :: Expr }
->   deriving (Show, Eq)
+>   deriving Eq
 
 > instance Ord CaseAlt where -- only the tag matters
 >    compare (Alt t1 _ _) (Alt t2 _ _) = compare t1 t2
@@ -106,25 +113,62 @@
 > data Op = Plus | Minus | Times | Divide | OpEQ | OpLT | OpLE | OpGT | OpGE
 >   deriving (Show, Eq)
 
+> instance Show CaseAlt where
+>     show (DefaultCase e) = "default -> " ++ show e
+>     show (ConstAlt i e) = show i ++ " -> " ++ show e
+>     show (Alt t args e) = "Con " ++ show t ++ show args ++ " -> " ++ show e
+
+> instance Show Expr where
+>     show (V i) = "var" ++ show i
+>     show (R n) = show n
+>     show (App f as) = show f ++ show as
+>     show (Lazy e) = "%lazy(" ++ show e ++ ")"
+>     show (Effect e) = "%effect(" ++ show e ++ ")"
+>     show (Con t es) = "Con " ++ show t ++ show es
+>     show (Const c) = show c
+>     show (Proj e i) = show e ++ "!" ++ show i
+>     show (Case e alts) = "case " ++ show e ++ " of " ++ show alts
+>     show (If x t e) = "if " ++ show x ++ " then " ++ show t ++ " else " ++ show e
+>     show (While e b) = "%while(" ++ show e ++ "," ++ show b ++ ")"
+>     show (WhileAcc e b a) = "%while(" ++ show e ++ ", " ++ show b ++ 
+>                             ", " ++ show a ++ ")"
+>     show (Op o l r) = "(" ++ show l ++ " " ++ show o ++ " " ++ show r ++")"
+>     show (Let n t v e) = "let " ++ show n ++ ":" ++ show t ++ " = " ++
+>                          show v ++ " in " ++ show e
+>     show (Error e) = "error(" ++ show e ++ ")"
+>     show Impossible = "Impossible"
+>     show (ForeignCall t s as) = "foreign " ++ show t ++ " " ++
+>                                 show s ++ show as
+>     show (LazyForeignCall t s as) = "lazy foreign " ++ show t ++ " " ++
+>                                     show s ++ show as
+                             
 Supercombinator definitions
 
 > data Func = Bind { fun_args :: [(Name, Type)],
 >                    locals :: Int, -- total number of locals
->                    defn :: Expr }
+>                    defn :: Expr,
+>                    flags :: [CGFlag]}
 >   deriving Show
 
 Programs
 
 > data Decl = Decl { fname :: Name,
 >                    frettype :: Type,
->                    fdef :: Func }
+>                    fdef :: Func,
+>                    fexport :: Maybe String,  -- C name
+>                    fcompflags :: [CGFlag]
+>                  }
 >           | Extern { fname :: Name, 
 >                      frettype :: Type,
 >                      fargs :: [Type] }
 >           | Include String
 >           | Link String
+>           | CType Name
 >   deriving Show
 
+> data CGFlag = Inline | Strict
+>   deriving (Show, Eq)
+
 > data Result r = Success r
 >               | Failure String String Int
 >     deriving (Show, Eq)
@@ -140,6 +184,19 @@
 >     mplus (Success x) _ = (Success x)
 >     mplus (Failure _ _ _) y = y
 > 
+
+> appForm :: Expr -> Bool
+
+ appForm (App _ _) = True
+ appForm (V _) = True
+
+> appForm (R _) = True
+
+ appForm (Con _ _) = True
+ appForm (Const _) = True
+ appForm (LazyForeignCall _ _ _) = True
+
+> appForm _ = False
 
 
 
diff --git a/Epic/Lexer.lhs b/Epic/Lexer.lhs
--- a/Epic/Lexer.lhs
+++ b/Epic/Lexer.lhs
@@ -67,10 +67,13 @@
 >       | TokenForeign
 >       | TokenCInclude
 >       | TokenLink
+>       | TokenInline
 >       | TokenOB
 >       | TokenCB
 >       | TokenOCB
 >       | TokenCCB
+>       | TokenOSB
+>       | TokenCSB
 >       | TokenPlus
 >       | TokenMinus
 >       | TokenTimes
@@ -86,14 +89,20 @@
 >       | TokenUnit
 >       | TokenCon
 >       | TokenDefault
+>       | TokenExport
+>       | TokenCType
 >       | TokenLet
 >       | TokenCase
 >       | TokenOf
 >       | TokenIf
 >       | TokenThen
 >       | TokenElse
+>       | TokenWhile
+>       | TokenUnused
 >       | TokenIn
 >       | TokenLazy
+>       | TokenStrict
+>       | TokenEffect
 >       | TokenError
 >       | TokenImpossible
 >       | TokenProj
@@ -123,6 +132,8 @@
 > lexer cont (')':cs) = cont TokenCB cs
 > lexer cont ('{':cs) = cont TokenOCB cs
 > lexer cont ('}':cs) = cont TokenCCB cs
+> lexer cont ('[':cs) = cont TokenOSB cs
+> lexer cont (']':cs) = cont TokenCSB cs
 > lexer cont ('+':cs) = cont TokenPlus cs
 > lexer cont ('-':cs) = cont TokenMinus cs
 > lexer cont ('*':cs) = cont TokenTimes cs
@@ -224,6 +235,8 @@
 >       ("impossible",rest) -> cont TokenImpossible rest
 >       ("foreign",rest) -> cont TokenForeign rest
 > -- declarations
+>       ("export",rest) -> cont TokenExport rest
+>       ("ctype",rest) -> cont TokenCType rest
 >       ("extern",rest) -> cont TokenExtern rest
 >       ("include",rest) -> cont TokenInclude rest
 >       (var,rest)   -> cont (mkname var) rest
@@ -232,6 +245,11 @@
 >     case span isAllowed cs of
 >       ("include",rest) -> cont TokenCInclude rest
 >       ("link",rest) -> cont TokenLink rest
+>       ("inline",rest) -> cont TokenInline rest
+>       ("effect",rest) -> cont TokenEffect rest
+>       ("strict",rest) -> cont TokenStrict rest
+>       ("while",rest) -> cont TokenWhile rest
+>       ("unused", rest) -> cont TokenUnused rest
 >       (thing,rest) -> lexError '%' rest
  
 > mkname :: String -> Token
diff --git a/Epic/Parser.y b/Epic/Parser.y
--- a/Epic/Parser.y
+++ b/Epic/Parser.y
@@ -48,8 +48,12 @@
       if              { TokenIf }
       then            { TokenThen }
       else            { TokenElse }
+      while           { TokenWhile }
+      unused          { TokenUnused }
       in              { TokenIn }
       lazy            { TokenLazy }
+      strict          { TokenStrict }
+      effect          { TokenEffect }
       foreign         { TokenForeign }
       errorcode       { TokenError }
       impossible      { TokenImpossible }
@@ -57,6 +61,8 @@
       ')'             { TokenCB }
       '{'             { TokenOCB }
       '}'             { TokenCCB }
+      '['             { TokenOSB }
+      ']'             { TokenCSB }
       '+'             { TokenPlus }
       '-'             { TokenMinus }
       '*'             { TokenTimes }
@@ -75,7 +81,10 @@
       arrow           { TokenArrow }
       cinclude         { TokenCInclude }
       extern          { TokenExtern }
+      export          { TokenExport }
+      ctype           { TokenCType }
       include         { TokenInclude }
+      inline          { TokenInline }
 
 %nonassoc NONE
 %nonassoc lazy
@@ -86,7 +95,8 @@
 %left '<' '>' le ge
 %left '+' '-'
 %left '*' '/'
-%nonassoc '!'
+%left NEG
+%left '!'
 %nonassoc '('
 
 
@@ -118,13 +128,24 @@
      | funtype { TyFun }
 
 Declaration :: { Decl }
-Declaration: name '(' TypeList ')' arrow Type '=' Expr
-               { mkBind $1 (map snd $3) $6 (map fst $3) $8 }
+Declaration: Export Flags name '(' TypeList ')' arrow Type '=' Expr
+               { mkBind $3 (map snd $5) $8 (map fst $5) $10 $1 $2 }
            | extern name '(' TypeList ')' arrow Type
                { mkExtern $2 (map snd $4) $7 (map fst $4) }
            | cinclude string { Include $2 }
 
+Flags :: { [CGFlag] }
+Flags : { [] }
+      | Flag Flags { $1:$2 }
 
+Flag :: { CGFlag }
+     : inline { Inline }
+     | strict { Strict }
+
+Export :: { Maybe String }
+Export : { Nothing }
+       | export string { Just $2 }
+
 TypeList :: { [(Name,Type)] }
 TypeList : { [] }
          | name ':' Type { [($1,$3)] }
@@ -134,20 +155,25 @@
 Expr : name { R $1 }
      | '(' Expr ')' { $2 }
      | Expr '(' ExprList ')' { App $1 $3 }
-     | lazy '(' Expr '(' ExprList ')' ')' { LazyApp $3 $5 }
-     | lazy '(' name ')' { LazyApp (R $3) [] }
+     | '[' ExprList ']' { Con 0 $2 }
+     | lazy '(' Expr ')' { Lazy $3 }
+     | effect '(' Expr ')' { Effect $3 }
      | con int '(' ExprList ')' { Con $2 $4 }
      | Const { Const $1 }
      | Expr '!' int { Proj $1 $3 }
      | let name ':' Type '=' Expr in Expr %prec LET { Let $2 $4 $6 $8 }
      | Expr ';' Expr { Let (MN "unused" 0) TyUnit $1 $3 }
      | if Expr then Expr else Expr %prec IF { If $2 $4 $6 }
+     | while '(' Expr ',' Expr ')' { While $3 $5 }
+     | while '(' Expr ',' Expr ',' Expr ')' { WhileAcc $3 $5 $7 }
      | CaseExpr { $1 }
      | MathExpr { $1 }
      | errorcode string { Error $2 }
      | impossible { Impossible }
      | foreign Type string '(' ExprTypeList ')' 
           { ForeignCall $2 $3 $5 }
+     | lazy foreign Type string '(' ExprTypeList ')' 
+          { LazyForeignCall $3 $4 $6 }
 
 CaseExpr :: { Expr }
 CaseExpr : case Expr of '{' Alts '}' { Case $2 $5 }
@@ -160,11 +186,14 @@
 Alt :: { CaseAlt }
 Alt : con int '(' TypeList ')' arrow Expr 
          { Alt $2 $4 $7 }
+    | int arrow Expr
+         { ConstAlt $1 $3 }
     | default arrow Expr { DefaultCase $3 }
 
 MathExpr :: { Expr }
 MathExpr : Expr '+' Expr { Op Plus $1 $3 }
          | Expr '-' Expr { Op Minus $1 $3 }
+         | '-' Expr %prec NEG { Op Minus (Const (MkInt 0)) $2 }
          | Expr '*' Expr { Op Times $1 $3 }
          | Expr '/' Expr { Op Divide $1 $3 }
          | Expr '<' Expr { Op OpLT $1 $3 }
@@ -192,6 +221,7 @@
       | bigfloat { MkBigFloat $1 }
       | string { MkString $1 }
       | unit { MkUnit }
+      | unused { MkUnused }
 
 Line :: { LineNumber }
      : {- empty -}      {% getLineNo }
@@ -201,8 +231,8 @@
 
 {
 
-mkBind :: Name -> [Type] -> Type -> [Name] -> Expr -> Decl
-mkBind n tys ret ns expr = Decl n ret (Bind (zip ns tys) 0 expr)
+mkBind :: Name -> [Type] -> Type -> [Name] -> Expr -> Maybe String -> [CGFlag] -> Decl
+mkBind n tys ret ns expr export fl = Decl n ret (Bind (zip ns tys) 0 expr fl) export fl
 
 mkExtern :: Name -> [Type] -> Type -> [Name] -> Decl
 mkExtern n tys ret ns = Extern n ret tys
diff --git a/Epic/Scopecheck.lhs b/Epic/Scopecheck.lhs
--- a/Epic/Scopecheck.lhs
+++ b/Epic/Scopecheck.lhs
@@ -8,45 +8,53 @@
 > import Epic.Language
 > import Epic.Parser
 
+> import Debug.Trace
+
 > checkAll :: Monad m => [Decl] -> m (Context, [Decl])
 > checkAll xs = do let ctxt = mkContext xs
 >                  ds <- ca (mkContext xs) xs
->                  return (ctxt,ds)
+>                  return (mkContext ds,ds)
 >    where ca ctxt [] = return []
->          ca ctxt ((Decl nm rt fn):xs) = 
->              do fn' <- scopecheck ctxt fn
->                 xs' <- ca ctxt xs
->                 return $ (Decl nm rt fn'):xs'
+>          ca ctxt ((Decl nm rt fn exp fl):xs) = 
+>              do (fn', newds) <- scopecheck ctxt nm fn
+>                 xs' <- ca ctxt (newds ++ xs)
+>                 return $ (Decl nm rt fn' exp fl):xs'
 >          ca ctxt (x:xs) =
 >              do xs' <- ca ctxt xs
 >                 return (x:xs')
 
 >          mkContext [] = []
->          mkContext ((Decl nm rt (Bind args _ _)):xs) =
+>          mkContext ((Decl nm rt (Bind args _ _ _) _ _):xs) =
 >              (nm,(map snd args, rt)):(mkContext xs)
 >          mkContext ((Extern nm rt args):xs) =
 >              (nm,(args, rt)):(mkContext xs)
 >          mkContext (_:xs) = mkContext xs
 
-> scopecheck :: Monad m => Context -> Func -> m Func
-> scopecheck ctxt (Bind args locs exp) = do
->        (exp', locs') <- runStateT (tc (v_ise args 0) exp) (length args)
->        return $ Bind args locs' exp'
+Check all names are in scope in a function, and convert global references (R) to local names
+(V). Also, if any lazy expressions are not already applications, lift them out and make
+a new function. Returns the modified function, and a list of new declarations. The new 
+declarations will *not* have been scopechecked.
+
+> scopecheck :: Monad m => Context -> Name -> Func -> m (Func, [Decl])
+> scopecheck ctxt nm (Bind args locs exp fl) = do
+>        (exp', (locs', _, ds)) <- runStateT (tc (v_ise args 0) exp) (length args, 0, [])
+>        return $ (Bind args locs' exp' fl, ds)
 >  where
+>    getRoot (UN nm) = nm
+>    getRoot (MN nm i) = "_" ++ nm ++ "_" ++ show i
 >    tc env (R n) = case lookup n env of
 >                      Nothing -> case lookup n ctxt of
 >                         Nothing -> return $ Const (MkInt 1234567890)
-> -- lift $ fail $ 
->    --                                  "Unknown name " ++ showuser n
+>                                    -- lift $ fail $ "Unknown name " ++ showuser n
 >                         (Just _) -> return $ R n
 >                      (Just i) -> return $ V i
 >    tc env (Let n ty v sc) = do
 >                v' <- tc env v
 >                sc' <- tc ((n,length env):env) sc
->                maxlen <- get
->                put (if (length env + 1)>maxlen 
->                        then (length env + 1) 
->                        else maxlen)
+>                (maxlen, nextn, decls) <- get
+>                put ((if (length env + 1)>maxlen 
+>                         then (length env + 1) 
+>                         else maxlen), nextn, decls)
 >                return $ Let n ty v' sc'
 >    tc env (Case v alts) = do
 >                v' <- tc env v
@@ -57,14 +65,37 @@
 >                t' <- tc env t
 >                e' <- tc env e
 >                return $ If a' t' e'
+>    tc env (While t b) = do
+>                t' <- tc env t
+>                b' <- tc env b
+>                return $ While t' b'
+>    tc env (WhileAcc t a b) = do
+>                t' <- tc env t
+>                a' <- tc env a
+>                b' <- tc env b
+>                return $ WhileAcc t' a' b'
 >    tc env (App f as) = do
 >                f' <- tc env f
 >                as' <- mapM (tc env) as
 >                return $ App f' as'
->    tc env (LazyApp f as) = do
->                f' <- tc env f
->                as' <- mapM (tc env) as
->                return $ LazyApp f' as'
+>    tc env (Lazy e) | appForm e = do
+>                e' <- tc env e
+>                return $ Lazy e'
+
+Make a new function, with current env as arguments, and add as a decl
+
+>    tc env (Lazy e) = 
+>         do (maxlen, nextn, decls) <- get
+>            let newname = MN (getRoot nm) nextn
+>            let newargs = zip (map fst env) (repeat TyAny)
+>            let newfn = Bind newargs 0 e []
+>            let newd = Decl newname TyAny newfn Nothing []
+>            put (maxlen, nextn+1, newd:decls)
+>            return $ Lazy (App (R newname) (map V (map snd env)))
+
+>    tc env (Effect e) = do
+>                e' <- tc env e
+>                return $ Effect e'
 >    tc env (Con t as) = do
 >                as' <- mapM (tc env) as
 >                return $ Con t as'
@@ -78,24 +109,41 @@
 >    tc env (ForeignCall ty fn args) = do
 >                argexps' <- mapM (tc env) (map fst args)
 >                return $ ForeignCall ty fn (zip argexps' (map snd args))
+>    tc env (LazyForeignCall ty fn args) = do
+>                argexps' <- mapM (tc env) (map fst args)
+>                return $ LazyForeignCall ty fn (zip argexps' (map snd args))
 >    tc env x = return x
 
 >    tcalts env [] = return []
 >    tcalts env ((Alt tag args expr):alts) = do
 >                let env' = (v_ise args (length env))++env
 >                expr' <- tc env' expr
->                maxlen <- get
->                put (if (length env')>maxlen 
->                        then (length env')
->                        else maxlen)
+>                (maxlen, nextn, decls) <- get
+>                put ((if (length env')>maxlen 
+>                         then (length env')
+>                         else maxlen), nextn, decls)
 >                alts' <- tcalts env alts
 >                return $ (Alt tag args expr'):alts'
+>    tcalts env ((ConstAlt tag expr):alts) = do
+>                expr' <- tc env expr
+>                alts' <- tcalts env alts
+>                return $ (ConstAlt tag expr'):alts'
 >    tcalts env ((DefaultCase expr):alts) = do
 >                expr' <- tc env expr
 >                alts' <- tcalts env alts
 >                return $ (DefaultCase expr'):alts'
 
 Turn the argument list into a mapping from names to argument position
+If any names appear more than once, use the last one.
 
+We're being very tolerant of input here... 
+
 >    v_ise [] _ = []
->    v_ise ((n,ty):args) i = (n,i):(v_ise args (i+1))
+>    v_ise ((n,ty):args) i = let rest = v_ise args (i+1) in
+>                                case lookup n rest of
+>                                  Nothing -> (n,i):rest
+>                                  _ -> rest
+
+       where dropArg n [] = []
+             dropArg n ((x,i):xs) | x == n = dropArg n xs
+                                  | otherwise = (x,i):(dropArg n xs)
diff --git a/Epic/Simplify.lhs b/Epic/Simplify.lhs
new file mode 100644
--- /dev/null
+++ b/Epic/Simplify.lhs
@@ -0,0 +1,103 @@
+> module Epic.Simplify(simplifyAll) where
+
+> import Epic.Language
+
+> import Data.Maybe
+> import Debug.Trace
+
+> simplifyAll :: (Context, [Decl]) -> (Context, [Decl])
+> simplifyAll (ctxt, xs) = let sctxt = mapMaybe mkEntry xs in
+>                              simpl sctxt ctxt xs
+>   where mkEntry d@(Decl n _ fn _ fl) = Just (n, (d, (length (fun_args fn)), fl))
+>         mkEntry _ = Nothing
+
+For each supercombinator, evaluate it as far as we believe sensible - basically just inlining
+definitions marked as such, constant folding, case on constants, etc.
+
+Also consider creating specialised versions of functions?
+
+> type SCtxt = [(Name, (Decl, Int, [CGFlag]))]
+
+> simpl :: SCtxt -> Context -> [Decl] -> (Context, [Decl])
+> simpl sctxt ctxt ds = (ctxt, map simplD ds)
+>   where simplD (Decl fn fr fd fe fl) = let simpled = simplFun fd in
+>                                        diff fn simpled fd $ 
+>                                          Decl fn fr (simplFun fd) fe fl
+>         simplD d = d
+
+>         simplFun (Bind args locs def fl) 
+>             = Bind args locs (simplify sctxt (map (\x -> Nothing) args) (length args) def) fl
+>         diff fn simpled fd x | defn simpled == defn fd = x
+>                              | otherwise =  {- trace (show fn ++ "\n" ++ show simpled ++ "\n" ++
+>                                                   show fd) -} x
+
+> inlinable = elem Inline
+
+> simplify :: SCtxt -> [Maybe Expr] -> Int -> Expr -> Expr
+> simplify sctxt args arity exp = s' args arity exp 
+>   where
+>     s' args depth (V i) = if i<length args then 
+>                             case args!!i of
+>                               Nothing -> V i
+>                               Just v -> v
+>                             else error "Can't happen - simplify - No such arg" -- V (i + (arity - length args)) -- adjust case/let offset
+>     s' args d (R fn) 
+>       = case lookup fn sctxt of
+>             Just (decl, 0, fl) -> 
+>                if (inlinable fl) then s' args d (inline d decl [])
+>                    else R fn
+>             _ -> R fn
+>     s' args d (App f a) = apply d (s' args d f) (map (s' args d) a) args
+>     s' args d (Lazy e) = Lazy $ s' args d e
+>     s' args d (Effect e) = Effect $ s' args d e
+>     s' args d (While t e) = While (s' args d t) (s' args d e)
+>     s' args d (WhileAcc t a e) = WhileAcc (s' args d t) (s' args d a) (s' args d e)
+>     s' args d (Con t a) = Con t (map (s' args d) a)
+>     s' args d (Proj e i) = project (s' args d e) i
+>     s' args d (Case e alts) = runCase (s' args d e) (map (salt args d) alts)
+>     s' args d (If x t e) = runIf (s' args d x) (s' args d t) (s' args d e)
+>     s' args d (Op op l r) = runOp op (s' args d l) (s' args d r)
+>     s' args d (Let n ty v sc) 
+>          = simplFLet $ runLet n ty (s' args d v)
+>                                    (s' (args++[Just (V d)]) (d+1) sc)
+>     s' args d (ForeignCall ty nm a) 
+>           = ForeignCall ty nm (map (\ (x,y) -> (s' args d x, y)) a)
+>     s' args d (LazyForeignCall ty nm a) 
+>           = LazyForeignCall ty nm (map (\ (x,y) -> (s' args d x, y)) a)
+>     s' args d x = x
+
+>     salt args d (Alt t bargs e) 
+>         = Alt t bargs (s' newargs (d+length bargs) e)
+>       where newargs = args ++ (map (Just . V) (take (length bargs) [d..]))
+>     salt args d (ConstAlt c e) = ConstAlt c (s' args d e)
+>     salt args d (DefaultCase e) = DefaultCase (s' args d e)
+
+>     project e i = Proj e i
+>     runCase e alts = Case e alts
+>     runIf x t e = If x t e
+>     runOp op l r = Op op l r
+>     runLet n ty v sc = Let n ty v sc
+
+>     apply d f@(R fn) as args
+>       = case lookup fn sctxt of
+>             Just (decl, ar, fl) -> 
+>                if (inlinable fl && ar == length as) then inline d decl (map Just as)
+>                    else App f as
+>             _ -> App f as
+>     apply d f as args = App f as
+
+>     inline :: Int -> Decl -> [Maybe Expr] -> Expr
+>     inline d (Decl fn _ (Bind _ _ exp _) _ _) args 
+>                = simplify (remove fn sctxt) args d exp
+>         where remove fn [] = []
+>               remove fn (f@(x,_):xs) | x == fn = xs
+>                                      | otherwise = f:(remove fn xs)
+
+If we do this, we can chop out some pointless assignments to Unit
+
+> simplFLet :: Expr -> Expr
+> simplFLet (Let n _ (ForeignCall ty f args) s) = 
+>                  Let n ty (ForeignCall ty f args) s
+> simplFLet (Let n _ (Effect (ForeignCall ty f args)) s) =
+>                  Let n ty (Effect (ForeignCall ty f args)) s
+> simplFLet x = x
diff --git a/Main.lhs b/Main.lhs
new file mode 100644
--- /dev/null
+++ b/Main.lhs
@@ -0,0 +1,118 @@
+> module Main where
+
+> import System
+> import System.Directory
+> import System.Environment
+> import System.IO
+> import Monad
+
+> import Epic.Compiler
+
+> main = do args <- getArgs
+>           (fns, opts) <- getInput args
+>           outfile <- getOutput opts
+>           ofiles <- compileFiles fns (mkOpts opts)
+>           copts <- getCOpts opts
+>           extras <- getExtra opts
+>           if ((length ofiles) > 0 && (not (elem Obj opts)))
+>              then link (ofiles ++ copts) extras outfile (not (elem ExtMain opts))
+>              else return ()
+>   where mkOpts (KeepInt:xs) = KeepC:(mkOpts xs)
+>         mkOpts (TraceOn:xs) = Trace:(mkOpts xs)
+>         mkOpts (Header f:xs) = MakeHeader f:(mkOpts xs)
+>         mkOpts (_:xs) = mkOpts xs
+>         mkOpts [] = []
+
+> compileFiles [] _ = return []
+> compileFiles (fn:xs) opts
+>     | isDotE fn = do
+>        let ofile = getRoot fn ++ ".o"
+>        compileOpts fn ofile (Just (getRoot fn ++ ".ei")) opts
+>        rest <- compileFiles xs opts
+>        return (ofile:rest)
+>     | isDotO fn = do
+>        rest <- compileFiles xs opts
+>        return (fn:rest)
+>     | otherwise = do -- probably autogenerated, just build it.
+>        let ofile = fn ++ ".o"
+>        compileOpts fn ofile Nothing opts
+>        rest <- compileFiles xs opts
+>        return (ofile:rest)
+
+> isDotE ('.':'e':[]) = True
+> isDotE (_:xs) = isDotE xs
+> isDotE [] = False
+
+> isDotC ('.':'c':[]) = True
+> isDotC (_:xs) = isDotC xs
+> isDotC [] = False
+
+> isDotO ('.':'o':[]) = True
+> isDotO (_:xs) = isDotO xs
+> isDotO [] = False
+
+> mkExecname fn = case span (/='.') fn of
+>     (stem,".e") -> stem
+>     (stem,_) -> fn ++ ".exe"
+
+> getRoot fn = case span (/='.') fn of
+>     (stem,_) -> stem
+
+> getInput :: [String] -> IO ([FilePath],[Option])
+> getInput args = do let opts = parseArgs args
+>                    fns <- getFile opts
+>                    if (length fns == 0) 
+>                       then do showUsage
+>                               return (fns,opts)
+>                       else return (fns,opts)
+
+> showUsage = do putStrLn "Epigram Supercombinator Compiler version 0.1"
+>                putStrLn "Usage:\n\tepic <input file> [options]"
+>                exitWith (ExitFailure 1)
+
+> data Option = KeepInt -- Don't delete intermediate file
+>             | TraceOn -- Trace while running (debug option)
+>             | Obj -- Just make the .o, don't link
+>             | File String -- File to send the compiler
+>             | Output String -- Output filename
+>             | Header String -- Header output filename
+>             | ExtraInc String -- extra files to inlude
+>             | COpt String -- option to send straight to gcc
+>             | ExtMain -- external main (i.e. in a .o)
+>   deriving Eq
+
+> parseArgs :: [String] -> [Option]
+> parseArgs [] = []
+> parseArgs ("-keepc":args) = KeepInt:(parseArgs args)
+> parseArgs ("-trace":args) = TraceOn:(parseArgs args)
+> parseArgs ("-c":args) = Obj:(parseArgs args)
+> parseArgs ("-extmain":args) = ExtMain:(parseArgs args)
+> parseArgs ("-o":name:args) = (Output name):(parseArgs args)
+> parseArgs ("-h":name:args) = (Header name):(parseArgs args)
+> parseArgs ("-i":inc:args) = (ExtraInc inc):(parseArgs args)
+> parseArgs (('$':x):args) = (COpt (x ++ concat (map (" "++) args))):[]
+> parseArgs (('-':x):args) = (COpt x):(parseArgs args)
+> parseArgs (x:args) = (File x):(parseArgs args)
+
+> getFile :: [Option] -> IO [FilePath]
+> getFile ((File x):xs) = do fns <- getFile xs
+>                            return (x:fns)
+> getFile (_:xs) = getFile xs
+> getFile [] = return []
+
+> getOutput :: [Option] -> IO FilePath
+> getOutput ((Output fn):xs) = return fn
+> getOutput (_:xs) = getOutput xs
+> getOutput [] = return "a.out"
+
+> getCOpts :: [Option] -> IO [String]
+> getCOpts ((COpt x):xs) = do fns <- getCOpts xs
+>                             return (x:fns)
+> getCOpts (_:xs) = getCOpts xs
+> getCOpts [] = return []
+
+> getExtra :: [Option] -> IO [String]
+> getExtra ((ExtraInc x):xs) = do fns <- getExtra xs
+>                                 return (x:fns)
+> getExtra (_:xs) = getExtra xs
+> getExtra [] = return []
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,4 +1,6 @@
 import Distribution.Simple
+import Distribution.Simple.InstallDirs
+import Distribution.Simple.LocalBuildInfo
 import Distribution.PackageDescription
 
 import System
@@ -21,6 +23,14 @@
     = do exit <- system "make -C evm clean"
          return ()
 
+addPrefix pfx var c = "export " ++ var ++ "=" ++ show pfx ++ "/" ++ c ++ ":$" ++ var
+
+postInstLib args flags desc local
+    = do let pfx = prefix (installDirTemplates local)
+         exit <- system $ "make -C evm install PREFIX=" ++ show pfx
+         return ()
+
 main = defaultMainWithHooks (simpleUserHooks { postBuild = buildLib,
-                                               postConf = postConfLib})
+                                               postConf = postConfLib,
+                                               postInst = postInstLib })
 
diff --git a/dist/build/Epic/Parser.hs b/dist/build/Epic/Parser.hs
--- a/dist/build/Epic/Parser.hs
+++ b/dist/build/Epic/Parser.hs
@@ -20,9 +20,14 @@
 import GlaExts
 #endif
 
--- parser produced by Happy Version 1.16
+-- parser produced by Happy Version 1.18.2
 
-newtype HappyAbsSyn  = HappyAbsSyn (() -> ())
+newtype HappyAbsSyn  = HappyAbsSyn HappyAny
+#if __GLASGOW_HASKELL__ >= 607
+type HappyAny = GHC.Exts.Any
+#else
+type HappyAny = forall a . a
+#endif
 happyIn4 :: ([Decl]) -> (HappyAbsSyn )
 happyIn4 x = unsafeCoerce# x
 {-# INLINE happyIn4 #-}
@@ -41,34 +46,34 @@
 happyOut6 :: (HappyAbsSyn ) -> (Decl)
 happyOut6 x = unsafeCoerce# x
 {-# INLINE happyOut6 #-}
-happyIn7 :: ([(Name,Type)]) -> (HappyAbsSyn )
+happyIn7 :: ([CGFlag]) -> (HappyAbsSyn )
 happyIn7 x = unsafeCoerce# x
 {-# INLINE happyIn7 #-}
-happyOut7 :: (HappyAbsSyn ) -> ([(Name,Type)])
+happyOut7 :: (HappyAbsSyn ) -> ([CGFlag])
 happyOut7 x = unsafeCoerce# x
 {-# INLINE happyOut7 #-}
-happyIn8 :: (Expr) -> (HappyAbsSyn )
+happyIn8 :: (CGFlag) -> (HappyAbsSyn )
 happyIn8 x = unsafeCoerce# x
 {-# INLINE happyIn8 #-}
-happyOut8 :: (HappyAbsSyn ) -> (Expr)
+happyOut8 :: (HappyAbsSyn ) -> (CGFlag)
 happyOut8 x = unsafeCoerce# x
 {-# INLINE happyOut8 #-}
-happyIn9 :: (Expr) -> (HappyAbsSyn )
+happyIn9 :: (Maybe String) -> (HappyAbsSyn )
 happyIn9 x = unsafeCoerce# x
 {-# INLINE happyIn9 #-}
-happyOut9 :: (HappyAbsSyn ) -> (Expr)
+happyOut9 :: (HappyAbsSyn ) -> (Maybe String)
 happyOut9 x = unsafeCoerce# x
 {-# INLINE happyOut9 #-}
-happyIn10 :: ([CaseAlt]) -> (HappyAbsSyn )
+happyIn10 :: ([(Name,Type)]) -> (HappyAbsSyn )
 happyIn10 x = unsafeCoerce# x
 {-# INLINE happyIn10 #-}
-happyOut10 :: (HappyAbsSyn ) -> ([CaseAlt])
+happyOut10 :: (HappyAbsSyn ) -> ([(Name,Type)])
 happyOut10 x = unsafeCoerce# x
 {-# INLINE happyOut10 #-}
-happyIn11 :: (CaseAlt) -> (HappyAbsSyn )
+happyIn11 :: (Expr) -> (HappyAbsSyn )
 happyIn11 x = unsafeCoerce# x
 {-# INLINE happyIn11 #-}
-happyOut11 :: (HappyAbsSyn ) -> (CaseAlt)
+happyOut11 :: (HappyAbsSyn ) -> (Expr)
 happyOut11 x = unsafeCoerce# x
 {-# INLINE happyOut11 #-}
 happyIn12 :: (Expr) -> (HappyAbsSyn )
@@ -77,59 +82,78 @@
 happyOut12 :: (HappyAbsSyn ) -> (Expr)
 happyOut12 x = unsafeCoerce# x
 {-# INLINE happyOut12 #-}
-happyIn13 :: ([Expr]) -> (HappyAbsSyn )
+happyIn13 :: ([CaseAlt]) -> (HappyAbsSyn )
 happyIn13 x = unsafeCoerce# x
 {-# INLINE happyIn13 #-}
-happyOut13 :: (HappyAbsSyn ) -> ([Expr])
+happyOut13 :: (HappyAbsSyn ) -> ([CaseAlt])
 happyOut13 x = unsafeCoerce# x
 {-# INLINE happyOut13 #-}
-happyIn14 :: ([(Expr,Type)]) -> (HappyAbsSyn )
+happyIn14 :: (CaseAlt) -> (HappyAbsSyn )
 happyIn14 x = unsafeCoerce# x
 {-# INLINE happyIn14 #-}
-happyOut14 :: (HappyAbsSyn ) -> ([(Expr,Type)])
+happyOut14 :: (HappyAbsSyn ) -> (CaseAlt)
 happyOut14 x = unsafeCoerce# x
 {-# INLINE happyOut14 #-}
-happyIn15 :: (Const) -> (HappyAbsSyn )
+happyIn15 :: (Expr) -> (HappyAbsSyn )
 happyIn15 x = unsafeCoerce# x
 {-# INLINE happyIn15 #-}
-happyOut15 :: (HappyAbsSyn ) -> (Const)
+happyOut15 :: (HappyAbsSyn ) -> (Expr)
 happyOut15 x = unsafeCoerce# x
 {-# INLINE happyOut15 #-}
-happyIn16 :: (LineNumber) -> (HappyAbsSyn )
+happyIn16 :: ([Expr]) -> (HappyAbsSyn )
 happyIn16 x = unsafeCoerce# x
 {-# INLINE happyIn16 #-}
-happyOut16 :: (HappyAbsSyn ) -> (LineNumber)
+happyOut16 :: (HappyAbsSyn ) -> ([Expr])
 happyOut16 x = unsafeCoerce# x
 {-# INLINE happyOut16 #-}
-happyIn17 :: (String) -> (HappyAbsSyn )
+happyIn17 :: ([(Expr,Type)]) -> (HappyAbsSyn )
 happyIn17 x = unsafeCoerce# x
 {-# INLINE happyIn17 #-}
-happyOut17 :: (HappyAbsSyn ) -> (String)
+happyOut17 :: (HappyAbsSyn ) -> ([(Expr,Type)])
 happyOut17 x = unsafeCoerce# x
 {-# INLINE happyOut17 #-}
-happyInTok :: Token -> (HappyAbsSyn )
+happyIn18 :: (Const) -> (HappyAbsSyn )
+happyIn18 x = unsafeCoerce# x
+{-# INLINE happyIn18 #-}
+happyOut18 :: (HappyAbsSyn ) -> (Const)
+happyOut18 x = unsafeCoerce# x
+{-# INLINE happyOut18 #-}
+happyIn19 :: (LineNumber) -> (HappyAbsSyn )
+happyIn19 x = unsafeCoerce# x
+{-# INLINE happyIn19 #-}
+happyOut19 :: (HappyAbsSyn ) -> (LineNumber)
+happyOut19 x = unsafeCoerce# x
+{-# INLINE happyOut19 #-}
+happyIn20 :: (String) -> (HappyAbsSyn )
+happyIn20 x = unsafeCoerce# x
+{-# INLINE happyIn20 #-}
+happyOut20 :: (HappyAbsSyn ) -> (String)
+happyOut20 x = unsafeCoerce# x
+{-# INLINE happyOut20 #-}
+happyInTok :: (Token) -> (HappyAbsSyn )
 happyInTok x = unsafeCoerce# x
 {-# INLINE happyInTok #-}
-happyOutTok :: (HappyAbsSyn ) -> Token
+happyOutTok :: (HappyAbsSyn ) -> (Token)
 happyOutTok x = unsafeCoerce# x
 {-# INLINE happyOutTok #-}
 
+
 happyActOffsets :: HappyAddr
-happyActOffsets = HappyA# "\x01\x00\x04\x00\x00\x00\x04\x01\x1f\x01\x21\x01\xe2\x00\x01\x00\x12\x01\x01\x00\x00\x00\xf0\x00\x00\x00\x0d\x01\xe1\x00\xc6\x00\xff\x00\x00\x00\x00\x00\xce\x00\x20\x01\xae\x00\x20\x01\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5\x00\x20\x01\xd5\x00\xaa\x00\x4b\x00\x00\x00\x00\x00\xda\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x00\xbb\x00\x4b\x00\x4b\x00\x94\x00\x20\x01\xac\x00\x00\x00\x4b\x00\xb0\x00\x00\x00\xa7\x00\x28\x00\x62\x00\x4d\x00\x77\x00\x84\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\x05\x00\xa2\x00\x05\x00\xf6\x00\x00\x00\xed\xff\xed\xff\xed\xff\xed\xff\xe8\x00\xe1\xff\xe1\xff\xef\xff\xef\xff\x91\x00\x80\x00\x05\x00\x20\x01\x76\x00\x05\x00\xcc\x00\x72\x00\x65\x00\x00\x00\x05\x00\x00\x00\x05\x00\x70\x00\x2e\x00\x59\x00\x5f\x00\x00\x00\x05\x00\x00\x00\x00\x00\x05\x00\x61\x00\x51\x00\x75\x00\x3c\x00\x05\x00\x5e\x00\x9f\x00\x5d\x00\x00\x00\x20\x01\x4f\x00\xbe\x00\x05\x00\x4e\x00\x2e\x00\x00\x00\x83\x00\x05\x00\x00\x00\x6e\x00\xbe\x00\x00\x00\x35\x00\x05\x00\x44\x00\xbe\x00\x26\x00\x00\x00\x05\x00\xbe\x00\x00\x00"#
+happyActOffsets = HappyA# "\xce\x01\x05\x00\x00\x00\xdf\xff\x2d\x01\x2c\x01\x23\x01\xe1\x00\x01\x01\x1d\x01\xce\x01\x00\x00\x00\x00\xf7\x00\x00\x00\x1c\x01\xdf\xff\x00\x00\x00\x00\x00\x00\xe7\x00\x13\x01\x00\x00\x00\x00\xe5\x00\xd8\x00\xfb\x00\xd6\x00\x3d\x01\xc8\x00\x3d\x01\xc5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x00\x3d\x01\xf6\x00\x00\x00\x00\x00\xbb\x00\x01\x00\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\x00\xe9\x00\x01\x00\x01\x00\xc4\x00\x00\x00\xe8\xff\xc2\x00\x3d\x01\xe2\x00\x00\x00\x01\x00\x01\x00\x01\x00\xe6\xff\x76\x00\xb2\x00\xd3\x00\x00\x00\xd7\x00\x01\x00\x3d\x01\x01\x00\x01\x00\x18\x00\x03\x00\xa1\x00\xaf\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\xd4\x00\x01\x00\x03\x01\x00\x00\xe3\xff\xe3\xff\xe3\xff\xe3\xff\xf3\x00\xe6\xff\xe6\xff\x0d\x01\x0d\x01\x9e\x00\x01\x00\x3d\x01\xa2\x00\x01\x00\x66\x00\xc0\x00\xc3\x00\xad\x00\x9d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x94\x00\x00\x00\x01\x00\x2c\x00\x2a\x00\x85\x00\x8c\x00\x00\x00\x00\x00\x01\x00\x8b\x00\x6c\x00\x77\x00\x9f\x00\x71\x00\x01\x00\x56\x00\x01\x00\x9a\x00\x79\x00\x00\x00\x3d\x01\x6f\x00\x00\x00\x01\x00\xe3\x00\x01\x00\x6b\x00\x01\x00\x2a\x00\x00\x00\x43\x00\x01\x00\x00\x00\xe3\x00\x86\x00\xe3\x00\x8a\x00\x00\x00\x40\x00\x01\x00\x00\x00\x69\x00\xe3\x00\x30\x00\x00\x00\x01\x00\xe3\x00\x00\x00"#
 
 happyGotoOffsets :: HappyAddr
-happyGotoOffsets = HappyA# "\x32\x00\x5b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x56\x00\x00\x00\x00\x00\x54\x00\x49\x00\x00\x00\x00\x00\x45\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3e\x00\x34\x00\x00\x00\xaf\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x01\xa5\x01\x00\x00\x1b\x00\x00\x00\x00\x00\x9d\x01\x00\x00\x00\x00\x00\x00\x9b\x01\x00\x00\x00\x00\x00\x00\x00\x00\x4b\x01\x93\x01\x91\x01\x89\x01\x87\x01\x7f\x01\x7d\x01\x75\x01\x73\x01\x6b\x01\x00\x00\x69\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x43\x01\x0d\x00\x00\x00\x61\x01\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x01\x00\x00\x39\x01\x00\x00\x2f\x00\x00\x00\x00\x00\x00\x00\x31\x01\x00\x00\x00\x00\x5f\x01\x00\x00\x00\x00\x00\x00\x00\x00\x57\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x55\x01\x00\x00\x1c\x00\x00\x00\x00\x00\x4d\x01\x00\x00\xfe\xff\x00\x00\x00\x00\x00\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5a\x00\x00\x00\x00\x00"#
+happyGotoOffsets = HappyA# "\x04\x02\x09\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x00\x65\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x50\x00\x00\x00\x00\x00\x00\x00\xf7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x01\xed\x01\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\xeb\x01\x73\x01\xe3\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x01\x4e\x00\xd9\x01\xd7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x01\xcf\x01\xcd\x01\xc5\x01\xc3\x01\xbb\x01\xb9\x01\xb1\x01\xaf\x01\xa7\x01\x00\x00\xa5\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x01\x39\x00\x00\x00\x9d\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x01\x00\x00\x53\x01\x00\x00\x00\x00\x00\x00\x9b\x01\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x01\x00\x00\x4b\x01\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x00\x00\x89\x01\x00\x00\x87\x01\x00\x00\x7f\x01\x0b\x00\x00\x00\x00\x00\x7d\x01\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x01\x00\x00\x00\x00"#
 
 happyDefActions :: HappyAddr
-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\x00\x00\x00\x00\xfd\xff\x00\x00\xed\xff\xec\xff\x00\x00\x00\x00\xec\xff\xbb\xff\xfc\xff\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xff\xfb\xff\xfa\xff\xf9\xff\xf8\xff\xf7\xff\xf6\xff\xf5\xff\xf4\xff\xf3\xff\xf0\xff\xf1\xff\xf2\xff\x00\x00\x00\x00\xec\xff\x00\x00\x00\x00\xea\xff\xee\xff\xef\xff\xde\xff\xdd\xff\xe3\xff\xe9\xff\xbe\xff\xc4\xff\xc3\xff\xc1\xff\xc0\xff\xbf\xff\xc2\xff\xbd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xff\x00\x00\x00\x00\xdc\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xff\xe2\xff\xce\xff\xcf\xff\xcc\xff\xcd\xff\xcb\xff\xd0\xff\xd1\xff\xd2\xff\xd3\xff\xc9\xff\x00\x00\xca\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xff\x00\x00\xe8\xff\xc7\xff\xe5\xff\xca\xff\x00\x00\xd8\xff\x00\x00\x00\x00\xe7\xff\xca\xff\xc8\xff\xe4\xff\x00\x00\x00\x00\xd7\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xff\x00\x00\xe7\xff\xdf\xff\x00\x00\x00\x00\xd8\xff\xd9\xff\x00\x00\x00\x00\xd6\xff\xec\xff\xd4\xff\xe6\xff\xc6\xff\xc7\xff\x00\x00\xe1\xff\x00\x00\xc5\xff\x00\x00\xd5\xff"#
+happyDefActions = HappyA# "\xe8\xff\x00\x00\x00\x00\xec\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xff\x00\x00\xe8\xff\xfd\xff\xe7\xff\x00\x00\xed\xff\x00\x00\xec\xff\xe9\xff\xea\xff\xeb\xff\x00\x00\xe6\xff\xae\xff\xfc\xff\x00\x00\x00\x00\xe6\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xff\xfb\xff\xfa\xff\xf9\xff\xf8\xff\xf7\xff\xf6\xff\xf5\xff\xf4\xff\xf3\xff\xf0\xff\xf1\xff\xf2\xff\x00\x00\x00\x00\xe6\xff\xee\xff\xe4\xff\x00\x00\x00\x00\xef\xff\xd5\xff\xd4\xff\xdc\xff\xe3\xff\xb2\xff\xb8\xff\xb7\xff\xb5\xff\xb4\xff\xb3\xff\xb6\xff\xb1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd2\xff\x00\x00\xbe\xff\x00\x00\xc6\xff\xbd\xff\x00\x00\x00\x00\xd3\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xff\xdb\xff\xc2\xff\xc3\xff\xc0\xff\xc1\xff\xbf\xff\xc4\xff\xc5\xff\xc7\xff\xc8\xff\x00\x00\xbe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xff\xe0\xff\xbe\xff\xbc\xff\xbb\xff\xde\xff\x00\x00\xdf\xff\x00\x00\x00\x00\xce\xff\x00\x00\x00\x00\xe1\xff\xdd\xff\x00\x00\x00\x00\xcd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xff\x00\x00\x00\x00\xd1\xff\x00\x00\x00\x00\xd7\xff\x00\x00\xd8\xff\x00\x00\x00\x00\x00\x00\xce\xff\xcf\xff\x00\x00\x00\x00\xcc\xff\xca\xff\xe6\xff\xc9\xff\x00\x00\xd0\xff\xba\xff\xbb\xff\xd6\xff\x00\x00\xda\xff\x00\x00\xb9\xff\x00\x00\xcb\xff"#
 
 happyCheck :: HappyAddr
-happyCheck = HappyA# "\xff\xff\x03\x00\x01\x00\x01\x00\x23\x00\x01\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x01\x00\x00\x00\x23\x00\x02\x00\x23\x00\x32\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x29\x00\x2a\x00\x15\x00\x16\x00\x01\x00\x18\x00\x19\x00\x32\x00\x1b\x00\x32\x00\x06\x00\x07\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x00\x00\x00\x00\x02\x00\x02\x00\x06\x00\x07\x00\x03\x00\x37\x00\x38\x00\x39\x00\x37\x00\x38\x00\x15\x00\x16\x00\x01\x00\x18\x00\x19\x00\x01\x00\x1b\x00\x16\x00\x17\x00\x01\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x04\x00\x05\x00\x0d\x00\x03\x00\x08\x00\x03\x00\x0a\x00\x0b\x00\x36\x00\x02\x00\x04\x00\x05\x00\x15\x00\x16\x00\x08\x00\x18\x00\x19\x00\x0b\x00\x1b\x00\x1a\x00\x24\x00\x34\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x01\x00\x23\x00\x23\x00\x36\x00\x24\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x03\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x1c\x00\x32\x00\x33\x00\x24\x00\x24\x00\x24\x00\x2b\x00\x23\x00\x35\x00\x26\x00\x23\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x1d\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x24\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x25\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x1e\x00\x32\x00\x33\x00\x24\x00\x03\x00\x23\x00\x23\x00\x31\x00\x02\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x02\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x23\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x01\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x34\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x03\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x23\x00\x24\x00\x2b\x00\x01\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x36\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x36\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x34\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x24\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x31\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x01\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x24\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x01\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x23\x00\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x33\x00\x3a\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x02\x00\x01\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x23\x00\x32\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x04\x00\x05\x00\xff\xff\xff\xff\x08\x00\x09\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\x09\x00\x08\x00\x0b\x00\x0a\x00\x0b\x00\x04\x00\x05\x00\xff\xff\xff\xff\x08\x00\x09\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\x09\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\x04\x00\x05\x00\x08\x00\xff\xff\x08\x00\x0b\x00\xff\xff\x0b\x00\x04\x00\x05\x00\xff\xff\xff\xff\x08\x00\xff\xff\xff\xff\x0b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
+happyCheck = HappyA# "\xff\xff\x22\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x27\x00\x02\x00\x24\x00\x27\x00\x05\x00\x27\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x09\x00\x0a\x00\x15\x00\x16\x00\x06\x00\x18\x00\x19\x00\x38\x00\x1b\x00\x1a\x00\x38\x00\x1e\x00\x1f\x00\x42\x00\x21\x00\x01\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x00\x00\x27\x00\x02\x00\x2b\x00\x03\x00\x05\x00\x2e\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x1c\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x01\x00\x38\x00\x39\x00\x09\x00\x0a\x00\x27\x00\x16\x00\x17\x00\x3d\x00\x3e\x00\x3f\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x1d\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x01\x00\x38\x00\x39\x00\x00\x00\x27\x00\x02\x00\x01\x00\x06\x00\x05\x00\x01\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x01\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x20\x00\x38\x00\x39\x00\x01\x00\x07\x00\x08\x00\x06\x00\x27\x00\x0b\x00\x3c\x00\x0d\x00\x0e\x00\x10\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x06\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x3a\x00\x38\x00\x39\x00\x27\x00\x28\x00\x03\x00\x04\x00\x03\x00\x04\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x01\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x3a\x00\x28\x00\x27\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x28\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x3a\x00\x28\x00\x03\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x3b\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x3c\x00\x38\x00\x39\x00\x3a\x00\x27\x00\x28\x00\x3c\x00\x28\x00\x2a\x00\x31\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x27\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x27\x00\x02\x00\x28\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x29\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x27\x00\x28\x00\x27\x00\x03\x00\x37\x00\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x2c\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x02\x00\x38\x00\x39\x00\x27\x00\x28\x00\x27\x00\x01\x00\x27\x00\x31\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x03\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x01\x00\x38\x00\x39\x00\x27\x00\x28\x00\x01\x00\x3c\x00\x28\x00\x3a\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x3c\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x28\x00\x27\x00\x37\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x01\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x01\x00\x27\x00\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x43\x00\x02\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x01\x00\xff\xff\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x27\x00\xff\xff\x33\x00\x34\x00\x35\x00\x36\x00\xff\xff\x38\x00\x2f\x00\x30\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\xff\xff\x43\x00\x38\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\x0c\x00\xff\xff\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\x0c\x00\xff\xff\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\x0c\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\x0c\x00\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\x00\x00\x0e\x00\x02\x00\xff\xff\xff\xff\x05\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
 
 happyTable :: HappyAddr
-happyTable = HappyA# "\x00\x00\x8e\x00\x04\x00\x8c\x00\x4a\x00\x04\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x6f\x00\x11\x00\x4a\x00\x07\x00\x4a\x00\x54\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4d\x00\x4e\x00\x38\x00\x39\x00\x43\x00\x3a\x00\x3b\x00\x54\x00\x3c\x00\x54\x00\x88\x00\x77\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x68\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x0a\x00\x06\x00\x07\x00\x07\x00\x76\x00\x77\x00\x29\x00\x05\x00\x06\x00\x09\x00\x05\x00\x06\x00\x38\x00\x39\x00\x2a\x00\x3a\x00\x3b\x00\x27\x00\x3c\x00\x79\x00\x7a\x00\x17\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x7c\x00\x2c\x00\x12\x00\x13\x00\x2d\x00\x0e\x00\x91\x00\x2e\x00\x93\x00\x02\x00\x93\x00\x2c\x00\x38\x00\x39\x00\x2d\x00\x3a\x00\x3b\x00\x2e\x00\x3c\x00\x65\x00\x91\x00\x8e\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x10\x00\x4a\x00\x8a\x00\x83\x00\x8c\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x84\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x66\x00\x54\x00\x55\x00\x7f\x00\x81\x00\x75\x00\x76\x00\x4a\x00\x85\x00\x86\x00\x6b\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x7b\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\x6c\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x6f\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x88\x00\x54\x00\x55\x00\x72\x00\x57\x00\x4a\x00\x63\x00\x64\x00\x69\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x43\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\x45\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x48\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\x73\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x49\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x80\x00\x54\x00\x55\x00\x4a\x00\x6a\x00\x29\x00\x10\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x26\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\x17\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x27\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x6d\x00\x54\x00\x55\x00\x25\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x15\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\x10\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x16\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\x10\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x11\x00\x0a\x00\x50\x00\x51\x00\x52\x00\x53\x00\x4a\x00\x54\x00\x55\x00\xff\xff\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x0d\x00\x0c\x00\x50\x00\x51\x00\x52\x00\x53\x00\x0e\x00\x54\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x60\x00\x2c\x00\x00\x00\x00\x00\x2d\x00\x73\x00\x00\x00\x2e\x00\x60\x00\x2c\x00\x7c\x00\x2c\x00\x2d\x00\x7b\x00\x2d\x00\x2e\x00\x7d\x00\x2e\x00\x60\x00\x2c\x00\x00\x00\x00\x00\x2d\x00\x70\x00\x00\x00\x2e\x00\x60\x00\x2c\x00\x8f\x00\x2c\x00\x2d\x00\x61\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x8a\x00\x2c\x00\x81\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x86\x00\x2c\x00\x6d\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x55\x00\x2c\x00\x57\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x58\x00\x2c\x00\x59\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x5a\x00\x2c\x00\x5b\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x5c\x00\x2c\x00\x5d\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x5e\x00\x2c\x00\x5f\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x66\x00\x2c\x00\x41\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x45\x00\x2c\x00\x46\x00\x2c\x00\x2d\x00\x00\x00\x2d\x00\x2e\x00\x00\x00\x2e\x00\x2b\x00\x2c\x00\x00\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x2e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+happyTable = HappyA# "\x00\x00\x12\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x5d\x00\x02\x00\x56\x00\x5d\x00\x03\x00\x57\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xa4\x00\x8e\x00\x40\x00\x41\x00\xad\x00\x42\x00\x43\x00\x67\x00\x44\x00\x77\x00\x67\x00\x45\x00\x46\x00\x13\x00\x47\x00\xaa\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x16\x00\x5d\x00\x08\x00\x4d\x00\x90\x00\x03\x00\x4e\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x78\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x88\x00\x67\x00\x68\x00\x8d\x00\x8e\x00\x5d\x00\x91\x00\x92\x00\x05\x00\x06\x00\x07\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x93\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x7a\x00\x67\x00\x68\x00\x0b\x00\x5d\x00\x08\x00\x53\x00\x30\x00\x03\x00\x31\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x2f\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xa4\x00\x67\x00\x68\x00\x1f\x00\x95\x00\x34\x00\x1b\x00\x5d\x00\x35\x00\xb2\x00\xb0\x00\x36\x00\x17\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x18\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xac\x00\x67\x00\x68\x00\x5d\x00\x9b\x00\x13\x00\x10\x00\x0f\x00\x10\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1a\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x9c\x00\xb0\x00\xa7\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xaa\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x86\x00\x98\x00\x9f\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xa1\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x9e\x00\x67\x00\x68\x00\x80\x00\x5d\x00\xad\x00\xa0\x00\x8c\x00\xa2\x00\x8d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x95\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x82\x00\x84\x00\x8b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x88\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x99\x00\x67\x00\x68\x00\x5d\x00\x83\x00\x75\x00\x6a\x00\x76\x00\x7d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x7f\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x53\x00\x67\x00\x68\x00\x5d\x00\x85\x00\x55\x00\x5b\x00\x58\x00\x33\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x5c\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x1a\x00\x67\x00\x68\x00\x5d\x00\x7e\x00\x1a\x00\x2e\x00\x2d\x00\x2f\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1f\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x1e\x00\x1b\x00\x1d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1a\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x15\x00\x16\x00\x0b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xff\xff\x0d\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x0e\x00\x00\x00\x0f\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x5d\x00\x00\x00\x63\x00\x64\x00\x65\x00\x66\x00\x00\x00\x67\x00\x60\x00\x61\x00\x05\x00\x06\x00\x07\x00\x00\x00\x0a\x00\x00\x00\xfe\xff\x67\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x95\x00\x34\x00\x00\x00\x00\x00\x35\x00\x00\x00\x99\x00\x36\x00\x95\x00\x34\x00\x00\x00\x00\x00\x35\x00\x00\x00\x96\x00\x36\x00\x4f\x00\x34\x00\x00\x00\x00\x00\x35\x00\x80\x00\x00\x00\x36\x00\x4f\x00\x34\x00\x00\x00\x00\x00\x35\x00\x89\x00\x00\x00\x36\x00\x4f\x00\x34\x00\x00\x00\x00\x00\x35\x00\x73\x00\x00\x00\x36\x00\x4f\x00\x34\x00\xb2\x00\x34\x00\x35\x00\x50\x00\x35\x00\x36\x00\x00\x00\x36\x00\xae\x00\x34\x00\xa5\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\xa7\x00\x34\x00\xa8\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x9c\x00\x34\x00\xa2\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x93\x00\x34\x00\x86\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x68\x00\x34\x00\x6a\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x6b\x00\x34\x00\x6c\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x6d\x00\x34\x00\x6e\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x6f\x00\x34\x00\x70\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x71\x00\x34\x00\x72\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x78\x00\x34\x00\x79\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x7b\x00\x34\x00\x4e\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x51\x00\x34\x00\x58\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x59\x00\x34\x00\x33\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x07\x00\x36\x00\x08\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x06\x00\x07\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
 
-happyReduceArr = array (1, 68) [
+happyReduceArr = array (1, 81) [
 	(1 , happyReduce_1),
 	(2 , happyReduce_2),
 	(3 , happyReduce_3),
@@ -197,11 +221,24 @@
 	(65 , happyReduce_65),
 	(66 , happyReduce_66),
 	(67 , happyReduce_67),
-	(68 , happyReduce_68)
+	(68 , happyReduce_68),
+	(69 , happyReduce_69),
+	(70 , happyReduce_70),
+	(71 , happyReduce_71),
+	(72 , happyReduce_72),
+	(73 , happyReduce_73),
+	(74 , happyReduce_74),
+	(75 , happyReduce_75),
+	(76 , happyReduce_76),
+	(77 , happyReduce_77),
+	(78 , happyReduce_78),
+	(79 , happyReduce_79),
+	(80 , happyReduce_80),
+	(81 , happyReduce_81)
 	]
 
-happy_n_terms = 59 :: Int
-happy_n_nonterms = 14 :: Int
+happy_n_terms = 68 :: Int
+happy_n_nonterms = 17 :: Int
 
 happyReduce_1 = happySpecReduce_1  0# happyReduction_1
 happyReduction_1 happy_x_1
@@ -227,7 +264,7 @@
 	happyRest) tk
 	 = happyThen (case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
 	case happyOut4 happy_x_3 of { happy_var_3 -> 
-	case happyOut17 happy_x_4 of { happy_var_4 -> 
+	case happyOut20 happy_x_4 of { happy_var_4 -> 
 	(
  	   let rest = happy_var_3 in
 	   let pt = unsafePerformIO (readFile happy_var_2) in
@@ -308,8 +345,10 @@
 		 (TyFun
 	)
 
-happyReduce_16 = happyReduce 8# 2# happyReduction_16
-happyReduction_16 (happy_x_8 `HappyStk`
+happyReduce_16 = happyReduce 10# 2# happyReduction_16
+happyReduction_16 (happy_x_10 `HappyStk`
+	happy_x_9 `HappyStk`
+	happy_x_8 `HappyStk`
 	happy_x_7 `HappyStk`
 	happy_x_6 `HappyStk`
 	happy_x_5 `HappyStk`
@@ -318,13 +357,15 @@
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	case happyOut5 happy_x_6 of { happy_var_6 -> 
-	case happyOut8 happy_x_8 of { happy_var_8 -> 
+	 = case happyOut9 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_2 of { happy_var_2 -> 
+	case happyOutTok happy_x_3 of { (TokenName happy_var_3) -> 
+	case happyOut10 happy_x_5 of { happy_var_5 -> 
+	case happyOut5 happy_x_8 of { happy_var_8 -> 
+	case happyOut11 happy_x_10 of { happy_var_10 -> 
 	happyIn6
-		 (mkBind happy_var_1 (map snd happy_var_3) happy_var_6 (map fst happy_var_3) happy_var_8
-	) `HappyStk` happyRest}}}}
+		 (mkBind happy_var_3 (map snd happy_var_5) happy_var_8 (map fst happy_var_5) happy_var_10 happy_var_1 happy_var_2
+	) `HappyStk` happyRest}}}}}}
 
 happyReduce_17 = happyReduce 7# 2# happyReduction_17
 happyReduction_17 (happy_x_7 `HappyStk`
@@ -336,7 +377,7 @@
 	happy_x_1 `HappyStk`
 	happyRest)
 	 = case happyOutTok happy_x_2 of { (TokenName happy_var_2) -> 
-	case happyOut7 happy_x_4 of { happy_var_4 -> 
+	case happyOut10 happy_x_4 of { happy_var_4 -> 
 	case happyOut5 happy_x_7 of { happy_var_7 -> 
 	happyIn6
 		 (mkExtern happy_var_2 (map snd happy_var_4) happy_var_7 (map fst happy_var_4)
@@ -355,18 +396,57 @@
 		 ([]
 	)
 
-happyReduce_20 = happySpecReduce_3  3# happyReduction_20
-happyReduction_20 happy_x_3
+happyReduce_20 = happySpecReduce_2  3# happyReduction_20
+happyReduction_20 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_2 of { happy_var_2 -> 
+	happyIn7
+		 (happy_var_1:happy_var_2
+	)}}
+
+happyReduce_21 = happySpecReduce_1  4# happyReduction_21
+happyReduction_21 happy_x_1
+	 =  happyIn8
+		 (Inline
+	)
+
+happyReduce_22 = happySpecReduce_1  4# happyReduction_22
+happyReduction_22 happy_x_1
+	 =  happyIn8
+		 (Strict
+	)
+
+happyReduce_23 = happySpecReduce_0  5# happyReduction_23
+happyReduction_23  =  happyIn9
+		 (Nothing
+	)
+
+happyReduce_24 = happySpecReduce_2  5# happyReduction_24
+happyReduction_24 happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
+	happyIn9
+		 (Just happy_var_2
+	)}
+
+happyReduce_25 = happySpecReduce_0  6# happyReduction_25
+happyReduction_25  =  happyIn10
+		 ([]
+	)
+
+happyReduce_26 = happySpecReduce_3  6# happyReduction_26
+happyReduction_26 happy_x_3
 	happy_x_2
 	happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
 	case happyOut5 happy_x_3 of { happy_var_3 -> 
-	happyIn7
+	happyIn10
 		 ([(happy_var_1,happy_var_3)]
 	)}}
 
-happyReduce_21 = happyReduce 5# 3# happyReduction_21
-happyReduction_21 (happy_x_5 `HappyStk`
+happyReduce_27 = happyReduce 5# 6# happyReduction_27
+happyReduction_27 (happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
@@ -374,97 +454,102 @@
 	happyRest)
 	 = case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
 	case happyOut5 happy_x_3 of { happy_var_3 -> 
-	case happyOut7 happy_x_5 of { happy_var_5 -> 
-	happyIn7
+	case happyOut10 happy_x_5 of { happy_var_5 -> 
+	happyIn10
 		 ((happy_var_1,happy_var_3):happy_var_5
 	) `HappyStk` happyRest}}}
 
-happyReduce_22 = happySpecReduce_1  4# happyReduction_22
-happyReduction_22 happy_x_1
+happyReduce_28 = happySpecReduce_1  7# happyReduction_28
+happyReduction_28 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
-	happyIn8
+	happyIn11
 		 (R happy_var_1
 	)}
 
-happyReduce_23 = happySpecReduce_3  4# happyReduction_23
-happyReduction_23 happy_x_3
+happyReduce_29 = happySpecReduce_3  7# happyReduction_29
+happyReduction_29 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_2 of { happy_var_2 -> 
-	happyIn8
+	 =  case happyOut11 happy_x_2 of { happy_var_2 -> 
+	happyIn11
 		 (happy_var_2
 	)}
 
-happyReduce_24 = happyReduce 4# 4# happyReduction_24
-happyReduction_24 (happy_x_4 `HappyStk`
+happyReduce_30 = happyReduce 4# 7# happyReduction_30
+happyReduction_30 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut13 happy_x_3 of { happy_var_3 -> 
-	happyIn8
+	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut16 happy_x_3 of { happy_var_3 -> 
+	happyIn11
 		 (App happy_var_1 happy_var_3
 	) `HappyStk` happyRest}}
 
-happyReduce_25 = happyReduce 7# 4# happyReduction_25
-happyReduction_25 (happy_x_7 `HappyStk`
-	happy_x_6 `HappyStk`
-	happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
+happyReduce_31 = happySpecReduce_3  7# happyReduction_31
+happyReduction_31 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut16 happy_x_2 of { happy_var_2 -> 
+	happyIn11
+		 (Con 0 happy_var_2
+	)}
+
+happyReduce_32 = happyReduce 4# 7# happyReduction_32
+happyReduction_32 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut8 happy_x_3 of { happy_var_3 -> 
-	case happyOut13 happy_x_5 of { happy_var_5 -> 
-	happyIn8
-		 (LazyApp happy_var_3 happy_var_5
-	) `HappyStk` happyRest}}
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (Lazy happy_var_3
+	) `HappyStk` happyRest}
 
-happyReduce_26 = happyReduce 4# 4# happyReduction_26
-happyReduction_26 (happy_x_4 `HappyStk`
+happyReduce_33 = happyReduce 4# 7# happyReduction_33
+happyReduction_33 (happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOutTok happy_x_3 of { (TokenName happy_var_3) -> 
-	happyIn8
-		 (LazyApp (R happy_var_3) []
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (Effect happy_var_3
 	) `HappyStk` happyRest}
 
-happyReduce_27 = happyReduce 5# 4# happyReduction_27
-happyReduction_27 (happy_x_5 `HappyStk`
+happyReduce_34 = happyReduce 5# 7# happyReduction_34
+happyReduction_34 (happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
 	 = case happyOutTok happy_x_2 of { (TokenInt happy_var_2) -> 
-	case happyOut13 happy_x_4 of { happy_var_4 -> 
-	happyIn8
+	case happyOut16 happy_x_4 of { happy_var_4 -> 
+	happyIn11
 		 (Con happy_var_2 happy_var_4
 	) `HappyStk` happyRest}}
 
-happyReduce_28 = happySpecReduce_1  4# happyReduction_28
-happyReduction_28 happy_x_1
-	 =  case happyOut15 happy_x_1 of { happy_var_1 -> 
-	happyIn8
+happyReduce_35 = happySpecReduce_1  7# happyReduction_35
+happyReduction_35 happy_x_1
+	 =  case happyOut18 happy_x_1 of { happy_var_1 -> 
+	happyIn11
 		 (Const happy_var_1
 	)}
 
-happyReduce_29 = happySpecReduce_3  4# happyReduction_29
-happyReduction_29 happy_x_3
+happyReduce_36 = happySpecReduce_3  7# happyReduction_36
+happyReduction_36 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
 	case happyOutTok happy_x_3 of { (TokenInt happy_var_3) -> 
-	happyIn8
+	happyIn11
 		 (Proj happy_var_1 happy_var_3
 	)}}
 
-happyReduce_30 = happyReduce 8# 4# happyReduction_30
-happyReduction_30 (happy_x_8 `HappyStk`
+happyReduce_37 = happyReduce 8# 7# happyReduction_37
+happyReduction_37 (happy_x_8 `HappyStk`
 	happy_x_7 `HappyStk`
 	happy_x_6 `HappyStk`
 	happy_x_5 `HappyStk`
@@ -475,67 +560,98 @@
 	happyRest)
 	 = case happyOutTok happy_x_2 of { (TokenName happy_var_2) -> 
 	case happyOut5 happy_x_4 of { happy_var_4 -> 
-	case happyOut8 happy_x_6 of { happy_var_6 -> 
-	case happyOut8 happy_x_8 of { happy_var_8 -> 
-	happyIn8
+	case happyOut11 happy_x_6 of { happy_var_6 -> 
+	case happyOut11 happy_x_8 of { happy_var_8 -> 
+	happyIn11
 		 (Let happy_var_2 happy_var_4 happy_var_6 happy_var_8
 	) `HappyStk` happyRest}}}}
 
-happyReduce_31 = happySpecReduce_3  4# happyReduction_31
-happyReduction_31 happy_x_3
+happyReduce_38 = happySpecReduce_3  7# happyReduction_38
+happyReduction_38 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn8
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn11
 		 (Let (MN "unused" 0) TyUnit happy_var_1 happy_var_3
 	)}}
 
-happyReduce_32 = happyReduce 6# 4# happyReduction_32
-happyReduction_32 (happy_x_6 `HappyStk`
+happyReduce_39 = happyReduce 6# 7# happyReduction_39
+happyReduction_39 (happy_x_6 `HappyStk`
 	happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut8 happy_x_2 of { happy_var_2 -> 
-	case happyOut8 happy_x_4 of { happy_var_4 -> 
-	case happyOut8 happy_x_6 of { happy_var_6 -> 
-	happyIn8
+	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
+	case happyOut11 happy_x_4 of { happy_var_4 -> 
+	case happyOut11 happy_x_6 of { happy_var_6 -> 
+	happyIn11
 		 (If happy_var_2 happy_var_4 happy_var_6
 	) `HappyStk` happyRest}}}
 
-happyReduce_33 = happySpecReduce_1  4# happyReduction_33
-happyReduction_33 happy_x_1
-	 =  case happyOut9 happy_x_1 of { happy_var_1 -> 
-	happyIn8
+happyReduce_40 = happyReduce 6# 7# happyReduction_40
+happyReduction_40 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	case happyOut11 happy_x_5 of { happy_var_5 -> 
+	happyIn11
+		 (While happy_var_3 happy_var_5
+	) `HappyStk` happyRest}}
+
+happyReduce_41 = happyReduce 8# 7# happyReduction_41
+happyReduction_41 (happy_x_8 `HappyStk`
+	happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	case happyOut11 happy_x_5 of { happy_var_5 -> 
+	case happyOut11 happy_x_7 of { happy_var_7 -> 
+	happyIn11
+		 (WhileAcc happy_var_3 happy_var_5 happy_var_7
+	) `HappyStk` happyRest}}}
+
+happyReduce_42 = happySpecReduce_1  7# happyReduction_42
+happyReduction_42 happy_x_1
+	 =  case happyOut12 happy_x_1 of { happy_var_1 -> 
+	happyIn11
 		 (happy_var_1
 	)}
 
-happyReduce_34 = happySpecReduce_1  4# happyReduction_34
-happyReduction_34 happy_x_1
-	 =  case happyOut12 happy_x_1 of { happy_var_1 -> 
-	happyIn8
+happyReduce_43 = happySpecReduce_1  7# happyReduction_43
+happyReduction_43 happy_x_1
+	 =  case happyOut15 happy_x_1 of { happy_var_1 -> 
+	happyIn11
 		 (happy_var_1
 	)}
 
-happyReduce_35 = happySpecReduce_2  4# happyReduction_35
-happyReduction_35 happy_x_2
+happyReduce_44 = happySpecReduce_2  7# happyReduction_44
+happyReduction_44 happy_x_2
 	happy_x_1
 	 =  case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
-	happyIn8
+	happyIn11
 		 (Error happy_var_2
 	)}
 
-happyReduce_36 = happySpecReduce_1  4# happyReduction_36
-happyReduction_36 happy_x_1
-	 =  happyIn8
+happyReduce_45 = happySpecReduce_1  7# happyReduction_45
+happyReduction_45 happy_x_1
+	 =  happyIn11
 		 (Impossible
 	)
 
-happyReduce_37 = happyReduce 6# 4# happyReduction_37
-happyReduction_37 (happy_x_6 `HappyStk`
+happyReduce_46 = happyReduce 6# 7# happyReduction_46
+happyReduction_46 (happy_x_6 `HappyStk`
 	happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
@@ -544,49 +660,65 @@
 	happyRest)
 	 = case happyOut5 happy_x_2 of { happy_var_2 -> 
 	case happyOutTok happy_x_3 of { (TokenString happy_var_3) -> 
-	case happyOut14 happy_x_5 of { happy_var_5 -> 
-	happyIn8
+	case happyOut17 happy_x_5 of { happy_var_5 -> 
+	happyIn11
 		 (ForeignCall happy_var_2 happy_var_3 happy_var_5
 	) `HappyStk` happyRest}}}
 
-happyReduce_38 = happyReduce 6# 5# happyReduction_38
-happyReduction_38 (happy_x_6 `HappyStk`
+happyReduce_47 = happyReduce 7# 7# happyReduction_47
+happyReduction_47 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
 	happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut8 happy_x_2 of { happy_var_2 -> 
-	case happyOut10 happy_x_5 of { happy_var_5 -> 
-	happyIn9
+	 = case happyOut5 happy_x_3 of { happy_var_3 -> 
+	case happyOutTok happy_x_4 of { (TokenString happy_var_4) -> 
+	case happyOut17 happy_x_6 of { happy_var_6 -> 
+	happyIn11
+		 (LazyForeignCall happy_var_3 happy_var_4 happy_var_6
+	) `HappyStk` happyRest}}}
+
+happyReduce_48 = happyReduce 6# 8# happyReduction_48
+happyReduction_48 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
+	case happyOut13 happy_x_5 of { happy_var_5 -> 
+	happyIn12
 		 (Case happy_var_2 happy_var_5
 	) `HappyStk` happyRest}}
 
-happyReduce_39 = happySpecReduce_0  6# happyReduction_39
-happyReduction_39  =  happyIn10
+happyReduce_49 = happySpecReduce_0  9# happyReduction_49
+happyReduction_49  =  happyIn13
 		 ([]
 	)
 
-happyReduce_40 = happySpecReduce_1  6# happyReduction_40
-happyReduction_40 happy_x_1
-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
-	happyIn10
+happyReduce_50 = happySpecReduce_1  9# happyReduction_50
+happyReduction_50 happy_x_1
+	 =  case happyOut14 happy_x_1 of { happy_var_1 -> 
+	happyIn13
 		 ([happy_var_1]
 	)}
 
-happyReduce_41 = happySpecReduce_3  6# happyReduction_41
-happyReduction_41 happy_x_3
+happyReduce_51 = happySpecReduce_3  9# happyReduction_51
+happyReduction_51 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
-	case happyOut10 happy_x_3 of { happy_var_3 -> 
-	happyIn10
+	 =  case happyOut14 happy_x_1 of { happy_var_1 -> 
+	case happyOut13 happy_x_3 of { happy_var_3 -> 
+	happyIn13
 		 (happy_var_1:happy_var_3
 	)}}
 
-happyReduce_42 = happyReduce 7# 7# happyReduction_42
-happyReduction_42 (happy_x_7 `HappyStk`
+happyReduce_52 = happyReduce 7# 10# happyReduction_52
+happyReduction_52 (happy_x_7 `HappyStk`
 	happy_x_6 `HappyStk`
 	happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
@@ -595,232 +727,256 @@
 	happy_x_1 `HappyStk`
 	happyRest)
 	 = case happyOutTok happy_x_2 of { (TokenInt happy_var_2) -> 
-	case happyOut7 happy_x_4 of { happy_var_4 -> 
-	case happyOut8 happy_x_7 of { happy_var_7 -> 
-	happyIn11
+	case happyOut10 happy_x_4 of { happy_var_4 -> 
+	case happyOut11 happy_x_7 of { happy_var_7 -> 
+	happyIn14
 		 (Alt happy_var_2 happy_var_4 happy_var_7
 	) `HappyStk` happyRest}}}
 
-happyReduce_43 = happySpecReduce_3  7# happyReduction_43
-happyReduction_43 happy_x_3
+happyReduce_53 = happySpecReduce_3  10# happyReduction_53
+happyReduction_53 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn11
+	 =  case happyOutTok happy_x_1 of { (TokenInt happy_var_1) -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn14
+		 (ConstAlt happy_var_1 happy_var_3
+	)}}
+
+happyReduce_54 = happySpecReduce_3  10# happyReduction_54
+happyReduction_54 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn14
 		 (DefaultCase happy_var_3
 	)}
 
-happyReduce_44 = happySpecReduce_3  8# happyReduction_44
-happyReduction_44 happy_x_3
+happyReduce_55 = happySpecReduce_3  11# happyReduction_55
+happyReduction_55 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op Plus happy_var_1 happy_var_3
 	)}}
 
-happyReduce_45 = happySpecReduce_3  8# happyReduction_45
-happyReduction_45 happy_x_3
+happyReduce_56 = happySpecReduce_3  11# happyReduction_56
+happyReduction_56 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op Minus happy_var_1 happy_var_3
 	)}}
 
-happyReduce_46 = happySpecReduce_3  8# happyReduction_46
-happyReduction_46 happy_x_3
+happyReduce_57 = happySpecReduce_2  11# happyReduction_57
+happyReduction_57 happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_2 of { happy_var_2 -> 
+	happyIn15
+		 (Op Minus (Const (MkInt 0)) happy_var_2
+	)}
+
+happyReduce_58 = happySpecReduce_3  11# happyReduction_58
+happyReduction_58 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op Times happy_var_1 happy_var_3
 	)}}
 
-happyReduce_47 = happySpecReduce_3  8# happyReduction_47
-happyReduction_47 happy_x_3
+happyReduce_59 = happySpecReduce_3  11# happyReduction_59
+happyReduction_59 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op Divide happy_var_1 happy_var_3
 	)}}
 
-happyReduce_48 = happySpecReduce_3  8# happyReduction_48
-happyReduction_48 happy_x_3
+happyReduce_60 = happySpecReduce_3  11# happyReduction_60
+happyReduction_60 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op OpLT happy_var_1 happy_var_3
 	)}}
 
-happyReduce_49 = happySpecReduce_3  8# happyReduction_49
-happyReduction_49 happy_x_3
+happyReduce_61 = happySpecReduce_3  11# happyReduction_61
+happyReduction_61 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op OpGT happy_var_1 happy_var_3
 	)}}
 
-happyReduce_50 = happySpecReduce_3  8# happyReduction_50
-happyReduction_50 happy_x_3
+happyReduce_62 = happySpecReduce_3  11# happyReduction_62
+happyReduction_62 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op OpLE happy_var_1 happy_var_3
 	)}}
 
-happyReduce_51 = happySpecReduce_3  8# happyReduction_51
-happyReduction_51 happy_x_3
+happyReduce_63 = happySpecReduce_3  11# happyReduction_63
+happyReduction_63 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op OpGE happy_var_1 happy_var_3
 	)}}
 
-happyReduce_52 = happySpecReduce_3  8# happyReduction_52
-happyReduction_52 happy_x_3
+happyReduce_64 = happySpecReduce_3  11# happyReduction_64
+happyReduction_64 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut8 happy_x_3 of { happy_var_3 -> 
-	happyIn12
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
 		 (Op OpEQ happy_var_1 happy_var_3
 	)}}
 
-happyReduce_53 = happySpecReduce_0  9# happyReduction_53
-happyReduction_53  =  happyIn13
+happyReduce_65 = happySpecReduce_0  12# happyReduction_65
+happyReduction_65  =  happyIn16
 		 ([]
 	)
 
-happyReduce_54 = happySpecReduce_1  9# happyReduction_54
-happyReduction_54 happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	happyIn13
+happyReduce_66 = happySpecReduce_1  12# happyReduction_66
+happyReduction_66 happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	happyIn16
 		 ([happy_var_1]
 	)}
 
-happyReduce_55 = happySpecReduce_3  9# happyReduction_55
-happyReduction_55 happy_x_3
+happyReduce_67 = happySpecReduce_3  12# happyReduction_67
+happyReduction_67 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut13 happy_x_3 of { happy_var_3 -> 
-	happyIn13
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut16 happy_x_3 of { happy_var_3 -> 
+	happyIn16
 		 (happy_var_1:happy_var_3
 	)}}
 
-happyReduce_56 = happySpecReduce_0  10# happyReduction_56
-happyReduction_56  =  happyIn14
+happyReduce_68 = happySpecReduce_0  13# happyReduction_68
+happyReduction_68  =  happyIn17
 		 ([]
 	)
 
-happyReduce_57 = happySpecReduce_3  10# happyReduction_57
-happyReduction_57 happy_x_3
+happyReduce_69 = happySpecReduce_3  13# happyReduction_69
+happyReduction_69 happy_x_3
 	happy_x_2
 	happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
 	case happyOut5 happy_x_3 of { happy_var_3 -> 
-	happyIn14
+	happyIn17
 		 ([(happy_var_1,happy_var_3)]
 	)}}
 
-happyReduce_58 = happyReduce 5# 10# happyReduction_58
-happyReduction_58 (happy_x_5 `HappyStk`
+happyReduce_70 = happyReduce 5# 13# happyReduction_70
+happyReduction_70 (happy_x_5 `HappyStk`
 	happy_x_4 `HappyStk`
 	happy_x_3 `HappyStk`
 	happy_x_2 `HappyStk`
 	happy_x_1 `HappyStk`
 	happyRest)
-	 = case happyOut8 happy_x_1 of { happy_var_1 -> 
+	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
 	case happyOut5 happy_x_3 of { happy_var_3 -> 
-	case happyOut14 happy_x_5 of { happy_var_5 -> 
-	happyIn14
+	case happyOut17 happy_x_5 of { happy_var_5 -> 
+	happyIn17
 		 ((happy_var_1,happy_var_3):happy_var_5
 	) `HappyStk` happyRest}}}
 
-happyReduce_59 = happySpecReduce_1  11# happyReduction_59
-happyReduction_59 happy_x_1
+happyReduce_71 = happySpecReduce_1  14# happyReduction_71
+happyReduction_71 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenInt happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkInt happy_var_1
 	)}
 
-happyReduce_60 = happySpecReduce_1  11# happyReduction_60
-happyReduction_60 happy_x_1
+happyReduce_72 = happySpecReduce_1  14# happyReduction_72
+happyReduction_72 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenBigInt happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkBigInt happy_var_1
 	)}
 
-happyReduce_61 = happySpecReduce_1  11# happyReduction_61
-happyReduction_61 happy_x_1
+happyReduce_73 = happySpecReduce_1  14# happyReduction_73
+happyReduction_73 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenChar happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkChar happy_var_1
 	)}
 
-happyReduce_62 = happySpecReduce_1  11# happyReduction_62
-happyReduction_62 happy_x_1
+happyReduce_74 = happySpecReduce_1  14# happyReduction_74
+happyReduction_74 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenBool happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkBool happy_var_1
 	)}
 
-happyReduce_63 = happySpecReduce_1  11# happyReduction_63
-happyReduction_63 happy_x_1
+happyReduce_75 = happySpecReduce_1  14# happyReduction_75
+happyReduction_75 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenFloat happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkFloat happy_var_1
 	)}
 
-happyReduce_64 = happySpecReduce_1  11# happyReduction_64
-happyReduction_64 happy_x_1
+happyReduce_76 = happySpecReduce_1  14# happyReduction_76
+happyReduction_76 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenBigFloat happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkBigFloat happy_var_1
 	)}
 
-happyReduce_65 = happySpecReduce_1  11# happyReduction_65
-happyReduction_65 happy_x_1
+happyReduce_77 = happySpecReduce_1  14# happyReduction_77
+happyReduction_77 happy_x_1
 	 =  case happyOutTok happy_x_1 of { (TokenString happy_var_1) -> 
-	happyIn15
+	happyIn18
 		 (MkString happy_var_1
 	)}
 
-happyReduce_66 = happySpecReduce_1  11# happyReduction_66
-happyReduction_66 happy_x_1
-	 =  happyIn15
+happyReduce_78 = happySpecReduce_1  14# happyReduction_78
+happyReduction_78 happy_x_1
+	 =  happyIn18
 		 (MkUnit
 	)
 
-happyReduce_67 = happyMonadReduce 0# 12# happyReduction_67
-happyReduction_67 (happyRest) tk
+happyReduce_79 = happySpecReduce_1  14# happyReduction_79
+happyReduction_79 happy_x_1
+	 =  happyIn18
+		 (MkUnused
+	)
+
+happyReduce_80 = happyMonadReduce 0# 15# happyReduction_80
+happyReduction_80 (happyRest) tk
 	 = happyThen (( getLineNo)
-	) (\r -> happyReturn (happyIn16 r))
+	) (\r -> happyReturn (happyIn19 r))
 
-happyReduce_68 = happyMonadReduce 0# 13# happyReduction_68
-happyReduction_68 (happyRest) tk
+happyReduce_81 = happyMonadReduce 0# 16# happyReduction_81
+happyReduction_81 (happyRest) tk
 	 = happyThen (( getFileName)
-	) (\r -> happyReturn (happyIn17 r))
+	) (\r -> happyReturn (happyIn20 r))
 
 happyNewToken action sts stk
 	= lexer(\tk -> 
 	let cont i = happyDoAction i tk action sts stk in
 	case tk of {
-	TokenEOF -> happyDoAction 58# tk action sts stk;
+	TokenEOF -> happyDoAction 67# tk action sts stk;
 	TokenName happy_dollar_dollar -> cont 1#;
 	TokenString happy_dollar_dollar -> cont 2#;
 	TokenInt happy_dollar_dollar -> cont 3#;
@@ -850,34 +1006,43 @@
 	TokenIf -> cont 27#;
 	TokenThen -> cont 28#;
 	TokenElse -> cont 29#;
-	TokenIn -> cont 30#;
-	TokenLazy -> cont 31#;
-	TokenForeign -> cont 32#;
-	TokenError -> cont 33#;
-	TokenImpossible -> cont 34#;
-	TokenOB -> cont 35#;
-	TokenCB -> cont 36#;
-	TokenOCB -> cont 37#;
-	TokenCCB -> cont 38#;
-	TokenPlus -> cont 39#;
-	TokenMinus -> cont 40#;
-	TokenTimes -> cont 41#;
-	TokenDivide -> cont 42#;
-	TokenEquals -> cont 43#;
-	TokenEQ -> cont 44#;
-	TokenLE -> cont 45#;
-	TokenGE -> cont 46#;
-	TokenLT -> cont 47#;
-	TokenGT -> cont 48#;
-	TokenColon -> cont 49#;
-	TokenProj -> cont 50#;
-	TokenSemi -> cont 51#;
-	TokenComma -> cont 52#;
-	TokenBar -> cont 53#;
-	TokenArrow -> cont 54#;
-	TokenCInclude -> cont 55#;
-	TokenExtern -> cont 56#;
-	TokenInclude -> cont 57#;
+	TokenWhile -> cont 30#;
+	TokenUnused -> cont 31#;
+	TokenIn -> cont 32#;
+	TokenLazy -> cont 33#;
+	TokenStrict -> cont 34#;
+	TokenEffect -> cont 35#;
+	TokenForeign -> cont 36#;
+	TokenError -> cont 37#;
+	TokenImpossible -> cont 38#;
+	TokenOB -> cont 39#;
+	TokenCB -> cont 40#;
+	TokenOCB -> cont 41#;
+	TokenCCB -> cont 42#;
+	TokenOSB -> cont 43#;
+	TokenCSB -> cont 44#;
+	TokenPlus -> cont 45#;
+	TokenMinus -> cont 46#;
+	TokenTimes -> cont 47#;
+	TokenDivide -> cont 48#;
+	TokenEquals -> cont 49#;
+	TokenEQ -> cont 50#;
+	TokenLE -> cont 51#;
+	TokenGE -> cont 52#;
+	TokenLT -> cont 53#;
+	TokenGT -> cont 54#;
+	TokenColon -> cont 55#;
+	TokenProj -> cont 56#;
+	TokenSemi -> cont 57#;
+	TokenComma -> cont 58#;
+	TokenBar -> cont 59#;
+	TokenArrow -> cont 60#;
+	TokenCInclude -> cont 61#;
+	TokenExtern -> cont 62#;
+	TokenExport -> cont 63#;
+	TokenCType -> cont 64#;
+	TokenInclude -> cont 65#;
+	TokenInline -> cont 66#;
 	_ -> happyError' tk
 	})
 
@@ -890,7 +1055,7 @@
 happyThen1 = happyThen
 happyReturn1 :: () => a -> P a
 happyReturn1 = happyReturn
-happyError' :: () => Token -> P a
+happyError' :: () => (Token) -> P a
 happyError' tk = (\token -> happyError) tk
 
 mkparse = happySomeParser where
@@ -899,8 +1064,8 @@
 happySeq = happyDontSeq
 
 
-mkBind :: Name -> [Type] -> Type -> [Name] -> Expr -> Decl
-mkBind n tys ret ns expr = Decl n ret (Bind (zip ns tys) 0 expr)
+mkBind :: Name -> [Type] -> Type -> [Name] -> Expr -> Maybe String -> [CGFlag] -> Decl
+mkBind n tys ret ns expr export fl = Decl n ret (Bind (zip ns tys) 0 expr fl) export fl
 
 mkExtern :: Name -> [Type] -> Type -> [Name] -> Decl
 mkExtern n tys ret ns = Extern n ret tys
@@ -912,14 +1077,14 @@
 parseFile fn = do s <- readFile fn
                   let x = parse s fn
                   return x
-{-# LINE 1 "GenericTemplate.hs" #-}
-{-# LINE 1 "GenericTemplate.hs" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
 {-# LINE 1 "<built-in>" #-}
 {-# LINE 1 "<command line>" #-}
-{-# LINE 1 "GenericTemplate.hs" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
 -- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp 
 
-{-# LINE 28 "GenericTemplate.hs" #-}
+{-# LINE 28 "templates/GenericTemplate.hs" #-}
 
 
 data Happy_IntList = HappyCons Int# Happy_IntList
@@ -928,11 +1093,11 @@
 
 
 
-{-# LINE 49 "GenericTemplate.hs" #-}
+{-# LINE 49 "templates/GenericTemplate.hs" #-}
 
-{-# LINE 59 "GenericTemplate.hs" #-}
+{-# LINE 59 "templates/GenericTemplate.hs" #-}
 
-{-# LINE 68 "GenericTemplate.hs" #-}
+{-# LINE 68 "templates/GenericTemplate.hs" #-}
 
 infixr 9 `HappyStk`
 data HappyStk a = HappyStk a (HappyStk a)
@@ -984,7 +1149,7 @@
  	 action | check     = indexShortOffAddr happyTable off_i
 		| otherwise = indexShortOffAddr happyDefActions st
 
-{-# LINE 127 "GenericTemplate.hs" #-}
+{-# LINE 127 "templates/GenericTemplate.hs" #-}
 
 
 indexShortOffAddr (HappyA# arr) off =
@@ -1017,7 +1182,7 @@
 -----------------------------------------------------------------------------
 -- HappyState data type (not arrays)
 
-{-# LINE 170 "GenericTemplate.hs" #-}
+{-# LINE 170 "templates/GenericTemplate.hs" #-}
 
 -----------------------------------------------------------------------------
 -- Shifting a token
diff --git a/dist/build/Epic/epic-tmp/Epic/Parser.hs b/dist/build/Epic/epic-tmp/Epic/Parser.hs
new file mode 100644
--- /dev/null
+++ b/dist/build/Epic/epic-tmp/Epic/Parser.hs
@@ -0,0 +1,1343 @@
+{-# OPTIONS -fglasgow-exts -cpp #-}
+-- -*-Haskell-*-
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+module Epic.Parser where
+
+import Char
+import System.IO.Unsafe
+
+import Epic.Language
+import Epic.Lexer
+#if __GLASGOW_HASKELL__ >= 503
+import Data.Array
+#else
+import Array
+#endif
+#if __GLASGOW_HASKELL__ >= 503
+import GHC.Exts
+#else
+import GlaExts
+#endif
+
+-- parser produced by Happy Version 1.18.2
+
+newtype HappyAbsSyn  = HappyAbsSyn HappyAny
+#if __GLASGOW_HASKELL__ >= 607
+type HappyAny = GHC.Exts.Any
+#else
+type HappyAny = forall a . a
+#endif
+happyIn4 :: ([Decl]) -> (HappyAbsSyn )
+happyIn4 x = unsafeCoerce# x
+{-# INLINE happyIn4 #-}
+happyOut4 :: (HappyAbsSyn ) -> ([Decl])
+happyOut4 x = unsafeCoerce# x
+{-# INLINE happyOut4 #-}
+happyIn5 :: (Type) -> (HappyAbsSyn )
+happyIn5 x = unsafeCoerce# x
+{-# INLINE happyIn5 #-}
+happyOut5 :: (HappyAbsSyn ) -> (Type)
+happyOut5 x = unsafeCoerce# x
+{-# INLINE happyOut5 #-}
+happyIn6 :: (Decl) -> (HappyAbsSyn )
+happyIn6 x = unsafeCoerce# x
+{-# INLINE happyIn6 #-}
+happyOut6 :: (HappyAbsSyn ) -> (Decl)
+happyOut6 x = unsafeCoerce# x
+{-# INLINE happyOut6 #-}
+happyIn7 :: ([CGFlag]) -> (HappyAbsSyn )
+happyIn7 x = unsafeCoerce# x
+{-# INLINE happyIn7 #-}
+happyOut7 :: (HappyAbsSyn ) -> ([CGFlag])
+happyOut7 x = unsafeCoerce# x
+{-# INLINE happyOut7 #-}
+happyIn8 :: (CGFlag) -> (HappyAbsSyn )
+happyIn8 x = unsafeCoerce# x
+{-# INLINE happyIn8 #-}
+happyOut8 :: (HappyAbsSyn ) -> (CGFlag)
+happyOut8 x = unsafeCoerce# x
+{-# INLINE happyOut8 #-}
+happyIn9 :: (Maybe String) -> (HappyAbsSyn )
+happyIn9 x = unsafeCoerce# x
+{-# INLINE happyIn9 #-}
+happyOut9 :: (HappyAbsSyn ) -> (Maybe String)
+happyOut9 x = unsafeCoerce# x
+{-# INLINE happyOut9 #-}
+happyIn10 :: ([(Name,Type)]) -> (HappyAbsSyn )
+happyIn10 x = unsafeCoerce# x
+{-# INLINE happyIn10 #-}
+happyOut10 :: (HappyAbsSyn ) -> ([(Name,Type)])
+happyOut10 x = unsafeCoerce# x
+{-# INLINE happyOut10 #-}
+happyIn11 :: (Expr) -> (HappyAbsSyn )
+happyIn11 x = unsafeCoerce# x
+{-# INLINE happyIn11 #-}
+happyOut11 :: (HappyAbsSyn ) -> (Expr)
+happyOut11 x = unsafeCoerce# x
+{-# INLINE happyOut11 #-}
+happyIn12 :: (Expr) -> (HappyAbsSyn )
+happyIn12 x = unsafeCoerce# x
+{-# INLINE happyIn12 #-}
+happyOut12 :: (HappyAbsSyn ) -> (Expr)
+happyOut12 x = unsafeCoerce# x
+{-# INLINE happyOut12 #-}
+happyIn13 :: ([CaseAlt]) -> (HappyAbsSyn )
+happyIn13 x = unsafeCoerce# x
+{-# INLINE happyIn13 #-}
+happyOut13 :: (HappyAbsSyn ) -> ([CaseAlt])
+happyOut13 x = unsafeCoerce# x
+{-# INLINE happyOut13 #-}
+happyIn14 :: (CaseAlt) -> (HappyAbsSyn )
+happyIn14 x = unsafeCoerce# x
+{-# INLINE happyIn14 #-}
+happyOut14 :: (HappyAbsSyn ) -> (CaseAlt)
+happyOut14 x = unsafeCoerce# x
+{-# INLINE happyOut14 #-}
+happyIn15 :: (Expr) -> (HappyAbsSyn )
+happyIn15 x = unsafeCoerce# x
+{-# INLINE happyIn15 #-}
+happyOut15 :: (HappyAbsSyn ) -> (Expr)
+happyOut15 x = unsafeCoerce# x
+{-# INLINE happyOut15 #-}
+happyIn16 :: ([Expr]) -> (HappyAbsSyn )
+happyIn16 x = unsafeCoerce# x
+{-# INLINE happyIn16 #-}
+happyOut16 :: (HappyAbsSyn ) -> ([Expr])
+happyOut16 x = unsafeCoerce# x
+{-# INLINE happyOut16 #-}
+happyIn17 :: ([(Expr,Type)]) -> (HappyAbsSyn )
+happyIn17 x = unsafeCoerce# x
+{-# INLINE happyIn17 #-}
+happyOut17 :: (HappyAbsSyn ) -> ([(Expr,Type)])
+happyOut17 x = unsafeCoerce# x
+{-# INLINE happyOut17 #-}
+happyIn18 :: (Const) -> (HappyAbsSyn )
+happyIn18 x = unsafeCoerce# x
+{-# INLINE happyIn18 #-}
+happyOut18 :: (HappyAbsSyn ) -> (Const)
+happyOut18 x = unsafeCoerce# x
+{-# INLINE happyOut18 #-}
+happyIn19 :: (LineNumber) -> (HappyAbsSyn )
+happyIn19 x = unsafeCoerce# x
+{-# INLINE happyIn19 #-}
+happyOut19 :: (HappyAbsSyn ) -> (LineNumber)
+happyOut19 x = unsafeCoerce# x
+{-# INLINE happyOut19 #-}
+happyIn20 :: (String) -> (HappyAbsSyn )
+happyIn20 x = unsafeCoerce# x
+{-# INLINE happyIn20 #-}
+happyOut20 :: (HappyAbsSyn ) -> (String)
+happyOut20 x = unsafeCoerce# x
+{-# INLINE happyOut20 #-}
+happyInTok :: (Token) -> (HappyAbsSyn )
+happyInTok x = unsafeCoerce# x
+{-# INLINE happyInTok #-}
+happyOutTok :: (HappyAbsSyn ) -> (Token)
+happyOutTok x = unsafeCoerce# x
+{-# INLINE happyOutTok #-}
+
+
+happyActOffsets :: HappyAddr
+happyActOffsets = HappyA# "\xce\x01\x05\x00\x00\x00\xdf\xff\x2d\x01\x2c\x01\x23\x01\xe1\x00\x01\x01\x1d\x01\xce\x01\x00\x00\x00\x00\xf7\x00\x00\x00\x1c\x01\xdf\xff\x00\x00\x00\x00\x00\x00\xe7\x00\x13\x01\x00\x00\x00\x00\xe5\x00\xd8\x00\xfb\x00\xd6\x00\x3d\x01\xc8\x00\x3d\x01\xc5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x00\x3d\x01\xf6\x00\x00\x00\x00\x00\xbb\x00\x01\x00\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\x00\xe9\x00\x01\x00\x01\x00\xc4\x00\x00\x00\xe8\xff\xc2\x00\x3d\x01\xe2\x00\x00\x00\x01\x00\x01\x00\x01\x00\xe6\xff\x76\x00\xb2\x00\xd3\x00\x00\x00\xd7\x00\x01\x00\x3d\x01\x01\x00\x01\x00\x18\x00\x03\x00\xa1\x00\xaf\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\xd4\x00\x01\x00\x03\x01\x00\x00\xe3\xff\xe3\xff\xe3\xff\xe3\xff\xf3\x00\xe6\xff\xe6\xff\x0d\x01\x0d\x01\x9e\x00\x01\x00\x3d\x01\xa2\x00\x01\x00\x66\x00\xc0\x00\xc3\x00\xad\x00\x9d\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x94\x00\x00\x00\x01\x00\x2c\x00\x2a\x00\x85\x00\x8c\x00\x00\x00\x00\x00\x01\x00\x8b\x00\x6c\x00\x77\x00\x9f\x00\x71\x00\x01\x00\x56\x00\x01\x00\x9a\x00\x79\x00\x00\x00\x3d\x01\x6f\x00\x00\x00\x01\x00\xe3\x00\x01\x00\x6b\x00\x01\x00\x2a\x00\x00\x00\x43\x00\x01\x00\x00\x00\xe3\x00\x86\x00\xe3\x00\x8a\x00\x00\x00\x40\x00\x01\x00\x00\x00\x69\x00\xe3\x00\x30\x00\x00\x00\x01\x00\xe3\x00\x00\x00"#
+
+happyGotoOffsets :: HappyAddr
+happyGotoOffsets = HappyA# "\x04\x02\x09\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x52\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6e\x00\x5f\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x00\x65\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x50\x00\x00\x00\x00\x00\x00\x00\xf7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x01\xed\x01\x00\x00\x00\x00\x00\x00\x00\x00\x54\x00\x00\x00\x00\x00\xeb\x01\x73\x01\xe3\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x01\x4e\x00\xd9\x01\xd7\x01\x00\x00\x00\x00\x00\x00\x00\x00\x6b\x01\xcf\x01\xcd\x01\xc5\x01\xc3\x01\xbb\x01\xb9\x01\xb1\x01\xaf\x01\xa7\x01\x00\x00\xa5\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x01\x39\x00\x00\x00\x9d\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5b\x01\x00\x00\x53\x01\x00\x00\x00\x00\x00\x00\x9b\x01\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x01\x00\x00\x4b\x01\x00\x00\x00\x00\x00\x00\x22\x00\x00\x00\x00\x00\x89\x01\x00\x00\x87\x01\x00\x00\x7f\x01\x0b\x00\x00\x00\x00\x00\x7d\x01\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x01\x00\x00\x00\x00"#
+
+happyDefActions :: HappyAddr
+happyDefActions = HappyA# "\xe8\xff\x00\x00\x00\x00\xec\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xff\x00\x00\xe8\xff\xfd\xff\xe7\xff\x00\x00\xed\xff\x00\x00\xec\xff\xe9\xff\xea\xff\xeb\xff\x00\x00\xe6\xff\xae\xff\xfc\xff\x00\x00\x00\x00\xe6\xff\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xff\xfb\xff\xfa\xff\xf9\xff\xf8\xff\xf7\xff\xf6\xff\xf5\xff\xf4\xff\xf3\xff\xf0\xff\xf1\xff\xf2\xff\x00\x00\x00\x00\xe6\xff\xee\xff\xe4\xff\x00\x00\x00\x00\xef\xff\xd5\xff\xd4\xff\xdc\xff\xe3\xff\xb2\xff\xb8\xff\xb7\xff\xb5\xff\xb4\xff\xb3\xff\xb6\xff\xb1\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0\xff\x00\x00\x00\x00\x00\x00\x00\x00\xd2\xff\x00\x00\xbe\xff\x00\x00\xc6\xff\xbd\xff\x00\x00\x00\x00\xd3\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xff\xdb\xff\xc2\xff\xc3\xff\xc0\xff\xc1\xff\xbf\xff\xc4\xff\xc5\xff\xc7\xff\xc8\xff\x00\x00\xbe\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xff\xe0\xff\xbe\xff\xbc\xff\xbb\xff\xde\xff\x00\x00\xdf\xff\x00\x00\x00\x00\xce\xff\x00\x00\x00\x00\xe1\xff\xdd\xff\x00\x00\x00\x00\xcd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xff\x00\x00\x00\x00\xd1\xff\x00\x00\x00\x00\xd7\xff\x00\x00\xd8\xff\x00\x00\x00\x00\x00\x00\xce\xff\xcf\xff\x00\x00\x00\x00\xcc\xff\xca\xff\xe6\xff\xc9\xff\x00\x00\xd0\xff\xba\xff\xbb\xff\xd6\xff\x00\x00\xda\xff\x00\x00\xb9\xff\x00\x00\xcb\xff"#
+
+happyCheck :: HappyAddr
+happyCheck = HappyA# "\xff\xff\x22\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x27\x00\x02\x00\x24\x00\x27\x00\x05\x00\x27\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x09\x00\x0a\x00\x15\x00\x16\x00\x06\x00\x18\x00\x19\x00\x38\x00\x1b\x00\x1a\x00\x38\x00\x1e\x00\x1f\x00\x42\x00\x21\x00\x01\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x00\x00\x27\x00\x02\x00\x2b\x00\x03\x00\x05\x00\x2e\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x1c\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x01\x00\x38\x00\x39\x00\x09\x00\x0a\x00\x27\x00\x16\x00\x17\x00\x3d\x00\x3e\x00\x3f\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x1d\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x01\x00\x38\x00\x39\x00\x00\x00\x27\x00\x02\x00\x01\x00\x06\x00\x05\x00\x01\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x01\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x20\x00\x38\x00\x39\x00\x01\x00\x07\x00\x08\x00\x06\x00\x27\x00\x0b\x00\x3c\x00\x0d\x00\x0e\x00\x10\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x06\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x3a\x00\x38\x00\x39\x00\x27\x00\x28\x00\x03\x00\x04\x00\x03\x00\x04\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x01\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x3a\x00\x28\x00\x27\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x28\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x3a\x00\x28\x00\x03\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x3b\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x3c\x00\x38\x00\x39\x00\x3a\x00\x27\x00\x28\x00\x3c\x00\x28\x00\x2a\x00\x31\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x27\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x27\x00\x02\x00\x28\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x29\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x27\x00\x28\x00\x27\x00\x03\x00\x37\x00\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x2c\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x02\x00\x38\x00\x39\x00\x27\x00\x28\x00\x27\x00\x01\x00\x27\x00\x31\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x03\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x01\x00\x38\x00\x39\x00\x27\x00\x28\x00\x01\x00\x3c\x00\x28\x00\x3a\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x3c\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x28\x00\x27\x00\x37\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x01\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x01\x00\x27\x00\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x43\x00\x02\x00\x33\x00\x34\x00\x35\x00\x36\x00\x27\x00\x38\x00\x39\x00\x01\x00\xff\xff\x02\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x27\x00\xff\xff\x33\x00\x34\x00\x35\x00\x36\x00\xff\xff\x38\x00\x2f\x00\x30\x00\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\xff\xff\x43\x00\x38\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\xff\xff\x0d\x00\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\x0c\x00\xff\xff\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\x0c\x00\xff\xff\x0e\x00\x07\x00\x08\x00\xff\xff\xff\xff\x0b\x00\x0c\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\x0c\x00\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\xff\xff\x0e\x00\x07\x00\x08\x00\x07\x00\x08\x00\x0b\x00\xff\xff\x0b\x00\x0e\x00\x00\x00\x0e\x00\x02\x00\xff\xff\xff\xff\x05\x00\xff\xff\x3d\x00\x3e\x00\x3f\x00\xff\xff\x41\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
+
+happyTable :: HappyAddr
+happyTable = HappyA# "\x00\x00\x12\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x5d\x00\x02\x00\x56\x00\x5d\x00\x03\x00\x57\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xa4\x00\x8e\x00\x40\x00\x41\x00\xad\x00\x42\x00\x43\x00\x67\x00\x44\x00\x77\x00\x67\x00\x45\x00\x46\x00\x13\x00\x47\x00\xaa\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x16\x00\x5d\x00\x08\x00\x4d\x00\x90\x00\x03\x00\x4e\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x78\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x88\x00\x67\x00\x68\x00\x8d\x00\x8e\x00\x5d\x00\x91\x00\x92\x00\x05\x00\x06\x00\x07\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x93\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x7a\x00\x67\x00\x68\x00\x0b\x00\x5d\x00\x08\x00\x53\x00\x30\x00\x03\x00\x31\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x2f\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xa4\x00\x67\x00\x68\x00\x1f\x00\x95\x00\x34\x00\x1b\x00\x5d\x00\x35\x00\xb2\x00\xb0\x00\x36\x00\x17\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x18\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xac\x00\x67\x00\x68\x00\x5d\x00\x9b\x00\x13\x00\x10\x00\x0f\x00\x10\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1a\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x9c\x00\xb0\x00\xa7\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xaa\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x86\x00\x98\x00\x9f\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xa1\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x9e\x00\x67\x00\x68\x00\x80\x00\x5d\x00\xad\x00\xa0\x00\x8c\x00\xa2\x00\x8d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x95\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x82\x00\x84\x00\x8b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x88\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x99\x00\x67\x00\x68\x00\x5d\x00\x83\x00\x75\x00\x6a\x00\x76\x00\x7d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x7f\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x53\x00\x67\x00\x68\x00\x5d\x00\x85\x00\x55\x00\x5b\x00\x58\x00\x33\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x5c\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x1a\x00\x67\x00\x68\x00\x5d\x00\x7e\x00\x1a\x00\x2e\x00\x2d\x00\x2f\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1f\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x1e\x00\x1b\x00\x1d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x1a\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x15\x00\x16\x00\x0b\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\xff\xff\x0d\x00\x63\x00\x64\x00\x65\x00\x66\x00\x5d\x00\x67\x00\x68\x00\x0e\x00\x00\x00\x0f\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x5d\x00\x00\x00\x63\x00\x64\x00\x65\x00\x66\x00\x00\x00\x67\x00\x60\x00\x61\x00\x05\x00\x06\x00\x07\x00\x00\x00\x0a\x00\x00\x00\xfe\xff\x67\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x95\x00\x34\x00\x00\x00\x00\x00\x35\x00\x00\x00\x99\x00\x36\x00\x95\x00\x34\x00\x00\x00\x00\x00\x35\x00\x00\x00\x96\x00\x36\x00\x4f\x00\x34\x00\x00\x00\x00\x00\x35\x00\x80\x00\x00\x00\x36\x00\x4f\x00\x34\x00\x00\x00\x00\x00\x35\x00\x89\x00\x00\x00\x36\x00\x4f\x00\x34\x00\x00\x00\x00\x00\x35\x00\x73\x00\x00\x00\x36\x00\x4f\x00\x34\x00\xb2\x00\x34\x00\x35\x00\x50\x00\x35\x00\x36\x00\x00\x00\x36\x00\xae\x00\x34\x00\xa5\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\xa7\x00\x34\x00\xa8\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x9c\x00\x34\x00\xa2\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x93\x00\x34\x00\x86\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x68\x00\x34\x00\x6a\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x6b\x00\x34\x00\x6c\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x6d\x00\x34\x00\x6e\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x6f\x00\x34\x00\x70\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x71\x00\x34\x00\x72\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x78\x00\x34\x00\x79\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x7b\x00\x34\x00\x4e\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x51\x00\x34\x00\x58\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x00\x00\x36\x00\x59\x00\x34\x00\x33\x00\x34\x00\x35\x00\x00\x00\x35\x00\x36\x00\x07\x00\x36\x00\x08\x00\x00\x00\x00\x00\x03\x00\x00\x00\x05\x00\x06\x00\x07\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
+
+happyReduceArr = array (1, 81) [
+	(1 , happyReduce_1),
+	(2 , happyReduce_2),
+	(3 , happyReduce_3),
+	(4 , happyReduce_4),
+	(5 , happyReduce_5),
+	(6 , happyReduce_6),
+	(7 , happyReduce_7),
+	(8 , happyReduce_8),
+	(9 , happyReduce_9),
+	(10 , happyReduce_10),
+	(11 , happyReduce_11),
+	(12 , happyReduce_12),
+	(13 , happyReduce_13),
+	(14 , happyReduce_14),
+	(15 , happyReduce_15),
+	(16 , happyReduce_16),
+	(17 , happyReduce_17),
+	(18 , happyReduce_18),
+	(19 , happyReduce_19),
+	(20 , happyReduce_20),
+	(21 , happyReduce_21),
+	(22 , happyReduce_22),
+	(23 , happyReduce_23),
+	(24 , happyReduce_24),
+	(25 , happyReduce_25),
+	(26 , happyReduce_26),
+	(27 , happyReduce_27),
+	(28 , happyReduce_28),
+	(29 , happyReduce_29),
+	(30 , happyReduce_30),
+	(31 , happyReduce_31),
+	(32 , happyReduce_32),
+	(33 , happyReduce_33),
+	(34 , happyReduce_34),
+	(35 , happyReduce_35),
+	(36 , happyReduce_36),
+	(37 , happyReduce_37),
+	(38 , happyReduce_38),
+	(39 , happyReduce_39),
+	(40 , happyReduce_40),
+	(41 , happyReduce_41),
+	(42 , happyReduce_42),
+	(43 , happyReduce_43),
+	(44 , happyReduce_44),
+	(45 , happyReduce_45),
+	(46 , happyReduce_46),
+	(47 , happyReduce_47),
+	(48 , happyReduce_48),
+	(49 , happyReduce_49),
+	(50 , happyReduce_50),
+	(51 , happyReduce_51),
+	(52 , happyReduce_52),
+	(53 , happyReduce_53),
+	(54 , happyReduce_54),
+	(55 , happyReduce_55),
+	(56 , happyReduce_56),
+	(57 , happyReduce_57),
+	(58 , happyReduce_58),
+	(59 , happyReduce_59),
+	(60 , happyReduce_60),
+	(61 , happyReduce_61),
+	(62 , happyReduce_62),
+	(63 , happyReduce_63),
+	(64 , happyReduce_64),
+	(65 , happyReduce_65),
+	(66 , happyReduce_66),
+	(67 , happyReduce_67),
+	(68 , happyReduce_68),
+	(69 , happyReduce_69),
+	(70 , happyReduce_70),
+	(71 , happyReduce_71),
+	(72 , happyReduce_72),
+	(73 , happyReduce_73),
+	(74 , happyReduce_74),
+	(75 , happyReduce_75),
+	(76 , happyReduce_76),
+	(77 , happyReduce_77),
+	(78 , happyReduce_78),
+	(79 , happyReduce_79),
+	(80 , happyReduce_80),
+	(81 , happyReduce_81)
+	]
+
+happy_n_terms = 68 :: Int
+happy_n_nonterms = 17 :: Int
+
+happyReduce_1 = happySpecReduce_1  0# happyReduction_1
+happyReduction_1 happy_x_1
+	 =  case happyOut6 happy_x_1 of { happy_var_1 -> 
+	happyIn4
+		 ([happy_var_1]
+	)}
+
+happyReduce_2 = happySpecReduce_2  0# happyReduction_2
+happyReduction_2 happy_x_2
+	happy_x_1
+	 =  case happyOut6 happy_x_1 of { happy_var_1 -> 
+	case happyOut4 happy_x_2 of { happy_var_2 -> 
+	happyIn4
+		 (happy_var_1:happy_var_2
+	)}}
+
+happyReduce_3 = happyMonadReduce 4# 0# happyReduction_3
+happyReduction_3 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest) tk
+	 = happyThen (case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
+	case happyOut4 happy_x_3 of { happy_var_3 -> 
+	case happyOut20 happy_x_4 of { happy_var_4 -> 
+	(
+ 	   let rest = happy_var_3 in
+	   let pt = unsafePerformIO (readFile happy_var_2) in
+		case (parse pt happy_var_4) of
+		   Success x -> returnP (x ++ rest)
+		   Failure err file ln -> failP err)}}}
+	) (\r -> happyReturn (happyIn4 r))
+
+happyReduce_4 = happySpecReduce_1  1# happyReduction_4
+happyReduction_4 happy_x_1
+	 =  happyIn5
+		 (TyInt
+	)
+
+happyReduce_5 = happySpecReduce_1  1# happyReduction_5
+happyReduction_5 happy_x_1
+	 =  happyIn5
+		 (TyBigInt
+	)
+
+happyReduce_6 = happySpecReduce_1  1# happyReduction_6
+happyReduction_6 happy_x_1
+	 =  happyIn5
+		 (TyChar
+	)
+
+happyReduce_7 = happySpecReduce_1  1# happyReduction_7
+happyReduction_7 happy_x_1
+	 =  happyIn5
+		 (TyBool
+	)
+
+happyReduce_8 = happySpecReduce_1  1# happyReduction_8
+happyReduction_8 happy_x_1
+	 =  happyIn5
+		 (TyFloat
+	)
+
+happyReduce_9 = happySpecReduce_1  1# happyReduction_9
+happyReduction_9 happy_x_1
+	 =  happyIn5
+		 (TyBigFloat
+	)
+
+happyReduce_10 = happySpecReduce_1  1# happyReduction_10
+happyReduction_10 happy_x_1
+	 =  happyIn5
+		 (TyString
+	)
+
+happyReduce_11 = happySpecReduce_1  1# happyReduction_11
+happyReduction_11 happy_x_1
+	 =  happyIn5
+		 (TyPtr
+	)
+
+happyReduce_12 = happySpecReduce_1  1# happyReduction_12
+happyReduction_12 happy_x_1
+	 =  happyIn5
+		 (TyUnit
+	)
+
+happyReduce_13 = happySpecReduce_1  1# happyReduction_13
+happyReduction_13 happy_x_1
+	 =  happyIn5
+		 (TyAny
+	)
+
+happyReduce_14 = happySpecReduce_1  1# happyReduction_14
+happyReduction_14 happy_x_1
+	 =  happyIn5
+		 (TyData
+	)
+
+happyReduce_15 = happySpecReduce_1  1# happyReduction_15
+happyReduction_15 happy_x_1
+	 =  happyIn5
+		 (TyFun
+	)
+
+happyReduce_16 = happyReduce 10# 2# happyReduction_16
+happyReduction_16 (happy_x_10 `HappyStk`
+	happy_x_9 `HappyStk`
+	happy_x_8 `HappyStk`
+	happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut9 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_2 of { happy_var_2 -> 
+	case happyOutTok happy_x_3 of { (TokenName happy_var_3) -> 
+	case happyOut10 happy_x_5 of { happy_var_5 -> 
+	case happyOut5 happy_x_8 of { happy_var_8 -> 
+	case happyOut11 happy_x_10 of { happy_var_10 -> 
+	happyIn6
+		 (mkBind happy_var_3 (map snd happy_var_5) happy_var_8 (map fst happy_var_5) happy_var_10 happy_var_1 happy_var_2
+	) `HappyStk` happyRest}}}}}}
+
+happyReduce_17 = happyReduce 7# 2# happyReduction_17
+happyReduction_17 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_2 of { (TokenName happy_var_2) -> 
+	case happyOut10 happy_x_4 of { happy_var_4 -> 
+	case happyOut5 happy_x_7 of { happy_var_7 -> 
+	happyIn6
+		 (mkExtern happy_var_2 (map snd happy_var_4) happy_var_7 (map fst happy_var_4)
+	) `HappyStk` happyRest}}}
+
+happyReduce_18 = happySpecReduce_2  2# happyReduction_18
+happyReduction_18 happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
+	happyIn6
+		 (Include happy_var_2
+	)}
+
+happyReduce_19 = happySpecReduce_0  3# happyReduction_19
+happyReduction_19  =  happyIn7
+		 ([]
+	)
+
+happyReduce_20 = happySpecReduce_2  3# happyReduction_20
+happyReduction_20 happy_x_2
+	happy_x_1
+	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
+	case happyOut7 happy_x_2 of { happy_var_2 -> 
+	happyIn7
+		 (happy_var_1:happy_var_2
+	)}}
+
+happyReduce_21 = happySpecReduce_1  4# happyReduction_21
+happyReduction_21 happy_x_1
+	 =  happyIn8
+		 (Inline
+	)
+
+happyReduce_22 = happySpecReduce_1  4# happyReduction_22
+happyReduction_22 happy_x_1
+	 =  happyIn8
+		 (Strict
+	)
+
+happyReduce_23 = happySpecReduce_0  5# happyReduction_23
+happyReduction_23  =  happyIn9
+		 (Nothing
+	)
+
+happyReduce_24 = happySpecReduce_2  5# happyReduction_24
+happyReduction_24 happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
+	happyIn9
+		 (Just happy_var_2
+	)}
+
+happyReduce_25 = happySpecReduce_0  6# happyReduction_25
+happyReduction_25  =  happyIn10
+		 ([]
+	)
+
+happyReduce_26 = happySpecReduce_3  6# happyReduction_26
+happyReduction_26 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
+	case happyOut5 happy_x_3 of { happy_var_3 -> 
+	happyIn10
+		 ([(happy_var_1,happy_var_3)]
+	)}}
+
+happyReduce_27 = happyReduce 5# 6# happyReduction_27
+happyReduction_27 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
+	case happyOut5 happy_x_3 of { happy_var_3 -> 
+	case happyOut10 happy_x_5 of { happy_var_5 -> 
+	happyIn10
+		 ((happy_var_1,happy_var_3):happy_var_5
+	) `HappyStk` happyRest}}}
+
+happyReduce_28 = happySpecReduce_1  7# happyReduction_28
+happyReduction_28 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenName happy_var_1) -> 
+	happyIn11
+		 (R happy_var_1
+	)}
+
+happyReduce_29 = happySpecReduce_3  7# happyReduction_29
+happyReduction_29 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_2 of { happy_var_2 -> 
+	happyIn11
+		 (happy_var_2
+	)}
+
+happyReduce_30 = happyReduce 4# 7# happyReduction_30
+happyReduction_30 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut16 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (App happy_var_1 happy_var_3
+	) `HappyStk` happyRest}}
+
+happyReduce_31 = happySpecReduce_3  7# happyReduction_31
+happyReduction_31 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut16 happy_x_2 of { happy_var_2 -> 
+	happyIn11
+		 (Con 0 happy_var_2
+	)}
+
+happyReduce_32 = happyReduce 4# 7# happyReduction_32
+happyReduction_32 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (Lazy happy_var_3
+	) `HappyStk` happyRest}
+
+happyReduce_33 = happyReduce 4# 7# happyReduction_33
+happyReduction_33 (happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (Effect happy_var_3
+	) `HappyStk` happyRest}
+
+happyReduce_34 = happyReduce 5# 7# happyReduction_34
+happyReduction_34 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_2 of { (TokenInt happy_var_2) -> 
+	case happyOut16 happy_x_4 of { happy_var_4 -> 
+	happyIn11
+		 (Con happy_var_2 happy_var_4
+	) `HappyStk` happyRest}}
+
+happyReduce_35 = happySpecReduce_1  7# happyReduction_35
+happyReduction_35 happy_x_1
+	 =  case happyOut18 happy_x_1 of { happy_var_1 -> 
+	happyIn11
+		 (Const happy_var_1
+	)}
+
+happyReduce_36 = happySpecReduce_3  7# happyReduction_36
+happyReduction_36 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOutTok happy_x_3 of { (TokenInt happy_var_3) -> 
+	happyIn11
+		 (Proj happy_var_1 happy_var_3
+	)}}
+
+happyReduce_37 = happyReduce 8# 7# happyReduction_37
+happyReduction_37 (happy_x_8 `HappyStk`
+	happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_2 of { (TokenName happy_var_2) -> 
+	case happyOut5 happy_x_4 of { happy_var_4 -> 
+	case happyOut11 happy_x_6 of { happy_var_6 -> 
+	case happyOut11 happy_x_8 of { happy_var_8 -> 
+	happyIn11
+		 (Let happy_var_2 happy_var_4 happy_var_6 happy_var_8
+	) `HappyStk` happyRest}}}}
+
+happyReduce_38 = happySpecReduce_3  7# happyReduction_38
+happyReduction_38 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn11
+		 (Let (MN "unused" 0) TyUnit happy_var_1 happy_var_3
+	)}}
+
+happyReduce_39 = happyReduce 6# 7# happyReduction_39
+happyReduction_39 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
+	case happyOut11 happy_x_4 of { happy_var_4 -> 
+	case happyOut11 happy_x_6 of { happy_var_6 -> 
+	happyIn11
+		 (If happy_var_2 happy_var_4 happy_var_6
+	) `HappyStk` happyRest}}}
+
+happyReduce_40 = happyReduce 6# 7# happyReduction_40
+happyReduction_40 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	case happyOut11 happy_x_5 of { happy_var_5 -> 
+	happyIn11
+		 (While happy_var_3 happy_var_5
+	) `HappyStk` happyRest}}
+
+happyReduce_41 = happyReduce 8# 7# happyReduction_41
+happyReduction_41 (happy_x_8 `HappyStk`
+	happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_3 of { happy_var_3 -> 
+	case happyOut11 happy_x_5 of { happy_var_5 -> 
+	case happyOut11 happy_x_7 of { happy_var_7 -> 
+	happyIn11
+		 (WhileAcc happy_var_3 happy_var_5 happy_var_7
+	) `HappyStk` happyRest}}}
+
+happyReduce_42 = happySpecReduce_1  7# happyReduction_42
+happyReduction_42 happy_x_1
+	 =  case happyOut12 happy_x_1 of { happy_var_1 -> 
+	happyIn11
+		 (happy_var_1
+	)}
+
+happyReduce_43 = happySpecReduce_1  7# happyReduction_43
+happyReduction_43 happy_x_1
+	 =  case happyOut15 happy_x_1 of { happy_var_1 -> 
+	happyIn11
+		 (happy_var_1
+	)}
+
+happyReduce_44 = happySpecReduce_2  7# happyReduction_44
+happyReduction_44 happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_2 of { (TokenString happy_var_2) -> 
+	happyIn11
+		 (Error happy_var_2
+	)}
+
+happyReduce_45 = happySpecReduce_1  7# happyReduction_45
+happyReduction_45 happy_x_1
+	 =  happyIn11
+		 (Impossible
+	)
+
+happyReduce_46 = happyReduce 6# 7# happyReduction_46
+happyReduction_46 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut5 happy_x_2 of { happy_var_2 -> 
+	case happyOutTok happy_x_3 of { (TokenString happy_var_3) -> 
+	case happyOut17 happy_x_5 of { happy_var_5 -> 
+	happyIn11
+		 (ForeignCall happy_var_2 happy_var_3 happy_var_5
+	) `HappyStk` happyRest}}}
+
+happyReduce_47 = happyReduce 7# 7# happyReduction_47
+happyReduction_47 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut5 happy_x_3 of { happy_var_3 -> 
+	case happyOutTok happy_x_4 of { (TokenString happy_var_4) -> 
+	case happyOut17 happy_x_6 of { happy_var_6 -> 
+	happyIn11
+		 (LazyForeignCall happy_var_3 happy_var_4 happy_var_6
+	) `HappyStk` happyRest}}}
+
+happyReduce_48 = happyReduce 6# 8# happyReduction_48
+happyReduction_48 (happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_2 of { happy_var_2 -> 
+	case happyOut13 happy_x_5 of { happy_var_5 -> 
+	happyIn12
+		 (Case happy_var_2 happy_var_5
+	) `HappyStk` happyRest}}
+
+happyReduce_49 = happySpecReduce_0  9# happyReduction_49
+happyReduction_49  =  happyIn13
+		 ([]
+	)
+
+happyReduce_50 = happySpecReduce_1  9# happyReduction_50
+happyReduction_50 happy_x_1
+	 =  case happyOut14 happy_x_1 of { happy_var_1 -> 
+	happyIn13
+		 ([happy_var_1]
+	)}
+
+happyReduce_51 = happySpecReduce_3  9# happyReduction_51
+happyReduction_51 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut14 happy_x_1 of { happy_var_1 -> 
+	case happyOut13 happy_x_3 of { happy_var_3 -> 
+	happyIn13
+		 (happy_var_1:happy_var_3
+	)}}
+
+happyReduce_52 = happyReduce 7# 10# happyReduction_52
+happyReduction_52 (happy_x_7 `HappyStk`
+	happy_x_6 `HappyStk`
+	happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOutTok happy_x_2 of { (TokenInt happy_var_2) -> 
+	case happyOut10 happy_x_4 of { happy_var_4 -> 
+	case happyOut11 happy_x_7 of { happy_var_7 -> 
+	happyIn14
+		 (Alt happy_var_2 happy_var_4 happy_var_7
+	) `HappyStk` happyRest}}}
+
+happyReduce_53 = happySpecReduce_3  10# happyReduction_53
+happyReduction_53 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenInt happy_var_1) -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn14
+		 (ConstAlt happy_var_1 happy_var_3
+	)}}
+
+happyReduce_54 = happySpecReduce_3  10# happyReduction_54
+happyReduction_54 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn14
+		 (DefaultCase happy_var_3
+	)}
+
+happyReduce_55 = happySpecReduce_3  11# happyReduction_55
+happyReduction_55 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op Plus happy_var_1 happy_var_3
+	)}}
+
+happyReduce_56 = happySpecReduce_3  11# happyReduction_56
+happyReduction_56 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op Minus happy_var_1 happy_var_3
+	)}}
+
+happyReduce_57 = happySpecReduce_2  11# happyReduction_57
+happyReduction_57 happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_2 of { happy_var_2 -> 
+	happyIn15
+		 (Op Minus (Const (MkInt 0)) happy_var_2
+	)}
+
+happyReduce_58 = happySpecReduce_3  11# happyReduction_58
+happyReduction_58 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op Times happy_var_1 happy_var_3
+	)}}
+
+happyReduce_59 = happySpecReduce_3  11# happyReduction_59
+happyReduction_59 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op Divide happy_var_1 happy_var_3
+	)}}
+
+happyReduce_60 = happySpecReduce_3  11# happyReduction_60
+happyReduction_60 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op OpLT happy_var_1 happy_var_3
+	)}}
+
+happyReduce_61 = happySpecReduce_3  11# happyReduction_61
+happyReduction_61 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op OpGT happy_var_1 happy_var_3
+	)}}
+
+happyReduce_62 = happySpecReduce_3  11# happyReduction_62
+happyReduction_62 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op OpLE happy_var_1 happy_var_3
+	)}}
+
+happyReduce_63 = happySpecReduce_3  11# happyReduction_63
+happyReduction_63 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op OpGE happy_var_1 happy_var_3
+	)}}
+
+happyReduce_64 = happySpecReduce_3  11# happyReduction_64
+happyReduction_64 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut11 happy_x_3 of { happy_var_3 -> 
+	happyIn15
+		 (Op OpEQ happy_var_1 happy_var_3
+	)}}
+
+happyReduce_65 = happySpecReduce_0  12# happyReduction_65
+happyReduction_65  =  happyIn16
+		 ([]
+	)
+
+happyReduce_66 = happySpecReduce_1  12# happyReduction_66
+happyReduction_66 happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	happyIn16
+		 ([happy_var_1]
+	)}
+
+happyReduce_67 = happySpecReduce_3  12# happyReduction_67
+happyReduction_67 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut16 happy_x_3 of { happy_var_3 -> 
+	happyIn16
+		 (happy_var_1:happy_var_3
+	)}}
+
+happyReduce_68 = happySpecReduce_0  13# happyReduction_68
+happyReduction_68  =  happyIn17
+		 ([]
+	)
+
+happyReduce_69 = happySpecReduce_3  13# happyReduction_69
+happyReduction_69 happy_x_3
+	happy_x_2
+	happy_x_1
+	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut5 happy_x_3 of { happy_var_3 -> 
+	happyIn17
+		 ([(happy_var_1,happy_var_3)]
+	)}}
+
+happyReduce_70 = happyReduce 5# 13# happyReduction_70
+happyReduction_70 (happy_x_5 `HappyStk`
+	happy_x_4 `HappyStk`
+	happy_x_3 `HappyStk`
+	happy_x_2 `HappyStk`
+	happy_x_1 `HappyStk`
+	happyRest)
+	 = case happyOut11 happy_x_1 of { happy_var_1 -> 
+	case happyOut5 happy_x_3 of { happy_var_3 -> 
+	case happyOut17 happy_x_5 of { happy_var_5 -> 
+	happyIn17
+		 ((happy_var_1,happy_var_3):happy_var_5
+	) `HappyStk` happyRest}}}
+
+happyReduce_71 = happySpecReduce_1  14# happyReduction_71
+happyReduction_71 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenInt happy_var_1) -> 
+	happyIn18
+		 (MkInt happy_var_1
+	)}
+
+happyReduce_72 = happySpecReduce_1  14# happyReduction_72
+happyReduction_72 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenBigInt happy_var_1) -> 
+	happyIn18
+		 (MkBigInt happy_var_1
+	)}
+
+happyReduce_73 = happySpecReduce_1  14# happyReduction_73
+happyReduction_73 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenChar happy_var_1) -> 
+	happyIn18
+		 (MkChar happy_var_1
+	)}
+
+happyReduce_74 = happySpecReduce_1  14# happyReduction_74
+happyReduction_74 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenBool happy_var_1) -> 
+	happyIn18
+		 (MkBool happy_var_1
+	)}
+
+happyReduce_75 = happySpecReduce_1  14# happyReduction_75
+happyReduction_75 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenFloat happy_var_1) -> 
+	happyIn18
+		 (MkFloat happy_var_1
+	)}
+
+happyReduce_76 = happySpecReduce_1  14# happyReduction_76
+happyReduction_76 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenBigFloat happy_var_1) -> 
+	happyIn18
+		 (MkBigFloat happy_var_1
+	)}
+
+happyReduce_77 = happySpecReduce_1  14# happyReduction_77
+happyReduction_77 happy_x_1
+	 =  case happyOutTok happy_x_1 of { (TokenString happy_var_1) -> 
+	happyIn18
+		 (MkString happy_var_1
+	)}
+
+happyReduce_78 = happySpecReduce_1  14# happyReduction_78
+happyReduction_78 happy_x_1
+	 =  happyIn18
+		 (MkUnit
+	)
+
+happyReduce_79 = happySpecReduce_1  14# happyReduction_79
+happyReduction_79 happy_x_1
+	 =  happyIn18
+		 (MkUnused
+	)
+
+happyReduce_80 = happyMonadReduce 0# 15# happyReduction_80
+happyReduction_80 (happyRest) tk
+	 = happyThen (( getLineNo)
+	) (\r -> happyReturn (happyIn19 r))
+
+happyReduce_81 = happyMonadReduce 0# 16# happyReduction_81
+happyReduction_81 (happyRest) tk
+	 = happyThen (( getFileName)
+	) (\r -> happyReturn (happyIn20 r))
+
+happyNewToken action sts stk
+	= lexer(\tk -> 
+	let cont i = happyDoAction i tk action sts stk in
+	case tk of {
+	TokenEOF -> happyDoAction 67# tk action sts stk;
+	TokenName happy_dollar_dollar -> cont 1#;
+	TokenString happy_dollar_dollar -> cont 2#;
+	TokenInt happy_dollar_dollar -> cont 3#;
+	TokenBigInt happy_dollar_dollar -> cont 4#;
+	TokenBool happy_dollar_dollar -> cont 5#;
+	TokenFloat happy_dollar_dollar -> cont 6#;
+	TokenBigFloat happy_dollar_dollar -> cont 7#;
+	TokenChar happy_dollar_dollar -> cont 8#;
+	TokenIntType -> cont 9#;
+	TokenBigIntType -> cont 10#;
+	TokenCharType -> cont 11#;
+	TokenBoolType -> cont 12#;
+	TokenFloatType -> cont 13#;
+	TokenBigFloatType -> cont 14#;
+	TokenStringType -> cont 15#;
+	TokenPtrType -> cont 16#;
+	TokenUnitType -> cont 17#;
+	TokenFunType -> cont 18#;
+	TokenDataType -> cont 19#;
+	TokenAnyType -> cont 20#;
+	TokenUnit -> cont 21#;
+	TokenCon -> cont 22#;
+	TokenDefault -> cont 23#;
+	TokenLet -> cont 24#;
+	TokenCase -> cont 25#;
+	TokenOf -> cont 26#;
+	TokenIf -> cont 27#;
+	TokenThen -> cont 28#;
+	TokenElse -> cont 29#;
+	TokenWhile -> cont 30#;
+	TokenUnused -> cont 31#;
+	TokenIn -> cont 32#;
+	TokenLazy -> cont 33#;
+	TokenStrict -> cont 34#;
+	TokenEffect -> cont 35#;
+	TokenForeign -> cont 36#;
+	TokenError -> cont 37#;
+	TokenImpossible -> cont 38#;
+	TokenOB -> cont 39#;
+	TokenCB -> cont 40#;
+	TokenOCB -> cont 41#;
+	TokenCCB -> cont 42#;
+	TokenOSB -> cont 43#;
+	TokenCSB -> cont 44#;
+	TokenPlus -> cont 45#;
+	TokenMinus -> cont 46#;
+	TokenTimes -> cont 47#;
+	TokenDivide -> cont 48#;
+	TokenEquals -> cont 49#;
+	TokenEQ -> cont 50#;
+	TokenLE -> cont 51#;
+	TokenGE -> cont 52#;
+	TokenLT -> cont 53#;
+	TokenGT -> cont 54#;
+	TokenColon -> cont 55#;
+	TokenProj -> cont 56#;
+	TokenSemi -> cont 57#;
+	TokenComma -> cont 58#;
+	TokenBar -> cont 59#;
+	TokenArrow -> cont 60#;
+	TokenCInclude -> cont 61#;
+	TokenExtern -> cont 62#;
+	TokenExport -> cont 63#;
+	TokenCType -> cont 64#;
+	TokenInclude -> cont 65#;
+	TokenInline -> cont 66#;
+	_ -> happyError' tk
+	})
+
+happyError_ tk = happyError' tk
+
+happyThen :: () => P a -> (a -> P b) -> P b
+happyThen = (thenP)
+happyReturn :: () => a -> P a
+happyReturn = (returnP)
+happyThen1 = happyThen
+happyReturn1 :: () => a -> P a
+happyReturn1 = happyReturn
+happyError' :: () => (Token) -> P a
+happyError' tk = (\token -> happyError) tk
+
+mkparse = happySomeParser where
+  happySomeParser = happyThen (happyParse 0#) (\x -> happyReturn (happyOut4 x))
+
+happySeq = happyDontSeq
+
+
+mkBind :: Name -> [Type] -> Type -> [Name] -> Expr -> Maybe String -> [CGFlag] -> Decl
+mkBind n tys ret ns expr export fl = Decl n ret (Bind (zip ns tys) 0 expr fl) export fl
+
+mkExtern :: Name -> [Type] -> Type -> [Name] -> Decl
+mkExtern n tys ret ns = Extern n ret tys
+
+parse :: String -> FilePath -> Result [Decl]
+parse s fn = mkparse s fn 1
+
+parseFile :: FilePath -> IO (Result [Decl])
+parseFile fn = do s <- readFile fn
+                  let x = parse s fn
+                  return x
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+{-# LINE 1 "<built-in>" #-}
+{-# LINE 1 "<command line>" #-}
+{-# LINE 1 "templates/GenericTemplate.hs" #-}
+-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp 
+
+{-# LINE 28 "templates/GenericTemplate.hs" #-}
+
+
+data Happy_IntList = HappyCons Int# Happy_IntList
+
+
+
+
+
+{-# LINE 49 "templates/GenericTemplate.hs" #-}
+
+{-# LINE 59 "templates/GenericTemplate.hs" #-}
+
+{-# LINE 68 "templates/GenericTemplate.hs" #-}
+
+infixr 9 `HappyStk`
+data HappyStk a = HappyStk a (HappyStk a)
+
+-----------------------------------------------------------------------------
+-- starting the parse
+
+happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll
+
+-----------------------------------------------------------------------------
+-- Accepting the parse
+
+-- If the current token is 0#, it means we've just accepted a partial
+-- parse (a %partial parser).  We must ignore the saved token on the top of
+-- the stack in this case.
+happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =
+	happyReturn1 ans
+happyAccept j tk st sts (HappyStk ans _) = 
+	(happyTcHack j (happyTcHack st)) (happyReturn1 ans)
+
+-----------------------------------------------------------------------------
+-- Arrays only: do the next action
+
+
+
+happyDoAction i tk st
+	= {- nothing -}
+
+
+	  case action of
+		0#		  -> {- nothing -}
+				     happyFail i tk st
+		-1# 	  -> {- nothing -}
+				     happyAccept i tk st
+		n | (n <# (0# :: Int#)) -> {- nothing -}
+
+				     (happyReduceArr ! rule) i tk st
+				     where rule = (I# ((negateInt# ((n +# (1# :: Int#))))))
+		n		  -> {- nothing -}
+
+
+				     happyShift new_state i tk st
+				     where new_state = (n -# (1# :: Int#))
+   where off    = indexShortOffAddr happyActOffsets st
+	 off_i  = (off +# i)
+	 check  = if (off_i >=# (0# :: Int#))
+			then (indexShortOffAddr happyCheck off_i ==#  i)
+			else False
+ 	 action | check     = indexShortOffAddr happyTable off_i
+		| otherwise = indexShortOffAddr happyDefActions st
+
+{-# LINE 127 "templates/GenericTemplate.hs" #-}
+
+
+indexShortOffAddr (HappyA# arr) off =
+#if __GLASGOW_HASKELL__ > 500
+	narrow16Int# i
+#elif __GLASGOW_HASKELL__ == 500
+	intToInt16# i
+#else
+	(i `iShiftL#` 16#) `iShiftRA#` 16#
+#endif
+  where
+#if __GLASGOW_HASKELL__ >= 503
+	i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
+#else
+	i = word2Int# ((high `shiftL#` 8#) `or#` low)
+#endif
+	high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
+	low  = int2Word# (ord# (indexCharOffAddr# arr off'))
+	off' = off *# 2#
+
+
+
+
+
+data HappyAddr = HappyA# Addr#
+
+
+
+
+-----------------------------------------------------------------------------
+-- HappyState data type (not arrays)
+
+{-# LINE 170 "templates/GenericTemplate.hs" #-}
+
+-----------------------------------------------------------------------------
+-- Shifting a token
+
+happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =
+     let i = (case unsafeCoerce# x of { (I# (i)) -> i }) in
+--     trace "shifting the error token" $
+     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)
+
+happyShift new_state i tk st sts stk =
+     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)
+
+-- happyReduce is specialised for the common cases.
+
+happySpecReduce_0 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_0 nt fn j tk st@((action)) sts stk
+     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)
+
+happySpecReduce_1 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')
+     = let r = fn v1 in
+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
+
+happySpecReduce_2 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')
+     = let r = fn v1 v2 in
+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
+
+happySpecReduce_3 i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')
+     = let r = fn v1 v2 v3 in
+       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
+
+happyReduce k i fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happyReduce k nt fn j tk st sts stk
+     = case happyDrop (k -# (1# :: Int#)) sts of
+	 sts1@((HappyCons (st1@(action)) (_))) ->
+        	let r = fn stk in  -- it doesn't hurt to always seq here...
+       		happyDoSeq r (happyGoto nt j tk st1 sts1 r)
+
+happyMonadReduce k nt fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happyMonadReduce k nt fn j tk st sts stk =
+        happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))
+       where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))
+             drop_stk = happyDropStk k stk
+
+happyMonad2Reduce k nt fn 0# tk st sts stk
+     = happyFail 0# tk st sts stk
+happyMonad2Reduce k nt fn j tk st sts stk =
+       happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))
+       where sts1@((HappyCons (st1@(action)) (_))) = happyDrop k (HappyCons (st) (sts))
+             drop_stk = happyDropStk k stk
+
+             off    = indexShortOffAddr happyGotoOffsets st1
+             off_i  = (off +# nt)
+             new_state = indexShortOffAddr happyTable off_i
+
+
+
+
+happyDrop 0# l = l
+happyDrop n (HappyCons (_) (t)) = happyDrop (n -# (1# :: Int#)) t
+
+happyDropStk 0# l = l
+happyDropStk n (x `HappyStk` xs) = happyDropStk (n -# (1#::Int#)) xs
+
+-----------------------------------------------------------------------------
+-- Moving to a new state after a reduction
+
+
+happyGoto nt j tk st = 
+   {- nothing -}
+   happyDoAction j tk new_state
+   where off    = indexShortOffAddr happyGotoOffsets st
+	 off_i  = (off +# nt)
+ 	 new_state = indexShortOffAddr happyTable off_i
+
+
+
+
+-----------------------------------------------------------------------------
+-- Error recovery (0# is the error token)
+
+-- parse error if we are in recovery and we fail again
+happyFail  0# tk old_st _ stk =
+--	trace "failing" $ 
+    	happyError_ tk
+
+{-  We don't need state discarding for our restricted implementation of
+    "error".  In fact, it can cause some bogus parses, so I've disabled it
+    for now --SDM
+
+-- discard a state
+happyFail  0# tk old_st (HappyCons ((action)) (sts)) 
+						(saved_tok `HappyStk` _ `HappyStk` stk) =
+--	trace ("discarding state, depth " ++ show (length stk))  $
+	happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))
+-}
+
+-- Enter error recovery: generate an error token,
+--                       save the old token and carry on.
+happyFail  i tk (action) sts stk =
+--      trace "entering error recovery" $
+	happyDoAction 0# tk action sts ( (unsafeCoerce# (I# (i))) `HappyStk` stk)
+
+-- Internal happy errors:
+
+notHappyAtAll = error "Internal Happy error\n"
+
+-----------------------------------------------------------------------------
+-- Hack to get the typechecker to accept our action functions
+
+
+happyTcHack :: Int# -> a -> a
+happyTcHack x y = y
+{-# INLINE happyTcHack #-}
+
+
+-----------------------------------------------------------------------------
+-- Seq-ing.  If the --strict flag is given, then Happy emits 
+--	happySeq = happyDoSeq
+-- otherwise it emits
+-- 	happySeq = happyDontSeq
+
+happyDoSeq, happyDontSeq :: a -> b -> b
+happyDoSeq   a b = a `seq` b
+happyDontSeq a b = b
+
+-----------------------------------------------------------------------------
+-- Don't inline any functions from the template.  GHC has a nasty habit
+-- of deciding to inline happyGoto everywhere, which increases the size of
+-- the generated parser quite a bit.
+
+
+{-# NOINLINE happyDoAction #-}
+{-# NOINLINE happyTable #-}
+{-# NOINLINE happyCheck #-}
+{-# NOINLINE happyActOffsets #-}
+{-# NOINLINE happyGotoOffsets #-}
+{-# NOINLINE happyDefActions #-}
+
+{-# NOINLINE happyShift #-}
+{-# NOINLINE happySpecReduce_0 #-}
+{-# NOINLINE happySpecReduce_1 #-}
+{-# NOINLINE happySpecReduce_2 #-}
+{-# NOINLINE happySpecReduce_3 #-}
+{-# NOINLINE happyReduce #-}
+{-# NOINLINE happyMonadReduce #-}
+{-# NOINLINE happyGoto #-}
+{-# NOINLINE happyFail #-}
+
+-- end of Happy Template.
diff --git a/epic.cabal b/epic.cabal
--- a/epic.cabal
+++ b/epic.cabal
@@ -1,5 +1,5 @@
 Name:		epic
-Version:	0.1.2
+Version:	0.1.3
 Author:		Edwin Brady
 License:	BSD3
 License-file:	LICENSE
@@ -10,18 +10,30 @@
 Synopsis:	Compiler for a supercombinator language
 Description:    Epic is a simple functional language which compiles to
                 reasonably efficient C code, using the Boehm-Demers-Weiser 
-	        garbage collector. It is currently used as a back end for 
-	        the Idris dependently typed programming language. It is invoked
-                as a library, as it is intended as a compiler back end.
+	        garbage collector (<http://www.hpl.hp.com/personal/Hans_Boehm/gc/>). 
+                It is intended as a compiler back end, and is currently used 
+                as a back end for Epigram (<http://www.e-pig.org>) and Idris 
+                (<http://www.cs.st-and.ac.uk/~eb/Idris>).
+	        It can be invoked either as a library or an application.
 
-Build-depends:	base, haskell98, mtl, Cabal, array, directory
-Build-type:     Simple
+Data-files:    evm/libevm.a evm/closure.h evm/stdfuns.h evm/stdfuns.c evm/mainprog.c 
+Extra-source-files: evm/closure.c evm/closure.h evm/stdfuns.h evm/mainprog.c evm/stdfuns.c evm/Makefile 
 
-Extensions:	MultiParamTypeClasses, FunctionalDependencies,
-		ExistentialQuantification, OverlappingInstances
-Exposed-modules: Epic.Compiler
-Other-modules: Epic.Bytecode Epic.Parser Epic.Scopecheck
-               Epic.Language Epic.Lexer Epic.CodegenC
-	       Epic.OTTLang Paths_epic
-Data-files:    evm/libevm.a evm/closure.h evm/stdfuns.h evm/mainprog.c
-Extra-source-files: evm/closure.c evm/closure.h evm/stdfuns.h evm/mainprog.c evm/Makefile
+Cabal-Version:  >= 1.2.3
+Build-type:     Custom
+
+Library
+        Exposed-modules: Epic.Compiler
+        Other-modules: Epic.Bytecode Epic.Parser Epic.Scopecheck
+                       Epic.Language Epic.Lexer Epic.CodegenC
+                       Epic.OTTLang Epic.Simplify Paths_epic
+        Build-depends:	base <=4 , haskell98, mtl, Cabal, array, directory
+
+
+Executable     epic
+               Main-is: Main.lhs
+               Other-modules: Epic.Bytecode Epic.Parser Epic.Scopecheck
+                              Epic.Language Epic.Lexer Epic.CodegenC
+                              Epic.OTTLang Epic.Simplify Paths_epic
+               Build-depends:	base, haskell98, mtl, Cabal, array, directory
+
diff --git a/evm/Makefile b/evm/Makefile
--- a/evm/Makefile
+++ b/evm/Makefile
@@ -1,5 +1,6 @@
 CC = gcc
-CFLAGS = -g -Wall # -O2
+CFLAGS = -Wall -g
+#CFLAGS = -Wall -O3
 OBJS = closure.o stdfuns.o
 INSTALLDIR = ${PREFIX}/lib/evm
 
diff --git a/evm/closure.c b/evm/closure.c
--- a/evm/closure.c
+++ b/evm/closure.c
@@ -6,12 +6,38 @@
 #include <gmp.h>
 
 VAL one;
+VAL* zcon;
+void* blob = NULL;
+int blobnext = 0;
 
-void dumpCon(con* c) {
-    printf("%d", c->tag);
+void* FASTMALLOC(int size) {
+    if (blob == NULL) { blob = malloc(10001000); }
+    void* newblock = blob+blobnext;
+    blobnext+=((size+4) & 0xfffffffc);
+    if (blobnext>10000000) blobnext=0;
+    return newblock;
 }
 
-void dumpClosure(Closure* c) {
+void dumpClosureA(Closure* c, int rec);
+
+void dumpCon(con* c, int rec) {
+    int x,arity;
+    if (!rec) { printf("TAG(%d)", c->tag & 65535); }
+
+    arity = c->tag >> 16;
+    if (arity>0 && !rec) { printf(": "); }
+
+    for(x=0; x<arity; ++x) {
+	dumpClosureA(c->args[x], rec);
+	if (x!=(arity-1)) { printf(", "); }
+    }
+}
+
+void dumpRecord(Closure* r) {
+    dumpClosureA(r, 1);
+}
+
+void dumpClosureA(Closure* c, int rec) {
     switch(GETTY(c)) {
     case FUN:
 	printf("FUN[");
@@ -20,11 +46,11 @@
 	printf("THUNK[");
 	break;
     case CON:
-	printf("CON[");
-	dumpCon((con*)c->info);
+	if (!rec) { printf("CON["); } else { printf("["); }
+	dumpCon((con*)c->info, rec);
 	break;
     case INT:
-	printf("INT[%d", ((int)c)>>1);
+	if (!rec) { printf("INT[%d", ((int)c)>>1); } else { printf("[%d", ((int)c)>>1); }
 	break;
     case BIGINT:
 	printf("BIGINT[");
@@ -50,10 +76,25 @@
     default:
 	printf("[%d,%d", GETTY(c), (int)c->info);
     }
-    printf("]\n");
+    printf("]");
 }
 
+void dumpClosure(Closure* c) {
+    dumpClosureA(c,0);
+    printf("\n");
+}
 
+void assertConR(Closure* c) 
+{
+    if (c==NULL) { printf("Null constructor\n"); assert(0); }
+    if (!ISCON(c)) { dumpClosure(c); assert(0); }
+}
+
+void assertIntR(Closure* c) 
+{
+    if (!ISINT(c)) { dumpClosure(c); assert(0); }
+}
+
 inline VAL CLOSURE(func x, int arity, int args, void** block)
 {
     VAL c = EMALLOC(sizeof(Closure)+sizeof(fun)); // MKCLOSURE;
@@ -74,11 +115,11 @@
     return c;
 }
 
-inline VAL CONSTRUCTOR(int tag, int arity, void** block)
+inline VAL CONSTRUCTORn(int tag, int arity, void** block)
 {
     VAL c = EMALLOC(sizeof(Closure)+sizeof(con)); // MKCLOSURE;
     con* cn = (con*)(c+1);
-    cn->tag = tag;
+    cn->tag = tag + (arity << 16);
     if (arity==0) {
 	cn->args = 0;
     } else {
@@ -92,10 +133,10 @@
 
 inline VAL CONSTRUCTOR1(int tag, VAL a1)
 {
-    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)); // MKCLOSURE;
+    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)+sizeof(VAL)); // MKCLOSURE;
     con* cn = (con*)(c+1);
-    cn->tag = tag;
-    cn->args = MKARGS(1);
+    cn->tag = tag + (1 << 16);
+    cn->args = (void*)c+sizeof(Closure)+sizeof(con); // MKARGS(1);
     cn->args[0] = a1;
     SETTY(c,CON);
     c->info = (void*)cn;
@@ -104,10 +145,10 @@
 
 inline VAL CONSTRUCTOR2(int tag, VAL a1, VAL a2)
 {
-    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)); // MKCLOSURE;
+    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)+2*sizeof(VAL)); // MKCLOSURE;
     con* cn = (con*)(c+1);
-    cn->tag = tag;
-    cn->args = MKARGS(2);
+    cn->tag = tag + (2 << 16);
+    cn->args = (void*)c+sizeof(Closure)+sizeof(con); //MKARGS(2);
     cn->args[0] = a1;
     cn->args[1] = a2;
     SETTY(c,CON);
@@ -117,10 +158,10 @@
 
 inline VAL CONSTRUCTOR3(int tag, VAL a1, VAL a2, VAL a3)
 {
-    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)); // MKCLOSURE;
+    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)+3*sizeof(VAL)); // MKCLOSURE;
     con* cn = (con*)(c+1);
-    cn->tag = tag;
-    cn->args = MKARGS(3);
+    cn->tag = tag + (3 << 16);
+    cn->args = (void*)c+sizeof(Closure)+sizeof(con); //MKARGS(3);
     cn->args[0] = a1;
     cn->args[1] = a2;
     cn->args[2] = a3;
@@ -131,10 +172,10 @@
 
 inline VAL CONSTRUCTOR4(int tag, VAL a1, VAL a2, VAL a3, VAL a4)
 {
-    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)); // MKCLOSURE;
+    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)+4*sizeof(VAL)); // MKCLOSURE;
     con* cn = (con*)(c+1);
-    cn->tag = tag;
-    cn->args = MKARGS(2);
+    cn->tag = tag + (4 << 16);
+    cn->args = (void*)c+sizeof(Closure)+sizeof(con); //MKARGS(2);
     cn->args[0] = a1;
     cn->args[1] = a2;
     cn->args[2] = a3;
@@ -146,10 +187,10 @@
 
 inline VAL CONSTRUCTOR5(int tag, VAL a1, VAL a2, VAL a3, VAL a4, VAL a5)
 {
-    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)); // MKCLOSURE;
+    VAL c = EMALLOC(sizeof(Closure)+sizeof(con)+5*sizeof(VAL)); // MKCLOSURE;
     con* cn = (con*)(c+1);
-    cn->tag = tag;
-    cn->args = MKARGS(5);
+    cn->tag = tag + (5 << 16);
+    cn->args = (void*)c+sizeof(Closure)+sizeof(con); //MKARGS(5);
     cn->args[0] = a1;
     cn->args[1] = a2;
     cn->args[2] = a3;
@@ -353,7 +394,7 @@
     thunk* fn = (thunk*)(c+1);
 
     if (ISFUN(f)) {
-	return CLOSURE_ADD2(f,a1,a2);
+	return NULL; //CLOSURE_ADD2(f,a1,a2);
     }
 
     fn->fn = (void*)f;
@@ -449,14 +490,19 @@
     else return aux_CLOSURE_APPLY1(f,a1);
 }
 
+void* block[1024]; // Yes. I know. Better check below that this is big enough.
+
 inline VAL CLOSURE_APPLY2(VAL f, VAL a1, VAL a2)
 {
+    int i;
     if (ISFUN(f)) {
 	fun* finf = (fun*)(f->info);
 	int got = finf->arg_end-finf->args;
 	if (finf->arity == (got+2)) {
-	    void* block[got+2];
-	    memcpy(block, finf->args, got*sizeof(VAL));
+//	    memcpy(block, finf->args, got*sizeof(VAL));
+	    for(i=0; i<got; ++i) {
+		block[i] = finf->args[i];
+	    }
 	    block[got] = a1;
 	    block[got+1] = a2;
 	    return (VAL)(finf->fn(block));
@@ -523,7 +569,7 @@
     else return aux_CLOSURE_APPLY5(f,a1,a2,a3,a4,a5);
 }
 
-VAL DO_EVAL(VAL x) {
+VAL DO_EVAL(VAL x, int update) {
 // dummy value we'll never inspect, leave it alone.
     if (x==NULL) return x; 
 
@@ -555,17 +601,17 @@
 	    // if it was a foreign/io call in particular.
 	    if (result) {
 		if (GETTY(result)==FUN || GETTY(result)==THUNK) {
-		    result=DO_EVAL(result);
+		    result=DO_EVAL(result, update);
 		}
 /*		if (ISINT(result)) {
 		    printf("Updating with %d\n", x);
 		} else {
 		    printf("Updating %d %d with %d\n", x, GETTY(x), result);
 		    }*/
-		UPDATE(x,result);
+		if (update) { UPDATE(x,result); } else { return result; }
 	    }
 	    else {
-		SETTY(x, INT); x->info=(void*)42;
+		if (update) { SETTY(x, INT); x->info=(void*)42; } else { return NULL; }
 	    }
 	}
 	// If there are too many arguments, run it with the right number
@@ -573,20 +619,20 @@
 	else if (excess > 0) {
 	    result = fn->fn(fn->args);
 	    result = CLOSURE_APPLY(result, excess, fn->args + fn->arity);
-	    result = DO_EVAL(result);
-	    UPDATE(x,result);
+	    result = DO_EVAL(result, update);
+	    if (update) { UPDATE(x,result); } else { return result; }
 	    return x;
 	}
 	break;
     case THUNK:
 	th = (thunk*)(x->info);
 	// Evaluate inner thunk, which should give us a function
-	th->fn = DO_EVAL((VAL)(th->fn));
+	VAL nextfn = DO_EVAL((VAL)(th->fn), update);
 	// Apply this thunk's arguments to it
-	CLOSURE_APPLY((VAL)th->fn, th->numargs, th->args);
+	CLOSURE_APPLY((VAL)nextfn, th->numargs, th->args);
 	// And off we go again...
-	th->fn = DO_EVAL((VAL)(th->fn));
-	UPDATE(x,((VAL)(th->fn)));
+	nextfn = DO_EVAL(nextfn, update);
+	if (update) { UPDATE(x, nextfn); } else { return nextfn; }
 	return x;
 	break;
     default:
@@ -604,14 +650,14 @@
 }
 */
 
-void* MKINT(int x)
+ /*void* MKINT(int x)
 {
     return (void*)((x<<1)+1);
 //    VAL c = MKCLOSURE;
 //    SETTY(c, INT);
 //    c->info = (void*)x;
 //    return c;
-}
+}*/
 
 void* NEWBIGINT(char* intstr)
 {
@@ -639,10 +685,12 @@
     return c;
 }
 
+/*
 int GETINT(void* x)
 {
     return ((int)x)>>1;
 }
+*/
 
 mpz_t* GETBIGINT(void* x)
 {
@@ -652,10 +700,15 @@
 
 void* MKSTR(char* x)
 {
-    VAL c = MKCLOSURE;
+//    VAL c = EMALLOC(sizeof(Closure)+strlen(x)+sizeof(char)+1); //MKCLOSURE;
+    VAL c = EMALLOC(sizeof(Closure));
     SETTY(c, STRING);
-    c->info = (void*)(EMALLOC(strlen(x)*sizeof(char)+1));
-    strcpy(c->info,x);
+//    c->info = ((void*)c)+sizeof(Closure);// (void*)(EMALLOC(strlen(x)*sizeof(char)+1));
+//    strcpy(c->info,x);
+
+// Since MKSTR is used to build strings from foreign calls, the string
+// itself will already have been allocated so we just want the closure.
+    c->info=x;
     return c;
 }
 
@@ -667,15 +720,10 @@
     return c;
 }
 
-char* GETSTR(void* x)
-{
-    return (char*)(((VAL)x)->info);
-}
-
-void* GETPTR(void* x)
-{
-    return (void*)(((VAL)x)->info);
-}
+/* void* GETPTR(void* x) */
+/* { */
+/*     return (void*)(((VAL)x)->info); */
+/* } */
 
 void ERROR(char* msg)
 {
@@ -694,5 +742,10 @@
 
 void init_evm()
 {
+    int i;
     one = MKINT(1);
+    zcon = EMALLOC(sizeof(Closure)*255);
+    for(i=0;i<255;++i) {
+	zcon[i] = CONSTRUCTORn(i,0,0);
+    }
 }
diff --git a/evm/closure.h b/evm/closure.h
--- a/evm/closure.h
+++ b/evm/closure.h
@@ -17,6 +17,10 @@
 #define EREALLOC GC_REALLOC
 #define EFREE GC_FREE
 
+//#define EMALLOC malloc
+//#define EREALLOC realloc
+//#define EFREE free
+
 #define MKCON (con*)EMALLOC(sizeof(con))
 #define MKFUN (fun*)EMALLOC(sizeof(fun))
 #define MKTHUNK (thunk*)EMALLOC(sizeof(thunk))
@@ -24,6 +28,8 @@
 #define MKUNIT (void*)0
 
 #define INTOP(op,x,y) MKINT((((int)x)>>1) op (((int)y)>>1))
+#define ADD(x,y) (void*)(((int)x)+(((int)y)-1))
+#define MULT(x,y) (MKINT((((int)x)>>1) * (((int)y)>>1)))
 #define CHECKEVALUATED(x) if(ISFUN(x) || ISTHUNK(x) \
     || ISFV(x)) return 0;
 
@@ -50,7 +56,14 @@
 } Closure;
 
 void dumpClosure(Closure* c);
+void assertConR(Closure* c);
+void assertIntR(Closure* c);
 
+#define assertCon(x)  
+#define assertInt(x) 
+//assertConR(x)
+//assertIntR(x)
+
 typedef Closure* VAL;
 
 #define GETTY(x) (ISINT(x) ? INT : ((ClosureType)(((x)->ty) >> 24)))
@@ -82,33 +95,45 @@
 
 #define UPDATE(x,res) if (ISINT(res)) { x = MKINT(GETINT(res)); } else { \
                       SETTY(x, GETTY(res)); x->info=res->info; }
-#define TAG(x) ((con*)((Closure*)x)->info)->tag
+#define TAG(x) (((con*)((Closure*)x)->info)->tag & 65535)
+#define ARITY(x) (((con*)((Closure*)x)->info)->tag >> 16)
 
-#define ISCON(x) GETTY(((Closure*)(x)))==CON
+#define ISCON(x) (GETTY(((Closure*)(x)))==CON)
 #define ISINT(x) ((((int)x)&1) == 1)
-#define ISTHUNK(x) GETTY(((Closure*)(x)))==THUNK
-#define ISFUN(x) GETTY(((Closure*)(x)))==FUN
-#define ISFV(x) GETTY(((Closure*)(x)))==FREEVAR
+#define ISTHUNK(x) (GETTY(((Closure*)(x)))==THUNK)
+#define ISFUN(x) (GETTY(((Closure*)(x)))==FUN)
+#define ISFV(x) (GETTY(((Closure*)(x)))==FREEVAR)
 
+#define NEEDSEVAL(x) ((x) && GETTY((Closure*)(x))<CON)
+#define NONEEDSEVAL(x) ((x) && GETTY((Closure*)(x))>=CON)
+
 #ifdef TRACEON
-#define TRACE if(1)
+  #define TRACE if(1)
 #else
-#define TRACE if(0)
+  #define TRACE if(0)
 #endif
 
 // Evaluate x to head normal form
-VAL DO_EVAL(VAL x);
+VAL DO_EVAL(VAL x, int update);
 
 //#define EVAL(x) DO_EVAL(x)
-#define EVAL(x) ((x && (ISTHUNK(x) || ISFUN(x))) ? DO_EVAL(x) : x)
+#define EVAL(x) (!ISINT(x) && NEEDSEVAL(x) ? DO_EVAL(x, 1) : x)
+#define EVALINT(x) (!ISINT(x) ? DO_EVAL(x, 1) : x)
+#define EVAL_NOUP(x) (!ISINT(x) && NEEDSEVAL(x) ? DO_EVAL(x, 0) : x)
+#define EVALINT_NOUP(x) (!ISINT(x) ? DO_EVAL(x, 0) : x)
 
+//#define EVAL(x) ((x && (ISFUN(x) || ISTHUNK(x))) ? DO_EVAL(x, 1) : x)
+//#define EVAL_NOUP(x) ((x && (ISFUN(x) || ISTHUNK(x))) ? DO_EVAL(x, 0) : x)
+
+#define CONSTRUCTOR(t,a,b) ((a)==0 && t<255 ? zcon[t] : CONSTRUCTORn(t,a,b))
+
 // Return a new constructor
-VAL CONSTRUCTOR(int tag, int arity, void** block);
-VAL CONSTRUCTOR1(int tag, VAL a1);
-VAL CONSTRUCTOR2(int tag, VAL a1, VAL a2);
-VAL CONSTRUCTOR3(int tag, VAL a1, VAL a2, VAL a3);
-VAL CONSTRUCTOR4(int tag, VAL a1, VAL a2, VAL a3, VAL a4);
-VAL CONSTRUCTOR5(int tag, VAL a1, VAL a2, VAL a3, VAL a4, VAL a5);
+inline VAL CONSTRUCTORn(int tag, int arity, void** block);
+inline VAL CONSTRUCTOR1(int tag, VAL a1);
+inline VAL CONSTRUCTOR2(int tag, VAL a1, VAL a2);
+inline VAL CONSTRUCTOR3(int tag, VAL a1, VAL a2, VAL a3);
+inline VAL CONSTRUCTOR4(int tag, VAL a1, VAL a2, VAL a3, VAL a4);
+inline VAL CONSTRUCTOR5(int tag, VAL a1, VAL a2, VAL a3, VAL a4, VAL a5);
 
 // Return a new function node
 VAL CLOSURE(func x, int arity, int args, void** block);
@@ -125,6 +150,7 @@
 VAL CLOSURE_APPLY(VAL x, int args, void** block);
 VAL CLOSURE_APPLY1(VAL x, VAL a1);
 VAL CLOSURE_APPLY2(VAL x, VAL a1, VAL a2);
+
 VAL CLOSURE_APPLY3(VAL x, VAL a1, VAL a2, VAL a3);
 VAL CLOSURE_APPLY4(VAL x, VAL a1, VAL a2, VAL a3, VAL a4);
 VAL CLOSURE_APPLY5(VAL x, VAL a1, VAL a2, VAL a3, VAL a4, VAL a5);
@@ -137,7 +163,15 @@
 
 //extern VAL one; 
 
-void* MKINT(int x);
+// array of zero arity constructors. We don't need more than one of each...
+extern VAL* zcon;
+
+#define MKINT(x) ((void*)((x)<<1)+1)
+#define GETINT(x) ((int)(x)>>1)
+#define GETPTR(x) ((void*)(((VAL)(x))->info))
+#define GETSTR(x) ((char*)(((VAL)(x))->info))
+
+//void* MKINT(int x);
 void* NEWBIGINT(char* bigint);
 void* MKBIGINT(mpz_t* bigint);
 
@@ -145,10 +179,10 @@
 void* MKPTR(void* ptr);
 
 // Get values from a closure
-int GETINT(void* x);
+//int GETINT(void* x);
+
 mpz_t* GETBIGINT(void* x);
-char* GETSTR(void* x);
-void* GETPTR(void* x);
+//void* GETPTR(void* x);
 
 void* MKFREE(int x);
 
@@ -158,5 +192,73 @@
 // Initialise everything
 void init_evm();
 
+void* FASTMALLOC(int size);
+
+#define CONSTRUCTOR1m(c,t,x)		\
+    c=EMALLOC(sizeof(Closure)+sizeof(con)+sizeof(VAL)); \
+    ((con*)((VAL)c+1))->tag = t + (1 << 16);			\
+    ((con*)((VAL)c+1))->args = (void*)c+sizeof(Closure)+sizeof(con); \
+    ((con*)((VAL)c+1))->args[0] = x; \
+    SETTY(((VAL)c),CON);	 \
+    ((VAL)c)->info = (void*)((con*)((VAL)c+1));
+
+#define CONSTRUCTOR2m(c,t,x,y)		\
+    c=EMALLOC(sizeof(Closure)+sizeof(con)+2*sizeof(VAL)); \
+    ((con*)((VAL)c+1))->tag = t + (2 << 16);			\
+    ((con*)((VAL)c+1))->args = (void*)c+sizeof(Closure)+sizeof(con); \
+    ((con*)((VAL)c+1))->args[0] = x; \
+    ((con*)((VAL)c+1))->args[1] = y; \
+    SETTY(((VAL)c),CON);	 \
+    ((VAL)c)->info = (void*)((con*)((VAL)c+1));
+
+#define CONSTRUCTOR3m(c,t,x,y,z)		\
+    c=EMALLOC(sizeof(Closure)+sizeof(con)+3*sizeof(VAL)); \
+    ((con*)((VAL)c+1))->tag = t + (3 << 16);			\
+    ((con*)((VAL)c+1))->args = (void*)c+sizeof(Closure)+sizeof(con); \
+    ((con*)((VAL)c+1))->args[0] = x; \
+    ((con*)((VAL)c+1))->args[1] = y; \
+    ((con*)((VAL)c+1))->args[2] = z; \
+    SETTY(((VAL)c),CON);	 \
+    ((VAL)c)->info = (void*)((con*)((VAL)c+1));
+
+#define CONSTRUCTOR4m(c,t,x,y,z,w)			  \
+    c=EMALLOC(sizeof(Closure)+sizeof(con)+4*sizeof(VAL)); \
+    ((con*)((VAL)c+1))->tag = t + (4<< 16);			\
+    ((con*)((VAL)c+1))->args = (void*)c+sizeof(Closure)+sizeof(con); \
+    ((con*)((VAL)c+1))->args[0] = x; \
+    ((con*)((VAL)c+1))->args[1] = y; \
+    ((con*)((VAL)c+1))->args[2] = z; \
+    ((con*)((VAL)c+1))->args[3] = w; \
+    SETTY(((VAL)c),CON);	 \
+    ((VAL)c)->info = (void*)((con*)((VAL)c+1));
+
+#define CONSTRUCTOR5m(c,t,x,y,z,w,v)			  \
+    c=EMALLOC(sizeof(Closure)+sizeof(con)+5*sizeof(VAL)); \
+    ((con*)((VAL)c+1))->tag = t + (5 << 16);			\
+    ((con*)((VAL)c+1))->args = (void*)c+sizeof(Closure)+sizeof(con); \
+    ((con*)((VAL)c+1))->args[0] = x; \
+    ((con*)((VAL)c+1))->args[1] = y; \
+    ((con*)((VAL)c+1))->args[2] = z; \
+    ((con*)((VAL)c+1))->args[3] = w; \
+    ((con*)((VAL)c+1))->args[4] = v; \
+    SETTY(((VAL)c),CON);	 \
+    ((VAL)c)->info = (void*)((con*)((VAL)c+1));
+
+//    s = EMALLOC(sizeof(Closure)+strlen(x)+sizeof(char)+1);	
+
+#define INITSTRING(var, str) \
+    static Closure* var = NULL; \
+    if (var==NULL) { var = MKSTR(str); }
+
+#define MKSTRm(c,s) c = s;
+
+//    SETTY((VAL)c, STRING);				   
+//    ((VAL)(c))->info = ((void*)c)+sizeof(Closure);	   
+//	    strcpy(((VAL)(c))->info,x);
+
+#define MKPTRm(c, x) \
+    c = MKCLOSURE; \
+    SETTY((VAL)c, PTR);				\
+    ((VAL)(c))->info = x; 
 
 #endif
diff --git a/evm/libevm.a b/evm/libevm.a
Binary files a/evm/libevm.a and b/evm/libevm.a differ
diff --git a/evm/mainprog.c b/evm/mainprog.c
--- a/evm/mainprog.c
+++ b/evm/mainprog.c
@@ -12,6 +12,20 @@
 int main(int argc, char* argv[]) {
     GC_init();
     init_evm();
+//    GC_use_entire_heap = 1;
+//    GC_free_space_divisor = 1;
+//    fprintf(stderr, "Heap: %d\n", GC_get_heap_size());
+    GC_expand_hp(1000000);
+//    fprintf(stderr, "Heap: %d\n", GC_get_heap_size());
+
+//    GC_disable();
+
     _do___U__main();
+
+    GC_gcollect();
+/*    fprintf(stderr, "%d\n", GC_gc_no);
+    fprintf(stderr, "Heap: %d\n", GC_get_heap_size());
+    fprintf(stderr, "Free: %d\n", GC_get_free_bytes());
+    fprintf(stderr, "Total: %d\n", GC_get_total_bytes());*/
     return 0; 
 }
diff --git a/evm/stdfuns.c b/evm/stdfuns.c
new file mode 100644
--- /dev/null
+++ b/evm/stdfuns.c
@@ -0,0 +1,339 @@
+#include "stdfuns.h"
+#include "closure.h"
+#include <stdlib.h>
+#include <gmp.h>
+#include <string.h>
+#include <sys/time.h>
+
+void printInt(int x) { printf("%d\n",x); }
+void putStr(char* s) { printf("%s",s); }
+void printBigInt(mpz_t x) { printf("%s\n",mpz_get_str(NULL,10,x)); }
+
+void epicGC() {
+    GC_gcollect();
+}
+
+void epicMemInfo() {
+    GC_gcollect();
+    int heap = GC_get_heap_size();
+    int free = GC_get_free_bytes();
+    int total = GC_get_total_bytes();
+
+    printf("Heap size %d\n", heap);
+    printf("Heap used %d\n", heap-free);
+    printf("Total allocations %d\n", total);
+}
+
+int readInt() {
+    return atoi(readStr());
+}
+
+// FIXME: Do this properly!
+char* readStr() {
+    char *buf = NULL;
+    if (buf==NULL) { buf = EMALLOC(sizeof(char)*512); } // yeah, right...
+    fgets(buf,512,stdin);
+    char *loc = strchr(buf,'\n');
+    *loc = '\0';
+    return buf;
+}
+
+// FIXME: Do this properly!
+void* freadStr(void* h) {
+    static char bufin[128];
+    bufin[0]='\0';
+
+    FILE* f = (FILE*)h;
+    fgets(bufin,128,f);
+    int len = strlen(bufin);
+
+    VAL c = GC_MALLOC_ATOMIC(sizeof(Closure)+len*sizeof(char)+sizeof(char)+1);
+    SETTY(c, STRING);
+    c->info = ((void*)(c+1));
+    char *buf = (char*)(c->info);
+    strcpy(buf,bufin);
+
+    char *loc = strchr(buf,'\n');
+    if (loc) *loc = '\0'; else buf[0]='\0';
+    return ((void*)c);
+}
+
+void fputStr(void* h, char* str) {
+    FILE* f = (FILE*)h;
+    fputs(str, f);
+}
+
+int streq(char* x, char* y) {
+    return !(strcmp(x,y));
+}
+
+int strlt(char* x, char* y) {
+    return strcmp(x,y)<0;
+}
+
+int strToInt(char* str)
+{
+    return strtol(str,NULL,10);
+}
+
+char* intToStr(int x)
+{
+    char* buf = EMALLOC(16);
+    sprintf(buf,"%d",x);
+    return buf;
+}
+
+void* getNative(void * fn) {
+    return fn;
+}
+
+int strIndex(char* str, int i)
+{
+    return (int)(str[i]);
+}
+
+int strHead(char* str) {
+    if (str[0]=='\0') 
+	ERROR("Can't take the head of an empty string");
+    return (int)(str[0]);
+}
+
+char* strTail(char* str) {
+    if (str[0]=='\0') 
+	ERROR("Can't take the tail of an empty string");
+    return str+1; // I'll need to check the GC will understand this...
+}
+
+char* strCons(int h, char* str) {
+    char* buf = EMALLOC((1+strlen(str))*sizeof(char));
+    buf[0]=(char)h;
+    strcpy(buf+1, str);
+    return buf;
+}
+
+char* append(char* x, char* y) {
+    char* buf = EMALLOC((strlen(x)+strlen(y))*sizeof(char));
+    strcpy(buf,x);
+    strcat(buf,y);
+    return buf;
+}
+
+mpz_t* addBigInt(mpz_t x, mpz_t y) {
+    mpz_t* answer = EMALLOC(sizeof(mpz_t));
+    mpz_add(*answer, x, y);
+    return answer;
+}
+
+mpz_t* subBigInt(mpz_t x, mpz_t y) {
+    mpz_t* answer = EMALLOC(sizeof(mpz_t));
+    mpz_sub(*answer, x, y);
+    return answer;
+}
+
+mpz_t* mulBigInt(mpz_t x, mpz_t y) {
+    mpz_t* answer = EMALLOC(sizeof(mpz_t));
+    mpz_mul(*answer, x, y);
+    return answer;
+}
+
+mpz_t* divBigInt(mpz_t x, mpz_t y) {
+    mpz_t* answer = EMALLOC(sizeof(mpz_t));
+    mpz_tdiv_q(*answer, x, y);
+    return answer;
+}
+
+mpz_t* modBigInt(mpz_t x, mpz_t y) {
+    mpz_t* answer = EMALLOC(sizeof(mpz_t));
+    mpz_tdiv_r(*answer, x, y);
+    return answer;
+}
+
+int eqBigInt(mpz_t x, mpz_t y) {
+    return mpz_cmp(x,y)==0;
+}
+
+int ltBigInt(mpz_t x, mpz_t y)
+{
+    return mpz_cmp(x,y)<0;
+}
+
+int gtBigInt(mpz_t x, mpz_t y)
+{
+    return mpz_cmp(x,y)>0;
+}
+
+int leBigInt(mpz_t x, mpz_t y)
+{
+    return mpz_cmp(x,y)<=0;
+}
+
+int geBigInt(mpz_t x, mpz_t y)
+{
+    return mpz_cmp(x,y)>=0;
+}
+
+mpz_t* strToBigInt(char* str)
+{
+    mpz_t* answer = EMALLOC(sizeof(mpz_t));
+    mpz_init(*answer);
+    mpz_set_str(*answer, str, 10);
+    return answer;
+}
+
+char* bigIntToStr(mpz_t x)
+{
+    char* str = mpz_get_str(NULL,10,x);
+    char* buf = EMALLOC(strlen(str)+1);
+    strcpy(buf,str);
+    free(str);
+    return buf;
+}
+
+// IORefs
+int numrefs = 0;
+void** iorefs = NULL;
+
+int newRef() {
+    // Increase space for the iorefs
+    if (iorefs==NULL) {
+	iorefs = (void**)(EMALLOC(sizeof(void*)));
+	numrefs=1;
+    } else {
+	iorefs = (void**)(EREALLOC(iorefs, sizeof(void*)*(numrefs+1)));
+	numrefs++;
+    }
+    return numrefs-1;
+}
+
+void* readRef(int r) {
+    return iorefs[r];
+}
+
+void writeRef(int r, void* val) {
+    iorefs[r]=val;
+}
+
+// Threads and locks
+
+typedef struct {
+    pthread_mutex_t m_id;
+} Mutex;
+
+typedef struct {
+    pthread_t t_id;
+} Thread;
+
+Mutex** ms = NULL;
+int mutexes = 0;
+
+int newLock(int sem)
+{
+    pthread_mutex_t m;
+
+    pthread_mutex_init(&m, NULL);
+    Mutex* newm = EMALLOC(sizeof(Mutex));
+    newm->m_id = m;
+
+    // Increase space for the mutexes
+    if (ms==NULL) {
+	ms = (Mutex**)EMALLOC(sizeof(Mutex*));
+	mutexes=1;
+    } else {
+	ms = (Mutex**)(EREALLOC(ms, sizeof(Mutex*)*(mutexes+1)));
+	mutexes++;
+    }
+
+    ms[mutexes-1] = newm;
+    return mutexes-1;
+}
+
+void doLock(int lock)
+{
+    pthread_mutex_lock(&(ms[lock]->m_id));
+}
+
+void doUnlock(int lock)
+{
+    pthread_mutex_unlock(&(ms[lock]->m_id));
+}
+
+struct threadinfo {
+    void* proc;
+    void* result;
+};
+
+void* runThread(void* th_in) {
+    struct threadinfo* th = (struct threadinfo*)th_in;
+    void* v = DO_EVAL(th->proc, 1);
+    th->result = v;
+    return v;
+}
+
+void doFork(void* proc)
+{
+    pthread_t* t = EMALLOC(sizeof(pthread_t));
+    struct threadinfo th;
+    th.proc = proc;
+    th.result = NULL;
+    pthread_create(t, NULL, runThread, &th);
+}
+
+void* doWithin(int limit, void* proc, void* doOnFail)
+{
+    pthread_t* t = EMALLOC(sizeof(pthread_t));
+//    printf("CREATING THREAD %d\n", t);
+    struct threadinfo th;
+    th.proc = proc;
+    th.result = NULL;
+
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    int tnow, tthen = do_utime();
+
+    pthread_create(t, NULL, runThread, &th);
+//    printf("tthen %d\n", tthen);
+
+    void* ans;
+
+    do 
+    {
+	// If the answer has been updated, we're done.
+	if (th.result!=NULL) {
+	    pthread_join(*t, &ans);
+	    return ans;
+	}
+	gettimeofday(&tv, NULL);
+	tnow = do_utime();
+	usleep(100);
+//	printf("tnow %d\n", tnow);
+    }
+    while(tnow<(tthen+(limit*1000)));
+    pthread_cancel(*t);
+    return DO_EVAL(doOnFail,1);
+}
+
+int do_utime() {
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+
+    static int start=0;
+    if (start==0) { start = tv.tv_sec; }
+
+    return 1000000*(tv.tv_sec - start)+tv.tv_usec;
+}
+
+// Basic file handling
+
+void* fileOpen(char* name, char* mode) {
+    FILE* f = fopen(name, mode);
+    return (void*)f;
+}
+
+void fileClose(void* h) {
+    FILE* f = (FILE*)h;
+    fclose(f);
+}
+
+int isNull(void* ptr) {
+    return ptr==NULL;
+}
diff --git a/evm/stdfuns.h b/evm/stdfuns.h
--- a/evm/stdfuns.h
+++ b/evm/stdfuns.h
@@ -21,13 +21,17 @@
 
 // dump memory usage (from libgc)
 void epicMemInfo();
+// Force garbage collection
+void epicGC();
 
 int readInt();
 char* readStr();
+int streq(char* x, char* y);
+int strlt(char* x, char* y);
 
 void* fileOpen(char* name, char* mode);
 void fileClose(void* h);
-char* freadStr(void* h);
+void* freadStr(void* h);
 void fputStr(void* h, char* str);
 
 int isNull(void* ptr);
@@ -42,7 +46,10 @@
 void doLock(int lock);
 void doUnlock(int lock);
 void doFork(void* proc);
+void* doWithin(int limit, void* proc, void* doOnFail);
 
+int do_utime() ;
+
 int strToInt(char* str);
 char* intToStr(int x);
 
@@ -55,6 +62,9 @@
 // String operations
 
 int strIndex(char* str, int i);
+int strHead(char* str);
+char* strTail(char* str);
+char* strCons(int h, char* str);
 char* append(char* x, char* y);
 
 // Big integer arithmetic
@@ -63,6 +73,7 @@
 mpz_t* subBigInt(mpz_t x, mpz_t y);
 mpz_t* mulBigInt(mpz_t x, mpz_t y);
 mpz_t* divBigInt(mpz_t x, mpz_t y);
+mpz_t* modBigInt(mpz_t x, mpz_t y);
 
 int eqBigInt(mpz_t x, mpz_t y);
 int ltBigInt(mpz_t x, mpz_t y);
