{-# LANGUAGE OverloadedStrings #-}

module LLVM.Examples.Structs (structs) where

import qualified LLVM.General.AST as AST


import Control.Monad
import Control.Lens ((.=))
import LLVM.Gen
import LLVM.General.AST.Type (double)
import LLVM.General.AST.AddrSpace (AddrSpace(..))
import qualified LLVM.General.AST.Type as T 

{-
## Errors encountered 

- Invalid GetElementPtrInst indices for type
-}


structs :: AST.Module
structs = mapLLVM . runLLVM defaultModule $ do

  moduleName .= "Structs"

  let pointT = T.StructureType True [T.i32, T.i32]
  let pointTPtr = T.PointerType pointT (AddrSpace 0) 
 
  -- | Creates a stuct of type `{ i32, i32 }` and stores `54` 
  -- in the first indice and stores `34` in the second indice
  defn double "main" [] $ do
    myPoint <- alloca pointT 8 
    x <- getElemPtr' pointTPtr myPoint [i32 0, i32 0]  
    y <- getElemPtr' pointTPtr myPoint [i32 0, i32 1]  
    store T.i32 4 (i32 54) x
    store T.i32 4 (i32 34) y
    ret (i32 0)


