<commit_before>module Component.App
  ( appClass
  , AppProps(..)
  ) where

import Prelude

import Data.Maybe
import Data.Either
import Data.Tuple
import Data.Array (uncons, cons, snoc, filter, singleton, reverse, null)
import Data.List (toList)
import Data.Foldable (intercalate)
import qualified Data.Map as Map
import qualified Data.Set as Set

import Data.Syntax
import Data.Expr
import Data.Parse
import Data.PrettyPrint

import Text.Parsing.Parser (ParseError(..))

import Control.Monad.Eff
import Control.Monad.Eff.Save

import qualified Thermite as T
import qualified Thermite.Action as T

import qualified React as R
import qualified React.DOM as RD
import qualified React.DOM.Props as RP

import Component.Event

data Level = Warning | Danger

instance showLevel :: Show Level where
  show Warning = "warning"
  show Danger  = "danger"

type AppState =
  { text    :: String
  , expr    :: Maybe Expr
  , history :: Array String
  , defs    :: Array Definition
  , env     :: Environment
  , error   :: Maybe (Tuple Level String)
  }

data AppAction
  = DoNothing
  | NewText String
  | ParseText
  | Reduce Expr
  | DismissAlert
  | Remove Name
  | Clear
  | Save

type AppProps = Unit

appClass :: R.ReactClass AppProps
appClass = T.createClass (T.simpleSpec initialState update render)

initialDefs :: Array Definition
initialDefs =
  [ { name: "i"
    , syntax: unsafeParse parseSyntax "λx. x"
    }
  , { name: "k"
    , syntax: unsafeParse parseSyntax "λx. λy. x"
    }
  , { name: "fix"
    , syntax: unsafeParse parseSyntax "λf. (λx. f (x x)) (λy. f (y y))"
    }
  ]

initialEnv :: Environment
initialEnv = Map.fromList (toList (map fromDef initialDefs))
 where
  fromDef def = Tuple def.name (syntaxToExpr def.syntax)

initialState :: AppState
initialState =
  { text: ""
  , expr: Nothing
  , history: []
  , defs: initialDefs
  , env: initialEnv
  , error: Nothing
  }

update :: T.PerformAction _ AppState _ AppAction
update props action =
  case action of
    DoNothing ->
      return unit
    NewText text ->
      T.modifyState (\s -> s { text = text, error = Nothing })
    DismissAlert ->
      T.modifyState (\s -> s { error = Nothing })
    Remove name ->
      T.modifyState (remove name)
    ParseText ->
      T.modifyState parse
    Reduce expr ->
      T.modifyState (reduce expr)
    Clear ->
      T.modifyState clear
    Save -> do
      s <- T.getState
      T.async \k -> do
        let text = intercalate "\n" (map defToString s.defs <> reverse s.history)
        saveTextAs text "evaluation.txt"
        k unit
     where
      defToString def = def.name <> " = " <> prettyPrint def.syntax

fail :: String -> AppState -> AppState
fail message s =
  s { text = "", error = Just (Tuple Danger message) }

parse :: AppState -> AppState
parse s
  | s.text == "" = s
parse s =
  case parseAll parseEither s.text of
    Left error   ->
      fail (formatParseError s.text error) s
    Right (Left def) ->
      addDef def s
    Right (Right syntax) ->
      addExpr syntax s

remove :: String -> AppState -> AppState
remove name s =
  s { defs = deleteByName name s.defs, env = env', error = error }
 where
  env' = Map.delete name s.env<commit_msg>making the input not disappear on parse failure<commit_after>module Component.App
  ( appClass
  , AppProps(..)
  ) where

import Prelude

import Data.Maybe
import Data.Either
import Data.Tuple
import Data.Array (uncons, cons, snoc, filter, singleton, reverse, null)
import Data.List (toList)
import Data.Foldable (intercalate)
import qualified Data.Map as Map
import qualified Data.Set as Set

import Data.Syntax
import Data.Expr
import Data.Parse
import Data.PrettyPrint

import Text.Parsing.Parser (ParseError(..))

import Control.Monad.Eff
import Control.Monad.Eff.Save

import qualified Thermite as T
import qualified Thermite.Action as T

import qualified React as R
import qualified React.DOM as RD
import qualified React.DOM.Props as RP

import Component.Event

data Level = Warning | Danger

instance showLevel :: Show Level where
  show Warning = "warning"
  show Danger  = "danger"

type AppState =
  { text    :: String
  , expr    :: Maybe Expr
  , history :: Array String
  , defs    :: Array Definition
  , env     :: Environment
  , error   :: Maybe (Tuple Level String)
  }

data AppAction
  = DoNothing
  | NewText String
  | ParseText
  | Reduce Expr
  | DismissAlert
  | Remove Name
  | Clear
  | Save

type AppProps = Unit

appClass :: R.ReactClass AppProps
appClass = T.createClass (T.simpleSpec initialState update render)

initialDefs :: Array Definition
initialDefs =
  [ { name: "i"
    , syntax: unsafeParse parseSyntax "λx. x"
    }
  , { name: "k"
    , syntax: unsafeParse parseSyntax "λx. λy. x"
    }
  , { name: "fix"
    , syntax: unsafeParse parseSyntax "λf. (λx. f (x x)) (λy. f (y y))"
    }
  ]

initialEnv :: Environment
initialEnv = Map.fromList (toList (map fromDef initialDefs))
 where
  fromDef def = Tuple def.name (syntaxToExpr def.syntax)

initialState :: AppState
initialState =
  { text: ""
  , expr: Nothing
  , history: []
  , defs: initialDefs
  , env: initialEnv
  , error: Nothing
  }

update :: T.PerformAction _ AppState _ AppAction
update props action =
  case action of
    DoNothing ->
      return unit
    NewText text ->
      T.modifyState (\s -> s { text = text, error = Nothing })
    DismissAlert ->
      T.modifyState (\s -> s { error = Nothing })
    Remove name ->
      T.modifyState (remove name)
    ParseText ->
      T.modifyState parse
    Reduce expr ->
      T.modifyState (reduce expr)
    Clear ->
      T.modifyState clear
    Save -> do
      s <- T.getState
      T.async \k -> do
        let text = intercalate "\n" (map defToString s.defs <> reverse s.history)
        saveTextAs text "evaluation.txt"
        k unit
     where
      defToString def = def.name <> " = " <> prettyPrint def.syntax

fail :: String -> AppState -> AppState
fail message s =
  s { error = Just (Tuple Danger message) }

parse :: AppState -> AppState
parse s
  | s.text == "" = s
parse s =
  case parseAll parseEither s.text of
    Left error   ->
      fail (formatParseError s.text error) s
    Right (Left def) ->
      addDef def s
    Right (Right syntax) ->
      addExpr syntax s

remove :: String -> AppState -> AppState
remove name s =
  s { defs = deleteByName name s.defs, env = env', error = error }
 where
  env' = Map.delete name s.env
{'fraction_non_alphanumeric': 0.10035954353603252, 'fraction_numerical': 0.0, 'mean_word_length': 2.806067816775729, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 47, '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': '4296089', 'n_tokens_mistral': 2057, 'n_tokens_neox': 2018, 'n_words': 685}