<commit_before>{-# LANGUAGE PatternSynonyms #-}
module Fun.Go.Printer
    ( printPretty
    , print
) where

import ClassyPrelude                hiding (print)
import Data.Either                  (partitionEithers)
import Data.SCargot.Repr.WellFormed (pattern A, pattern L, pattern Nil)
import Data.Text.Buildable          (Buildable)
import Data.Text.Format             (Format, format)
import Data.Text.Format.Params      (Params)

import Fun.Errors      (Error (..))
import Fun.Printer     (singleLine)
import Fun.SExpression (Atom (..), Expression, pattern ID, pattern KW, pattern OP, pattern SL,
                        pattern TP)
import Go.Fmt          (gofmt)


printPretty :: Expression -> Either Error Text
printPretty e = print e >>= gofmt

print :: Expression -> Either Error Text
-- empty
print Nil = Left . TranslationError $ "empty expression"

-- ident
print (ID x) = Right x

-- literal
print (SL x)      = Right $ printf1 "\"{}\"" x
print (A (Lit x)) = Right $ printf1 "{}" x

-- types
print (TP "any") = Right "interface{}"

print (TP x) = Right x

print (L [ TP "slice" , t@(TP _) ]) = printf1 "[]{}" <$> print t

print (L [ TP "map"   , k@(TP _) , v@(TP _) ])
    = printf2 "map[{}]{}" <$> print k <*> print v

-- const
print (L [ KW "const" , ID name , e ])
    = printf2 "const {} = {}" name <$> print e

print (L [ KW "const" , ID name , TP t , e ])
    = printf3 "const {} {} = {}" name t <$> print e

-- var
print (L [ KW "var" , ID n , TP t ])
    = Right $ printf2 "var {} {}" n t

print (L [ KW "var" , ID n , ct@(L(TP _ : _)) ])
    = printf2 "var {} {}" n <$> print ct

print (L [ KW "var" , ID n , TP t , e ])
    = printf3 "var {} {} = {}" n t <$> print e

print (L [ KW "var" , ID n , ts , L xs ])
    = printf3 "var {} = {}{{}}" n <$> print ts <*> printList xs

print (L [ KW "var" , ID n , e ]) = printf2 "var {} = {}" n <$> print e

-- FIXME: literal pair (used in maps)
print (L [ lit@(A (Lit _)) , ex ]) = printf2 "{}: {}" <$> print lit <*> print ex

-- package
print (L ( KW "package" : ID name : topLevels )) = case partitionEithers (print <$> topLevels) of
    (err : _ , _) -> Left err
    ([] , txts)   -> Right $ printf2 "package {}\n\n{}" name (ointercalate "\n\n" txts)

-- import
print (L [ KW "import" , SL path ])
    = Right $ printf1 "import \"{}\"" path

print (L [ KW "import" , SL path , SL alias ])
    = Right $ printf2 "import {} \"{}\"" alias path

-- func
print (L [ KW "func" , ID n , body ])
    = printf2 "func {}() {\n{}\n}" n <$> print body

print (L [ KW "func" , ID n , L args, body ])
    = printf3 "func {}({}) {\n{}\n}" n <$> printList args <*> print body

print (L [ KW "func" , ID n , L args, TP t, body ])
    = printf4 "func {}({}) {} {\n{}\n}" n <$> printList args <*> print (TP t) <*> print body

print (L [ KW "func" , ID n , L args, L results, body ])
    = printf4 "func {}({}) ({}) {\n{}\n}" n <$> printList args <*> printList results <*> print body

-- assignment
print (L [ KW "set" , ID name , body ])
    = printf2 "{} = {}" name <$> print body

print (L [ KW "set" , tar@(L ( KW "val" : _ )) , body ])
    = printf2 "{} = {}" <$> print tar <*> print body

-- indexed access
print (L [ KW "val" , ID name , idx ]) = printf2 "{}[{}]" name <$> print idx

-- function call
print (L ( ID f : args )) = printf2 "{}({})" f <$> printList args

-- unary operators
print (L [ OP op , x ]) = printf2 "{}{}" op <$> print x

-- binary operators
print (L [ OP "=" , lhs , rhs ]) = printf2 "{} == {}" <$> print lhs <*> print rhs

print (L (OP op : xs )) = intercalate (" " <> op <> " ") <$> mapM print xs

-- expression list, recursive
print (L [ L h ] ) = print (L h)
print (L ( L h : rest )) = printf2 "{}\n{}" <$> print (L h) <*> print (L rest)

-- FIXME: catch-all case
print s = Left . TranslationError $ "not supported yet " <> singleLine s



-- Utils --
<commit_msg>`_, x =` notation<commit_after>{-# LANGUAGE PatternSynonyms #-}
module Fun.Go.Printer
    ( printPretty
    , print
) where

import ClassyPrelude                hiding (print)
import Data.Either                  (partitionEithers)
import Data.SCargot.Repr.WellFormed (pattern A, pattern L, pattern Nil)
import Data.Text.Buildable          (Buildable)
import Data.Text.Format             (Format, format)
import Data.Text.Format.Params      (Params)

import Fun.Errors      (Error (..))
import Fun.Printer     (singleLine)
import Fun.SExpression (Atom (..), Expression, pattern ID, pattern KW, pattern OP, pattern SL,
                        pattern TP)
import Go.Fmt          (gofmt)


printPretty :: Expression -> Either Error Text
printPretty e = print e >>= gofmt

print :: Expression -> Either Error Text
-- empty
print Nil = Left . TranslationError $ "empty expression"

-- ident
print (ID x) = Right x

-- literal
print (SL x)      = Right $ printf1 "\"{}\"" x
print (A (Lit x)) = Right $ printf1 "{}" x

-- types
print (TP "any") = Right "interface{}"

print (TP x) = Right x

print (L [ TP "slice" , t@(TP _) ]) = printf1 "[]{}" <$> print t

print (L [ TP "map"   , k@(TP _) , v@(TP _) ])
    = printf2 "map[{}]{}" <$> print k <*> print v

-- const
print (L [ KW "const" , ID name , e ])
    = printf2 "const {} = {}" name <$> print e

print (L [ KW "const" , ID name , TP t , e ])
    = printf3 "const {} {} = {}" name t <$> print e

-- var
print (L [ KW "var" , ID n , TP t ])
    = Right $ printf2 "var {} {}" n t

print (L [ KW "var" , ID "_" , ID n , acc@(L ( KW "val" : _)) ])
    = printf2 "var _, {} = {}" n <$> print acc

print (L [ KW "var" , ID n , ct@(L(TP _ : _)) ])
    = printf2 "var {} {}" n <$> print ct

print (L [ KW "var" , ID n , TP t , e ])
    = printf3 "var {} {} = {}" n t <$> print e

print (L [ KW "var" , ID n , ts , L xs ])
    = printf3 "var {} = {}{{}}" n <$> print ts <*> printList xs

print (L [ KW "var" , ID n , e ]) = printf2 "var {} = {}" n <$> print e

-- FIXME: literal pair (used in maps)
print (L [ lit@(A (Lit _)) , ex ]) = printf2 "{}: {}" <$> print lit <*> print ex

-- package
print (L ( KW "package" : ID name : topLevels )) = case partitionEithers (print <$> topLevels) of
    (err : _ , _) -> Left err
    ([] , txts)   -> Right $ printf2 "package {}\n\n{}" name (ointercalate "\n\n" txts)

-- import
print (L [ KW "import" , SL path ])
    = Right $ printf1 "import \"{}\"" path

print (L [ KW "import" , SL path , SL alias ])
    = Right $ printf2 "import {} \"{}\"" alias path

-- func
print (L [ KW "func" , ID n , body ])
    = printf2 "func {}() {\n{}\n}" n <$> print body

print (L [ KW "func" , ID n , L args, body ])
    = printf3 "func {}({}) {\n{}\n}" n <$> printList args <*> print body

print (L [ KW "func" , ID n , L args, TP t, body ])
    = printf4 "func {}({}) {} {\n{}\n}" n <$> printList args <*> print (TP t) <*> print body

print (L [ KW "func" , ID n , L args, L results, body ])
    = printf4 "func {}({}) ({}) {\n{}\n}" n <$> printList args <*> printList results <*> print body

-- assignment
print (L [ KW "set" , ID name , xs ])
    = printf2 "{} = {}" name <$> print xs

print (L [ KW "set" , ID "_", ID name , xs ])
    = printf2 "_, {} = {}" name <$> print xs

print (L [ KW "set" , tar@(L ( KW "val" : _ )) , ex ])
    = printf2 "{} = {}" <$> print tar <*> print ex

-- indexed access
print (L [ KW "val" , ID name , idx ]) = printf2 "{}[{}]" name <$> print idx

-- function call
print (L ( ID f : args )) = printf2 "{}({})" f <$> printList args

-- unary operators
print (L [ OP op , x ]) = printf2 "{}{}" op <$> print x

-- binary operators
print (L [ OP "=" , lhs , rhs ]) = printf2 "{} == {}" <$> print lhs <*> print rhs

print (L (OP op : xs )) = intercalate (" " <> op <> " ") <$> mapM print xs

-- expression list, recursive
print (L [ L h ] ) = print (L h)
print (L ( L h : rest )) = printf2 "{}\n{}" <$> print (L h) <*> print (L rest)

-- FIXME: catch-all case
print s = Left . TranslationError $ "not supported yet " <> singleLine s



-- Utils --

{'fraction_non_alphanumeric': 0.20408163265306123, 'fraction_numerical': 0.006844974014450501, 'mean_word_length': 2.5652959783099862, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 89, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1319166', 'n_tokens_mistral': 3010, 'n_tokens_neox': 2910, 'n_words': 995}