{-# LANGUAGE CPP #-}

{-| Translate Agda names into a variety of GHC names
-}

module Agda.Compiler.Agate.TranslateName where

#include "../../undefined.h"
import Agda.Utils.Impossible

import Data.Char

----------------------------------------------------------------

translateNameAsUntypedTerm :: String -> String
translateNameAsUntypedTerm "_"                 = "_"
translateNameAsUntypedTerm s   | all isDigit s = 'x':s
translateNameAsUntypedTerm s                   = 'x':'_':escape s

translateNameAsUntypedConstructor :: String -> String
translateNameAsUntypedConstructor s = 'C':'_':escape s

translateNameAsOptimizedType :: String -> String
translateNameAsOptimizedType "_" = "_"
translateNameAsOptimizedType s   = 'T':'_':escape s

translateNameAsOptimizedTerm :: String -> String
translateNameAsOptimizedTerm "_"                 = "_"
translateNameAsOptimizedTerm s   | all isDigit s = 'o':s
translateNameAsOptimizedTerm s                   = 'o':'_':escape s

translateNameAsOptimizedConstructor :: String -> String
translateNameAsOptimizedConstructor s = 'D':'_':escape s

----------------------------------------------------------------

escape :: String -> String
escape ""      = ""
escape "_"     = "_"
escape (c:s) | isUpper c || isLower c || isDigit c = c:escape s
escape ('.':s) = '_':'_':escape s
escape ('_':s) = '_':'z':escape s
escape (c:s) | ord c >= 256
	       = '_':'u'
                    :intToDigit (ord c `div` 4096)
                    :intToDigit ((ord c `div` 256) `mod` 16)
                    :intToDigit ((ord c `div` 16)  `mod` 16)
                    :intToDigit (ord c `mod` 16):escape s
escape (c:s)   = '_':intToDigit (ord c `div` 16)
                    :intToDigit (ord c `mod` 16):escape s

----------------------------------------------------------------