<commit_before>module Emit (toC,
             envToC,
             globalsToC,
             projectIncludesToC,
             envToDeclarations,
             checkForUnresolvedSymbols,
             ToCMode(..),
             wrapInInitFunction
            ) where

import Data.List (intercalate, sortOn)
import Control.Monad.State
import Control.Monad (when, zipWithM_)
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Maybe (fromMaybe)
import Debug.Trace

import Obj
import Types
import Util
import Template
import Scoring
import Lookup
import Concretize

addIndent :: Int -> String
addIndent n = replicate n ' '

indentAmount :: Int
indentAmount = 4

data ToCError = InvalidParameter XObj
              | InvalidList XObj
              | DontVisitObj Obj
              | CannotEmitUnit
              | CannotEmitExternal
              | CannotEmitModKeyword
              | BinderIsMissingType Binder
              | UnresolvedMultiSymbol XObj
              | UnresolvedInterfaceSymbol XObj
              | UnresolvedGenericType XObj
              | CannotSet XObj

instance Show ToCError where
  show (InvalidParameter xobj) = "Invalid parameter: " ++ show (obj xobj)
  show (InvalidList xobj) = "Invalid list: " ++ show (obj xobj)
  show (DontVisitObj o) = "Don't visit " ++ show o ++ " (internal compiler error)."
  show CannotEmitUnit = "Can't emit code for empty list: ()"
  show CannotEmitExternal = "Can't emit code for external function/variable."
  show CannotEmitModKeyword = "Can't emit code for Mod."
  show (BinderIsMissingType b) = "Binder is missing type: " ++ show b
  show (UnresolvedMultiSymbol xobj@(XObj (MultiSym symName symPaths) _ _)) =
    "Found ambiguous symbol '" ++ symName ++
    "' (alternatives are " ++ joinWithComma (map show symPaths) ++ ")" ++
    " at " ++ prettyInfoFromXObj xobj
  show (UnresolvedInterfaceSymbol xobj@(XObj (InterfaceSym symName) _ _)) =
    "Found unresolved use of interface '" ++ symName ++ "'" ++
    " at " ++ prettyInfoFromXObj xobj
  show (UnresolvedGenericType xobj@(XObj _ _ (Just t))) =
    "Found unresolved generic type '" ++ show t ++ "' at " ++ prettyInfoFromXObj xobj
  show (CannotSet xobj) = "Can't emit code for setting " ++ pretty xobj ++ " at " ++ prettyInfoFromXObj xobj

data ToCMode = Functions | Globals | All deriving Show

data EmitterState = EmitterState { emitterSrc :: String }

appendToSrc :: String -> State EmitterState ()
appendToSrc moreSrc = modify (\s -> s { emitterSrc = emitterSrc s ++ moreSrc })

toC :: ToCMode -> XObj -> String
toC toCMode root = emitterSrc (execState (visit startingIndent root) (EmitterState ""))
  where startingIndent = case toCMode of
                           Functions -> 0
                           Globals -> 4
                           All -> 0
        visit :: Int -> XObj -> State EmitterState String
        visit indent xobj =
          case obj xobj of
            Lst _   -> visitList indent xobj
            Arr _   -> visitArray indent xobj
            Num IntTy num -> return (show (round num :: Int))
            Num LongTy num -> return (show (round num :: Int) ++ "l")
            Num FloatTy num -> return (show num ++ "f")
            Num DoubleTy num -> return (show num)
            Num _ _ -> error "Can't emit invalid number type."
            Bol b -> return (if b then "true" else "false")
            Str _ -> visitString indent xobj
            Pattern _ -> visitString indent xobj
            Chr c -> return $ case c of
                                '\t' -> "'\\t'"
                                '\n' -> "'\\n'"
                                x -> ['\'', x, '\'']
            Sym _ _ -> visitSymbol indent xobj
            Defn -> error (show (DontVisitObj Defn))
            Def -> error (show (DontVisitObj Def))
            Let -> error (show (DontVisitObj Let))
            If -> error (show (DontVisitObj If))
            Break -> error (show (DontVisitObj Break))
            While -> error (show (DontVisitObj While))
            Do -> error (show (DontVisitObj Do))
            e@(Typ _) -> error (show (DontVisitObj e))
            Mod _ -> error (show CannotEmitModKeyword)
            External _ -> error (show CannotEmitExternal)
            ExternalType -> error (show (DontVisitObj ExternalType))
            e@(Command _) -> error (show (DontVisitObj e))
            e@(Deftemplate _) ->  error (show (DontVisitObj e))
            e@(Instantiate _) ->  error (show (DontVisitObj e))
            e@(Defalias _) -> error (show (DontVisitObj e))
            e@(MultiSym _ _) -> error (show (DontVisitObj e))
            e@(InterfaceSym _) -> error (show (DontVisitObj e))
            Address -> error (show (DontVisitObj Address))
            SetBang -> error (show (DontVisitObj SetBang))
            Macro -> error (show (DontVisitObj Macro))
            Dynamic -> error (show (DontVisitObj Dynamic))
            The -> error (show (DontVisitObj The))<commit_msg>emit: fix emitting slash character<commit_after>module Emit (toC,
             envToC,
             globalsToC,
             projectIncludesToC,
             envToDeclarations,
             checkForUnresolvedSymbols,
             ToCMode(..),
             wrapInInitFunction
            ) where

import Data.List (intercalate, sortOn)
import Control.Monad.State
import Control.Monad (when, zipWithM_)
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Maybe (fromMaybe)
import Debug.Trace

import Obj
import Types
import Util
import Template
import Scoring
import Lookup
import Concretize

addIndent :: Int -> String
addIndent n = replicate n ' '

indentAmount :: Int
indentAmount = 4

data ToCError = InvalidParameter XObj
              | InvalidList XObj
              | DontVisitObj Obj
              | CannotEmitUnit
              | CannotEmitExternal
              | CannotEmitModKeyword
              | BinderIsMissingType Binder
              | UnresolvedMultiSymbol XObj
              | UnresolvedInterfaceSymbol XObj
              | UnresolvedGenericType XObj
              | CannotSet XObj

instance Show ToCError where
  show (InvalidParameter xobj) = "Invalid parameter: " ++ show (obj xobj)
  show (InvalidList xobj) = "Invalid list: " ++ show (obj xobj)
  show (DontVisitObj o) = "Don't visit " ++ show o ++ " (internal compiler error)."
  show CannotEmitUnit = "Can't emit code for empty list: ()"
  show CannotEmitExternal = "Can't emit code for external function/variable."
  show CannotEmitModKeyword = "Can't emit code for Mod."
  show (BinderIsMissingType b) = "Binder is missing type: " ++ show b
  show (UnresolvedMultiSymbol xobj@(XObj (MultiSym symName symPaths) _ _)) =
    "Found ambiguous symbol '" ++ symName ++
    "' (alternatives are " ++ joinWithComma (map show symPaths) ++ ")" ++
    " at " ++ prettyInfoFromXObj xobj
  show (UnresolvedInterfaceSymbol xobj@(XObj (InterfaceSym symName) _ _)) =
    "Found unresolved use of interface '" ++ symName ++ "'" ++
    " at " ++ prettyInfoFromXObj xobj
  show (UnresolvedGenericType xobj@(XObj _ _ (Just t))) =
    "Found unresolved generic type '" ++ show t ++ "' at " ++ prettyInfoFromXObj xobj
  show (CannotSet xobj) = "Can't emit code for setting " ++ pretty xobj ++ " at " ++ prettyInfoFromXObj xobj

data ToCMode = Functions | Globals | All deriving Show

data EmitterState = EmitterState { emitterSrc :: String }

appendToSrc :: String -> State EmitterState ()
appendToSrc moreSrc = modify (\s -> s { emitterSrc = emitterSrc s ++ moreSrc })

toC :: ToCMode -> XObj -> String
toC toCMode root = emitterSrc (execState (visit startingIndent root) (EmitterState ""))
  where startingIndent = case toCMode of
                           Functions -> 0
                           Globals -> 4
                           All -> 0
        visit :: Int -> XObj -> State EmitterState String
        visit indent xobj =
          case obj xobj of
            Lst _   -> visitList indent xobj
            Arr _   -> visitArray indent xobj
            Num IntTy num -> return (show (round num :: Int))
            Num LongTy num -> return (show (round num :: Int) ++ "l")
            Num FloatTy num -> return (show num ++ "f")
            Num DoubleTy num -> return (show num)
            Num _ _ -> error "Can't emit invalid number type."
            Bol b -> return (if b then "true" else "false")
            Str _ -> visitString indent xobj
            Pattern _ -> visitString indent xobj
            Chr c -> return $ case c of
                                '\t' -> "'\\t'"
                                '\n' -> "'\\n'"
                                '\\' -> "'\\\\'"
                                x -> ['\'', x, '\'']
            Sym _ _ -> visitSymbol indent xobj
            Defn -> error (show (DontVisitObj Defn))
            Def -> error (show (DontVisitObj Def))
            Let -> error (show (DontVisitObj Let))
            If -> error (show (DontVisitObj If))
            Break -> error (show (DontVisitObj Break))
            While -> error (show (DontVisitObj While))
            Do -> error (show (DontVisitObj Do))
            e@(Typ _) -> error (show (DontVisitObj e))
            Mod _ -> error (show CannotEmitModKeyword)
            External _ -> error (show CannotEmitExternal)
            ExternalType -> error (show (DontVisitObj ExternalType))
            e@(Command _) -> error (show (DontVisitObj e))
            e@(Deftemplate _) ->  error (show (DontVisitObj e))
            e@(Instantiate _) ->  error (show (DontVisitObj e))
            e@(Defalias _) -> error (show (DontVisitObj e))
            e@(MultiSym _ _) -> error (show (DontVisitObj e))
            e@(InterfaceSym _) -> error (show (DontVisitObj e))
            Address -> error (show (DontVisitObj Address))
            SetBang -> error (show (DontVisitObj SetBang))
            Macro -> error (show (DontVisitObj Macro))
            Dynamic -> error (show (DontVisitObj Dynamic))
            The -> error (show (DontVisitObj The))
{'fraction_non_alphanumeric': 0.10236141685011006, 'fraction_numerical': 0.0008004802881729037, 'mean_word_length': 2.059381695745332, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 98, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6044224', 'n_tokens_mistral': 2874, 'n_tokens_neox': 2765, 'n_words': 907}