codegenTop :: S.Expr -> LLVM ()
codegenTop (S.Function name args body) = do
  define double name fnargs bls
  where
    fnargs = toSig args
    bls = createBlocks $ execCodegen $ do
      entry <- addBlock entryBlockName
      setBlock entry
      forM args $ \varDef -> do
        let varName = varDefName varDef
        var <- alloca double
        store var (local (AST.Name varName))
        assign varName var
      cgen body >>= ret
codegenTop :: S.Expr -> LLVM ()
codegenTop (S.Function name args body) = do
  define double name fnargs bls
  where
    fnargs = toSig args
    bls = createBlocks $ execCodegen $ do
      entry <- addBlock entryBlockName
      setBlock entry
      forM args $ \varDef -> do
        let varName = varDefName varDef
        var <- alloca double
        store var (local (AST.Name varName))
        assign varName var
      cgen body >>= ret
codegenTop (S.Function name args body) = do
  define double name fnargs bls
  where
    fnargs = toSig args
    bls = createBlocks $ execCodegen $ do
      entry <- addBlock entryBlockName
      setBlock entry
      forM args $ \varDef -> do
        let varName = varDefName varDef
        var <- alloca double
        store var (local (AST.Name varName))
        assign varName var
      cgen body >>= ret