<commit_before>
module Kt2Dart where

import Control.Applicative
import Control.Monad

import OperatorP
import Parsers

kotlinJumps :: Parser String
kotlinJumps = continue' <|> throw' <|> break' <|> return'
  where label = option0 "" $ do
          charP '@'
          some $ oneOf alpha
          return ""
        f s = do
          stringP s
          label
          spaces0P
          return s

        continue' = f "continue"
        break' = f "break"
        throw' = do
          stringP "throw"
          spacesP
          e <- kotlinExpr
          return $ "throw " ++ e
        return' = do
          stringP "return"
          label
          spacesP
          e <- kotlinExpr
          return $ "return " ++ e
--

kotlinVarVal :: Parser String
kotlinVarVal = do
  reservedP "val" <|> reservedP "var"
  n <- allNameP
  v <- return "var" <~> do
    reservedP ":"
    allNameP
  i <- return [] <~> do
    reservedP "="
    e <- kotlinCallExpr <|> kotlinExpr
    return $ '=' : e
  return $ v ++ " " ++ n ++ i
--

kotlinStatement :: Parser String
kotlinStatement = do
  s <- kotlinJumps <|> kotlinVarVal <|> kotlinCallExpr <|> kotlinExpr <|> kotlinUnary
  option0 "" $ reservedP ";"
  return $ s ++ ";"
--

kotlinCallExpr :: Parser String
kotlinCallExpr = do
  n <- kotlinExpr
  e <- return "#" <~> do
    reservedP "("
    e <- option0 [] $ seperateP kotlinExpr ","
    reservedP ")"
    return $ join e
  l <- option0 "" kotlinLambda
  return $ g n ++ f e l
  where f "#"         [     ]  = []
        f "#"       b          = "(" ++ b ++ ")"
        f a@(_ : _) b@(_ : _)  = "(" ++ a ++ "," ++ b ++ ")"
        f a         b          = "(" ++ a ++ b ++ ")"
        g s@(h : _) |elem h l  = "new " ++ s
                    |otherwise = s
          where l = ['A' .. 'Z']
--

kotlinExpr :: Parser String
kotlinExpr = kotlinOps <|> kotlinLambda

kotlinLambda :: Parser String
kotlinLambda = do
  reservedP "{"
  pm <- option0 [] $ do
    p <- seperateP nameP ","
    reservedP "->"
    return p
  stmt <- many kotlinStatement
  reservedP "}"
  return $ "(" ++ join pm ++ "){" ++ join stmt ++ "}"
--

kotlinUnary :: Parser String
kotlinUnary = do
  op <- reservedP "++" <|> reservedP "--" <|> reservedP "!"
  e <- kotlinExpr
  return $ op ++ e
--

kotlinIncDec :: Parser String
kotlinIncDec = do
  e <- allNameP
  return e <~> do
    op <- reservedP "++" <|> reservedP "--"
    return $ e ++ op
--

-- | reference: https://kotlinlang.org/docs/reference/grammar.html
--   Kotlin operator precedence
kotlinOps :: Parser String
kotlinOps = flattenTree fa fb `liftM` parseOperators ops kotlinIncDec
  where
    fa "===" = "=="
    fa "!==" = "!="
    fa "?:"  = "??"
    fa "!!." = "."
    fa "::"  = "."
    fa other = other
    fb       = id

    ops = [ Na $ stringP <$>
            [ "=", "+=", "-=", "*=", "/=", "%=" ]    -- assignment
          , La $ stringP <$>
            [ "||" ]                                 -- disjunction
          , La $ stringP <$>
            [ "&&" ]                                 -- conjunction
          , La $ stringP <$>
            [ "===", "!==", "==", "!=" ]             -- equality
          , Na $ stringP <$>
            [ ">=", "<=", ">", "<"]                  -- comparison
          , Na $ stringP <$>
            [ "!in", "in", "is", "!is" ]             -- named checks
          , La $ stringP <$>
            [ "?:" ]                                 -- elvis
          , La
            [ do
                n <- nameP
                return $ if n == "in" || n == "is"
                  then n else '#' : n ]              -- infix function
          , Na $ stringP <$>
            [ ".." ]                                 -- range
          , La $ stringP <$>
            [ "+", "-" ]                             -- additive
          , La $ stringP <$>
            [ "*", "/", "%" ]                        -- multiplicative
          , Na $ stringP <$>
            [ ":", "as", "as?" ]                     -- type RHS
          , La $ stringP <$>
            [ ".", "?.", "!!.", "::" ]               -- member access
          ]
--

kotlin2Dart = parseCode kotlinStatement
<commit_msg>add-class-prototype<commit_after>
module Kt2Dart where

import Control.Applicative
import Control.Monad

import OperatorP
import Parsers

kotlinJumps :: Parser String
kotlinJumps = continue' <|> throw' <|> break' <|> return'
  where label = option0 "" $ do
          charP '@'
          some $ oneOf alpha
          return ""
        f s = do
          stringP s
          label
          spaces0P
          return s

        continue' = f "continue"
        break' = f "break"
        throw' = do
          stringP "throw"
          spacesP
          e <- kotlinExpr
          return $ "throw " ++ e
        return' = do
          stringP "return"
          label
          spacesP
          e <- kotlinExpr
          return $ "return " ++ e
--

kotlinVarVal :: Parser String
kotlinVarVal = do
  reservedP "val" <|> reservedP "var"
  n <- allNameP
  v <- return "var" <~> do
    reservedP ":"
    allNameP
  i <- return [] <~> do
    reservedP "="
    e <- kotlinCallExpr <|> kotlinExpr
    return $ '=' : e
  return $ v ++ " " ++ n ++ i
--

kotlinStatement :: Parser String
kotlinStatement = do
  s <- kotlinJumps <|> kotlinVarVal <|> kotlinCallExpr <|> kotlinExpr <|> kotlinUnary
  option0 "" $ reservedP ";"
  return $ s ++ ";"
--

kotlinCallExpr :: Parser String
kotlinCallExpr = do
  n <- kotlinExpr
  e <- return "#" <~> do
    reservedP "("
    e <- option0 [] $ seperateP kotlinExpr ","
    reservedP ")"
    return $ join e
  l <- option0 "" kotlinLambda
  return $ g n ++ f e l
  where f "#"         [     ]  = []
        f "#"       b          = "(" ++ b ++ ")"
        f a@(_ : _) b@(_ : _)  = "(" ++ a ++ "," ++ b ++ ")"
        f a         b          = "(" ++ a ++ b ++ ")"
        g s@(h : _) |elem h l  = "new " ++ s
                    |otherwise = s
          where l = ['A' .. 'Z']
--

kotlinExpr :: Parser String
kotlinExpr = kotlinOps <|> kotlinLambda

kotlinLambda :: Parser String
kotlinLambda = do
  reservedP "{"
  pm <- option0 [] $ do
    p <- seperateP nameP ","
    reservedP "->"
    return p
  stmt <- many kotlinStatement
  reservedP "}"
  return $ "(" ++ join pm ++ "){" ++ join stmt ++ "}"
--

kotlinUnary :: Parser String
kotlinUnary = do
  op <- reservedP "++" <|> reservedP "--" <|> reservedP "!"
  e <- kotlinExpr
  return $ op ++ e
--

kotlinIncDec :: Parser String
kotlinIncDec = do
  e <- allNameP
  return e <~> do
    op <- reservedP "++" <|> reservedP "--"
    return $ e ++ op
--

-- | reference: https://kotlinlang.org/docs/reference/grammar.html
--   Kotlin operator precedence
kotlinOps :: Parser String
kotlinOps = flattenTree fa fb `liftM` parseOperators ops kotlinIncDec
  where
    fa "===" = "=="
    fa "!==" = "!="
    fa "?:"  = "??"
    fa "!!." = "."
    fa "::"  = "."
    fa other = other
    fb       = id

    ops = [ Na $ stringP <$>
            [ "=", "+=", "-=", "*=", "/=", "%=" ]    -- assignment
          , La $ stringP <$>
            [ "||" ]                                 -- disjunction
          , La $ stringP <$>
            [ "&&" ]                                 -- conjunction
          , La $ stringP <$>
            [ "===", "!==", "==", "!=" ]             -- equality
          , Na $ stringP <$>
            [ ">=", "<=", ">", "<"]                  -- comparison
          , Na $ stringP <$>
            [ "!in", "in", "is", "!is" ]             -- named checks
          , La $ stringP <$>
            [ "?:" ]                                 -- elvis
          , La
            [ do
                n <- nameP
                return $ if n == "in" || n == "is"
                  then n else '#' : n ]              -- infix function
          , Na $ stringP <$>
            [ ".." ]                                 -- range
          , La $ stringP <$>
            [ "+", "-" ]                             -- additive
          , La $ stringP <$>
            [ "*", "/", "%" ]                        -- multiplicative
          , Na $ stringP <$>
            [ ":", "as", "as?" ]                     -- type RHS
          , La $ stringP <$>
            [ ".", "?.", "!!.", "::" ]               -- member access
          ]
--

kotlinClass :: Parser String
kotlinClass = do
  m <- many $ reservedP "abstract "
    <|> reservedP "private "
    <|> reservedP "data "
    <|> reservedP "public "
    <|> reservedP "sealed "
  reservedP "class"
  n <- nameP
  reservedP "{"
  -- TODO
  reservedP "}"
  return $ join [ e | e <- m, e `elem` [ "private ", "abstract " ] ] ++
    "class " ++ n ++ "{" ++ "" ++ "}"
--

kotlin2Dart = parseCode kotlinStatement

{'fraction_non_alphanumeric': 0.17461414420640406, 'fraction_numerical': 0.0018428933425478, 'mean_word_length': 1.3531165311653117, 'pattern_counts': {'":': 8, '<': 110, '<?xml version=': 0, '>': 71, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5118590', 'n_tokens_mistral': 2957, 'n_tokens_neox': 2787, 'n_words': 671}