<commit_before>{-# LANGUAGE LambdaCase #-}

module ArrayTemplates where

import Debug.Trace

import Util
import Types
import Obj
import Parsing
import Template
import Polymorphism
import Concretize
import Lookup

-- | "Endofunctor Map"
templateEMap :: (String, Binder)
templateEMap =
  let fTy = FuncTy [VarTy "a"] (VarTy "a")
      aTy = StructTy "Array" [VarTy "a"]
      bTy = StructTy "Array" [VarTy "a"]
  in  defineTemplate
      (SymPath ["Array"] "endo-map")
      (FuncTy [fTy, aTy] bTy)
      (toTemplate "Array $NAME($(Fn [a] a) f, Array a)")
      (toTemplate $ unlines
        ["$DECL { "
        ,"    for(int i = 0; i < a.len; ++i) {"
        ,"        (($a*)a.data)[i] = f((($a*)a.data)[i]); "
        ,"    }"
        ,"    return a;"
        ,"}"
        ])
      (\(FuncTy [t, arrayType] _) ->
         [defineFunctionTypeAlias t])

templateFilter :: (String, Binder)
templateFilter = defineTypeParameterizedTemplate templateCreator path t
  where
    fTy = FuncTy [RefTy (VarTy "a")] BoolTy
    aTy = StructTy "Array" [VarTy "a"]
    path = SymPath ["Array"] "filter"
    t = FuncTy [fTy, aTy] aTy
    templateCreator = TemplateCreator $
      \typeEnv env ->
        Template
        t
        (const (toTemplate "Array $NAME($(Fn [(Ref a)] Bool) predicate, Array a)"))
        (\(FuncTy [FuncTy [RefTy insideTy] BoolTy, _] _) ->
           (toTemplate $ unlines $
            let deleter = insideArrayDeletion typeEnv env insideTy
            in ["$DECL { "
               , "    int insertIndex = 0;"
               , "    for(int i = 0; i < a.len; ++i) {"
               , "        if(predicate(&((($a*)a.data)[i]))) {"
               , "            ((($a*)a.data)[insertIndex++]) = (($a*)a.data)[i];"
               , "        } else {"
               , "        " ++ deleter "i"
               , "        }"
               , "    }"
               , "    a.len = insertIndex;"
               , "    // NOTE: the array isn't resized for now, it probably should be?"
               , "    return a;"
               , "}"
               ]))
        (\(FuncTy [ft@(FuncTy [RefTy insideType] BoolTy), arrayType] _) ->
           [defineFunctionTypeAlias ft] ++
            depsForDeleteFunc typeEnv env insideType)

templatePushBack :: (String, Binder)
templatePushBack =
  let aTy = StructTy "Array" [VarTy "a"]
      valTy = VarTy "a"
  in  defineTemplate
      (SymPath ["Array"] "push-back")
      (FuncTy [aTy, valTy] aTy)
      (toTemplate "Array $NAME(Array a, $a value)")
      (toTemplate $ unlines
        ["$DECL { "
        ,"    a.len++;"
        ,"    if(a.len > a.capacity) {"
        ,"        a.capacity = a.len * 2;"
        ,"        a.data = realloc(a.data, sizeof($a) * a.capacity);"
        -- ,"        void *pre = a.data;"
        -- ,"        a.data = CARP_MALLOC(sizeof($a) * a.capacity);"
        -- ,"        unsigned long s = sizeof($a) * (a.len - 1);"
        -- ,"        memmove(a.data, pre, s);"
        -- ,"        CARP_FREE(pre);"
        ,"    }"
        ,"    (($a*)a.data)[a.len - 1] = value;"
        ,"    return a;"
        ,"}"
        ])
      (\(FuncTy [arrayType, _] _) -> [])

templatePopBack :: (String, Binder)
templatePopBack = defineTypeParameterizedTemplate templateCreator path t
  where path = SymPath ["Array"] "pop-back"
        aTy = StructTy "Array" [VarTy "a"]
        t = FuncTy [aTy] aTy
        templateCreator = TemplateCreator $
          \typeEnv env ->
            Template
            t
            (const (toTemplate "Array $NAME(Array a)"))
            (\(FuncTy [arrayType@(StructTy _ [insideTy])] _) ->
               let deleteElement = insideArrayDeletion typeEnv env insideTy
               in toTemplate (unlines
                               ["$DECL { "
                               ,"  a.len--;"
                               ,"  " ++ deleteElement "a.len"
                               -- ,"  a.data = realloc(a.data, sizeof($a) * a.len);"
                               -- ,"  void *pre = a.data;"
                               -- ,"  unsigned long s = sizeof($a) * a.len;"
                               -- ,"  a.data = CARP_MALLOC(s);"
                               -- ,"  memcpy(a.data, pre, s);"
                               -- ,"  CARP_FREE(pre);"
                               ,"  return a;"
                               ,"}"
                               ]))
            (\(FuncTy [arrayType@(StructTy _ [insideTy])] _) ->
               depsForDeleteFunc typeEnv env arrayType ++
               depsForCopyFunc typeEnv env insideTy
            )

templateNth :: (String, Binder)
templateNth =
  let t = VarTy "t"
  in defineTemplate
  (SymPath ["Array"] "nth")
  (FuncTy [RefTy (StructTy "Array" [t]), IntTy] (RefTy t))
  (toTemplate "$t* $NAME (Array *aRef, int n)")
  (toTemplate $ unlines ["$DECL {"
                        ,"    Array a = *aRef;"
                        ,"    #ifndef OPTIMIZE"
                        ,"    assert(n >= 0);"
                        ,"    assert(n < a.len);"
                        ,"    #endif"
                        ,"    return &((($t*)a.data)[n]);"
                        ,"}"])
  (\(FuncTy [(RefTy arrayType), _] _) -><commit_msg>Array will shrink when it's a fourth of its capacity.<commit_after>{-# LANGUAGE LambdaCase #-}

module ArrayTemplates where

import Debug.Trace

import Util
import Types
import Obj
import Parsing
import Template
import Polymorphism
import Concretize
import Lookup

-- | "Endofunctor Map"
templateEMap :: (String, Binder)
templateEMap =
  let fTy = FuncTy [VarTy "a"] (VarTy "a")
      aTy = StructTy "Array" [VarTy "a"]
      bTy = StructTy "Array" [VarTy "a"]
  in  defineTemplate
      (SymPath ["Array"] "endo-map")
      (FuncTy [fTy, aTy] bTy)
      (toTemplate "Array $NAME($(Fn [a] a) f, Array a)")
      (toTemplate $ unlines
        ["$DECL { "
        ,"    for(int i = 0; i < a.len; ++i) {"
        ,"        (($a*)a.data)[i] = f((($a*)a.data)[i]); "
        ,"    }"
        ,"    return a;"
        ,"}"
        ])
      (\(FuncTy [t, arrayType] _) ->
         [defineFunctionTypeAlias t])

templateFilter :: (String, Binder)
templateFilter = defineTypeParameterizedTemplate templateCreator path t
  where
    fTy = FuncTy [RefTy (VarTy "a")] BoolTy
    aTy = StructTy "Array" [VarTy "a"]
    path = SymPath ["Array"] "filter"
    t = FuncTy [fTy, aTy] aTy
    templateCreator = TemplateCreator $
      \typeEnv env ->
        Template
        t
        (const (toTemplate "Array $NAME($(Fn [(Ref a)] Bool) predicate, Array a)"))
        (\(FuncTy [FuncTy [RefTy insideTy] BoolTy, _] _) ->
           (toTemplate $ unlines $
            let deleter = insideArrayDeletion typeEnv env insideTy
            in ["$DECL { "
               , "    int insertIndex = 0;"
               , "    for(int i = 0; i < a.len; ++i) {"
               , "        if(predicate(&((($a*)a.data)[i]))) {"
               , "            ((($a*)a.data)[insertIndex++]) = (($a*)a.data)[i];"
               , "        } else {"
               , "        " ++ deleter "i"
               , "        }"
               , "    }"
               , "    a.len = insertIndex;"
               , "    // NOTE: the array isn't resized for now, it probably should be?"
               , "    return a;"
               , "}"
               ]))
        (\(FuncTy [ft@(FuncTy [RefTy insideType] BoolTy), arrayType] _) ->
           [defineFunctionTypeAlias ft] ++
            depsForDeleteFunc typeEnv env insideType)

templatePushBack :: (String, Binder)
templatePushBack =
  let aTy = StructTy "Array" [VarTy "a"]
      valTy = VarTy "a"
  in  defineTemplate
      (SymPath ["Array"] "push-back")
      (FuncTy [aTy, valTy] aTy)
      (toTemplate "Array $NAME(Array a, $a value)")
      (toTemplate $ unlines
        ["$DECL { "
        ,"    a.len++;"
        ,"    if(a.len > a.capacity) {"
        ,"        a.capacity = a.len * 2;"
        ,"        a.data = realloc(a.data, sizeof($a) * a.capacity);"
        -- ,"        void *pre = a.data;"
        -- ,"        a.data = CARP_MALLOC(sizeof($a) * a.capacity);"
        -- ,"        unsigned long s = sizeof($a) * (a.len - 1);"
        -- ,"        memmove(a.data, pre, s);"
        -- ,"        CARP_FREE(pre);"
        ,"    }"
        ,"    (($a*)a.data)[a.len - 1] = value;"
        ,"    return a;"
        ,"}"
        ])
      (\(FuncTy [arrayType, _] _) -> [])

templatePopBack :: (String, Binder)
templatePopBack = defineTypeParameterizedTemplate templateCreator path t
  where path = SymPath ["Array"] "pop-back"
        aTy = StructTy "Array" [VarTy "a"]
        t = FuncTy [aTy] aTy
        templateCreator = TemplateCreator $
          \typeEnv env ->
            Template
            t
            (const (toTemplate "Array $NAME(Array a)"))
            (\(FuncTy [arrayType@(StructTy _ [insideTy])] _) ->
               let deleteElement = insideArrayDeletion typeEnv env insideTy
               in toTemplate (unlines
                               ["$DECL { "
                               ,"  a.len--;"
                               ,"  " ++ deleteElement "a.len"
                               ,"    if(a.len < (a.capacity / 4)) {"
                               ,"        void *pre = a.data;"
                               ,"        unsigned long s = sizeof($a) * a.len;"
                               ,"        a.data = CARP_MALLOC(s);"
                               ,"        memcpy(a.data, pre, s);"
                               ,"        CARP_FREE(pre);"
                               ,"        a.capacity = a.len;"
                               ,"    }"
                               ,"  return a;"
                               ,"}"
                               ]))
            (\(FuncTy [arrayType@(StructTy _ [insideTy])] _) ->
               depsForDeleteFunc typeEnv env arrayType ++
               depsForCopyFunc typeEnv env insideTy
            )

templateNth :: (String, Binder)
templateNth =
  let t = VarTy "t"
  in defineTemplate
  (SymPath ["Array"] "nth")
  (FuncTy [RefTy (StructTy "Array" [t]), IntTy] (RefTy t))
  (toTemplate "$t* $NAME (Array *aRef, int n)")
  (toTemplate $ unlines ["$DECL {"
                        ,"    Array a = *aRef;"
                        ,"    #ifndef OPTIMIZE"
                        ,"    assert(n >= 0);"
                        ,"    assert(n < a.len);"
                        ,"    #endif"
                        ,"    return &((($t*)a.data)[n]);"
                        ,"}"])
  (\(FuncTy [(RefTy arrayType), _] _) ->
{'fraction_non_alphanumeric': 0.15320360702420502, 'fraction_numerical': 0.0014238253440911248, 'mean_word_length': 1.4027366020524514, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '76996', 'n_tokens_mistral': 3325, 'n_tokens_neox': 3204, 'n_words': 758}