codeGenSimpleType :: SimpleType -> CG IR.Reg
codeGenSimpleType = \case
  T_Unit                -> newRegWithSimpleType (-1)
  T_Int64               -> newRegWithSimpleType (-2)
  T_Word64              -> newRegWithSimpleType (-3)
  T_Float               -> newRegWithSimpleType (-4)
  T_Bool                -> newRegWithSimpleType (-5)
  T_String              -> newRegWithSimpleType (-6)
  T_Char                -> newRegWithSimpleType (-7)
  T_UnspecifiedLocation -> newRegWithSimpleType (-8)
  T_Location locs -> do
    r <- newReg
    let locs' = map fromIntegral locs
    mapM_ (`extendSimpleType` r) locs'
    pure r
  t -> newReg
  where
  -- TODO: rename simple type to something more generic,
  newRegWithSimpleType :: IR.SimpleType -> CG IR.Reg
  newRegWithSimpleType irTy = newReg >>= extendSimpleType irTy

  -- TODO: rename simple type to something more generic,
  extendSimpleType :: IR.SimpleType -> IR.Reg -> CG IR.Reg
  extendSimpleType irTy r = do
    emit IR.Set
      { dstReg    = r
      , constant  = IR.CSimpleType irTy
      }
    pure r
codeGenSimpleType :: SimpleType -> CG IR.Reg
codeGenSimpleType = \case
  T_Unit                -> newRegWithSimpleType (-1)
  T_Int64               -> newRegWithSimpleType (-2)
  T_Word64              -> newRegWithSimpleType (-3)
  T_Float               -> newRegWithSimpleType (-4)
  T_Bool                -> newRegWithSimpleType (-5)
  T_String              -> newRegWithSimpleType (-6)
  T_Char                -> newRegWithSimpleType (-7)
  T_UnspecifiedLocation -> newRegWithSimpleType (-8)
  T_Location locs -> do
    r <- newReg
    let locs' = map fromIntegral locs
    mapM_ (`extendSimpleType` r) locs'
    pure r
  t -> newReg
  where
  -- TODO: rename simple type to something more generic,
  newRegWithSimpleType :: IR.SimpleType -> CG IR.Reg
  newRegWithSimpleType irTy = newReg >>= extendSimpleType irTy

  -- TODO: rename simple type to something more generic,
  extendSimpleType :: IR.SimpleType -> IR.Reg -> CG IR.Reg
  extendSimpleType irTy r = do
    emit IR.Set
      { dstReg    = r
      , constant  = IR.CSimpleType irTy
      }
    pure r
codeGenSimpleType = \case
  T_Unit                -> newRegWithSimpleType (-1)
  T_Int64               -> newRegWithSimpleType (-2)
  T_Word64              -> newRegWithSimpleType (-3)
  T_Float               -> newRegWithSimpleType (-4)
  T_Bool                -> newRegWithSimpleType (-5)
  T_String              -> newRegWithSimpleType (-6)
  T_Char                -> newRegWithSimpleType (-7)
  T_UnspecifiedLocation -> newRegWithSimpleType (-8)
  T_Location locs -> do
    r <- newReg
    let locs' = map fromIntegral locs
    mapM_ (`extendSimpleType` r) locs'
    pure r
  t -> newReg
  where
  -- TODO: rename simple type to something more generic,
  newRegWithSimpleType :: IR.SimpleType -> CG IR.Reg
  newRegWithSimpleType irTy = newReg >>= extendSimpleType irTy

  -- TODO: rename simple type to something more generic,
  extendSimpleType :: IR.SimpleType -> IR.Reg -> CG IR.Reg
  extendSimpleType irTy r = do
    emit IR.Set
      { dstReg    = r
      , constant  = IR.CSimpleType irTy
      }
    pure r