-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Types and utilities to compute code size
-- in terms of textual length and AST nodes.
module Swarm.Game.Scenario.Scoring.CodeSize where

import Control.Monad (guard)
import Data.Aeson
import GHC.Generics (Generic)
import Swarm.Language.Module
import Swarm.Language.Pipeline
import Swarm.Language.Syntax

data CodeSizeDeterminators = CodeSizeDeterminators
  { CodeSizeDeterminators -> Maybe ProcessedTerm
initialCode :: Maybe ProcessedTerm
  , CodeSizeDeterminators -> Bool
hasUsedREPL :: Bool
  }
  deriving (Int -> CodeSizeDeterminators -> ShowS
[CodeSizeDeterminators] -> ShowS
CodeSizeDeterminators -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CodeSizeDeterminators] -> ShowS
$cshowList :: [CodeSizeDeterminators] -> ShowS
show :: CodeSizeDeterminators -> String
$cshow :: CodeSizeDeterminators -> String
showsPrec :: Int -> CodeSizeDeterminators -> ShowS
$cshowsPrec :: Int -> CodeSizeDeterminators -> ShowS
Show)

data ScenarioCodeMetrics = ScenarioCodeMetrics
  { ScenarioCodeMetrics -> Int
sourceTextLength :: Int
  , ScenarioCodeMetrics -> Int
astSize :: Int
  }
  deriving (ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
$c/= :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
== :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
$c== :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
Eq, Eq ScenarioCodeMetrics
ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
ScenarioCodeMetrics -> ScenarioCodeMetrics -> Ordering
ScenarioCodeMetrics -> ScenarioCodeMetrics -> ScenarioCodeMetrics
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> ScenarioCodeMetrics
$cmin :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> ScenarioCodeMetrics
max :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> ScenarioCodeMetrics
$cmax :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> ScenarioCodeMetrics
>= :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
$c>= :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
> :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
$c> :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
<= :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
$c<= :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
< :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
$c< :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Bool
compare :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Ordering
$ccompare :: ScenarioCodeMetrics -> ScenarioCodeMetrics -> Ordering
Ord, Int -> ScenarioCodeMetrics -> ShowS
[ScenarioCodeMetrics] -> ShowS
ScenarioCodeMetrics -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ScenarioCodeMetrics] -> ShowS
$cshowList :: [ScenarioCodeMetrics] -> ShowS
show :: ScenarioCodeMetrics -> String
$cshow :: ScenarioCodeMetrics -> String
showsPrec :: Int -> ScenarioCodeMetrics -> ShowS
$cshowsPrec :: Int -> ScenarioCodeMetrics -> ShowS
Show, ReadPrec [ScenarioCodeMetrics]
ReadPrec ScenarioCodeMetrics
Int -> ReadS ScenarioCodeMetrics
ReadS [ScenarioCodeMetrics]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ScenarioCodeMetrics]
$creadListPrec :: ReadPrec [ScenarioCodeMetrics]
readPrec :: ReadPrec ScenarioCodeMetrics
$creadPrec :: ReadPrec ScenarioCodeMetrics
readList :: ReadS [ScenarioCodeMetrics]
$creadList :: ReadS [ScenarioCodeMetrics]
readsPrec :: Int -> ReadS ScenarioCodeMetrics
$creadsPrec :: Int -> ReadS ScenarioCodeMetrics
Read, forall x. Rep ScenarioCodeMetrics x -> ScenarioCodeMetrics
forall x. ScenarioCodeMetrics -> Rep ScenarioCodeMetrics x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ScenarioCodeMetrics x -> ScenarioCodeMetrics
$cfrom :: forall x. ScenarioCodeMetrics -> Rep ScenarioCodeMetrics x
Generic, [ScenarioCodeMetrics] -> Encoding
[ScenarioCodeMetrics] -> Value
ScenarioCodeMetrics -> Encoding
ScenarioCodeMetrics -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [ScenarioCodeMetrics] -> Encoding
$ctoEncodingList :: [ScenarioCodeMetrics] -> Encoding
toJSONList :: [ScenarioCodeMetrics] -> Value
$ctoJSONList :: [ScenarioCodeMetrics] -> Value
toEncoding :: ScenarioCodeMetrics -> Encoding
$ctoEncoding :: ScenarioCodeMetrics -> Encoding
toJSON :: ScenarioCodeMetrics -> Value
$ctoJSON :: ScenarioCodeMetrics -> Value
ToJSON, Value -> Parser [ScenarioCodeMetrics]
Value -> Parser ScenarioCodeMetrics
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [ScenarioCodeMetrics]
$cparseJSONList :: Value -> Parser [ScenarioCodeMetrics]
parseJSON :: Value -> Parser ScenarioCodeMetrics
$cparseJSON :: Value -> Parser ScenarioCodeMetrics
FromJSON)

codeSizeFromDeterminator :: CodeSizeDeterminators -> Maybe ScenarioCodeMetrics
codeSizeFromDeterminator :: CodeSizeDeterminators -> Maybe ScenarioCodeMetrics
codeSizeFromDeterminator (CodeSizeDeterminators Maybe ProcessedTerm
maybeInitialCode Bool
usedRepl) = do
  forall (f :: * -> *). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not Bool
usedRepl
  ProcessedTerm (Module s :: Syntax' Polytype
s@(Syntax' SrcLoc
srcLoc Term' Polytype
_ Polytype
_) Ctx Polytype
_) Requirements
_ ReqCtx
_ <- Maybe ProcessedTerm
maybeInitialCode
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Int -> Int -> ScenarioCodeMetrics
ScenarioCodeMetrics (SrcLoc -> Int
charCount SrcLoc
srcLoc) (forall a. Data a => Syntax' a -> Int
measureAstSize Syntax' Polytype
s)
 where
  charCount :: SrcLoc -> Int
  charCount :: SrcLoc -> Int
charCount SrcLoc
NoLoc = Int
0
  charCount (SrcLoc Int
start Int
end) = Int
end forall a. Num a => a -> a -> a
- Int
start