<commit_before>module BreveLang
    where
    -- (
    --   Expr (..)
    -- , Statement (..)
    -- , Trace
    -- , Traces
    -- , breveParser
    -- , pitchClasses
    -- , durations
    -- ) where
{-
Breve:
pitchclass ::= A | B ...
octave ::= digit { digit }*
note ::= ( pitchclass octave duration )
rest ::= ( "rest" duration )
snippet ::= '{' note {, rest }* '}'
var ::= letter { letter | digit }*
list = "[" expr[, expr]* "]"

expr ::= note | rest | list | snippet | expr duop expr
statement ::= var = expr | var = snippet | statement {; statement}*

lineComment ::= --
blockComment ::= {- ... -}

Example program:
snippet1 = {(d 4 qn), (fs 4 qn), (a 4 qn)};
snippet2 = {(d 4 wn)} :=: [(fs 4 wn)] :=: [(a 4 wn)]
main = snippet1 :+: {(r qn)} :+: snippet

Output:
(music) D major arpeggio in quarter notes, a beat of rest, D major chord
(score)
    (main) Treble cleff, with 3 quarter notes stacked: D F# A
    (snippet 1) Treble cleff, with 3...
-}
import qualified Euterpea.Music.Note.Music as E
import Data.List (intercalate)
import Text.Parsec
import Text.Parsec.Expr
import Text.Parsec.Language (emptyDef)
import Text.Parsec.Token

-- Poor man's map
type Loc = (Int, Int)
type Traces = [Expr]

type Parser = Parsec String Traces

data Expr = PitchClass E.PitchClass Loc
          | N Integer Loc | D Double Loc
          | B Bool
          | UnOpExpr UnOp Expr
          | BinOpExpr BinOp Expr Expr
          | Note Expr Expr Expr -- PitchClass, Octave, Duration
          | Rest Expr           -- Duration
          | Snippet [Expr]      -- Note | Rest
          | Var String
          | List [Expr]         -- Homogeneous
          deriving (Eq)

instance Show Expr where
    show (PitchClass e _) = show e
    show (N i _) = show i
    show (D d _) = show d
    show (B b) = show b
    show (UnOpExpr u e) = shows u (show e)
    show (BinOpExpr b@Div e1 e2) = concat [show e1, show b, show e2]
    show (BinOpExpr b e1 e2) = unwords [show e1, show b, show e2]
    show (Note p o d) = '(' : unwords [show p, show o, shows d ")"]
    show (Rest d) = "(rest " ++ shows d ")"
    show (Snippet ss) = '{' : intercalate ", " (map show ss) ++ "}"
    show (Var v) = v
    show (List ls) = '[' : intercalate ", " (map show ls) ++ "]"

data BinOp =
      SeqOp | ParOp                     -- snippets
    | Add | Mult | Div | Sub            -- math
    | Eq | Neq | Lt | Lte | Gt | Gte    -- equality
    deriving (Eq)
instance Show BinOp where
    show SeqOp = ":+:"
    show ParOp = ":=:"
    show Add = "+"
    show Mult = "*"
    show Div = "/"
    show Sub = "-"
    show Eq = "=="
    show Neq = "!="
    show Lt = "<"
    show Lte = "<="
    show Gt = ">"
    show Gte = ">="

data UnOp = Not deriving (Eq)
instance Show UnOp where
    show Not = "!"

data Statement = Assign String Expr | Seq [Statement] deriving (Eq)
instance Show Statement where
    show (Assign s e) = unwords [s, "=", shows e ";"]
    show (Seq ss) = unlines (map show ss)

pitchClasses = [n : m | n <- ['A'..'G'], m <- ["ff", "ss", "f", "s", ""]]
keywords = ["rest", "true", "false", "if", "else", "def"]

mathOps = ["+", "-", "/", "*"]
boolOps = ["==", "<", "<=", ">", ">="]
catOps = ["=", ":=:", ":+:"]

breveDef :: LanguageDef st
breveDef = emptyDef { commentStart = "{-"
                    , commentEnd = "-}"
                    , nestedComments = True
                    , commentLine = "--"
                    , identStart = lower <|> char '_'
                    , identLetter = alphaNum <|> char '_' <|> char '-'
                    , opStart = oneOf ":!#$%&*+./<=>?@\\^|-~"
                    , opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~"
                    , reservedNames = pitchClasses ++ keywords
                    , reservedOpNames = catOps ++ mathOps ++ boolOps
                    , caseSensitive = True
                    }

-- extract the parsers we need
TokenParser { identifier = b_identifier<commit_msg>Added Expr and Statement for lambda<commit_after>module BreveLang
    where
    -- (
    --   Expr (..)
    -- , Statement (..)
    -- , Trace
    -- , Traces
    -- , breveParser
    -- , pitchClasses
    -- , durations
    -- ) where
{-
Breve:
pitchclass ::= A | B ...
octave ::= digit { digit }*
note ::= ( pitchclass octave duration )
rest ::= ( "rest" duration )
snippet ::= '{' note {, rest }* '}'
var ::= letter { letter | digit }*
list = "[" expr[, expr]* "]"

expr ::= note | rest | list | snippet | expr duop expr
statement ::= var = expr | var = snippet | statement {; statement}*

lineComment ::= --
blockComment ::= {- ... -}

Example program:
snippet1 = {(d 4 qn), (fs 4 qn), (a 4 qn)};
snippet2 = {(d 4 wn)} :=: [(fs 4 wn)] :=: [(a 4 wn)]
main = snippet1 :+: {(r qn)} :+: snippet

Output:
(music) D major arpeggio in quarter notes, a beat of rest, D major chord
(score)
    (main) Treble cleff, with 3 quarter notes stacked: D F# A
    (snippet 1) Treble cleff, with 3...
-}
import qualified Euterpea.Music.Note.Music as E
import Data.List (intercalate)
import Text.Parsec
import Text.Parsec.Expr
import Text.Parsec.Language (emptyDef)
import Text.Parsec.Token

-- Poor man's map
type Loc = (Int, Int)
type Traces = [Expr]

type Parser = Parsec String Traces

data Expr = PitchClass E.PitchClass Loc
          | N Integer Loc | D Double Loc
          | B Bool
          | UnOpExpr UnOp Expr
          | BinOpExpr BinOp Expr Expr
          | Note Expr Expr Expr -- PitchClass, Octave, Duration
          | Rest Expr           -- Duration
          | Snippet [Expr]      -- Note | Rest
          | Var String
          | List [Expr]         -- Homogeneous
          | Lambda [String] Statement    -- Seq or Return, most likely
          deriving (Eq)

instance Show Expr where
    show (PitchClass e _) = show e
    show (N i _) = show i
    show (D d _) = show d
    show (B b) = show b
    show (UnOpExpr u e) = shows u (show e)
    show (BinOpExpr b@Div e1 e2) = concat [show e1, show b, show e2]
    show (BinOpExpr b e1 e2) = unwords [show e1, show b, show e2]
    show (Note p o d) = '(' : unwords [show p, show o, shows d ")"]
    show (Rest d) = "(rest " ++ shows d ")"
    show (Snippet ss) = '{' : intercalate ", " (map show ss) ++ "}"
    show (Var v) = v
    show (List ls) = '[' : intercalate ", " (map show ls) ++ "]"
    show (Lambda v s) = '(':'\\': unwords v ++ (shows s ")")

data BinOp =
      SeqOp | ParOp                     -- snippets
    | Add | Mult | Div | Sub            -- math
    | Eq | Neq | Lt | Lte | Gt | Gte    -- equality
    deriving (Eq)
instance Show BinOp where
    show SeqOp = ":+:"
    show ParOp = ":=:"
    show Add = "+"
    show Mult = "*"
    show Div = "/"
    show Sub = "-"
    show Eq = "=="
    show Neq = "!="
    show Lt = "<"
    show Lte = "<="
    show Gt = ">"
    show Gte = ">="

data UnOp = Not deriving (Eq)
instance Show UnOp where
    show Not = "!"

data Statement = Assign String Expr | Return Expr | Seq [Statement] deriving (Eq)
instance Show Statement where
    show (Assign s e) = unwords [s, "=", shows e ";"]
    show (Seq ss) = unlines (map show ss)
    show (Return e) = "return " ++ (shows e ";")

pitchClasses = [n : m | n <- ['A'..'G'], m <- ["ff", "ss", "f", "s", ""]]
keywords = ["rest", "true", "false", "if", "else", "def"]

mathOps = ["+", "-", "/", "*"]
boolOps = ["==", "<", "<=", ">", ">="]
catOps = ["=", ":=:", ":+:"]

breveDef :: LanguageDef st
breveDef = emptyDef { commentStart = "{-"
                    , commentEnd = "-}"
                    , nestedComments = True
                    , commentLine = "--"
                    , identStart = lower <|> char '_'
                    , identLetter = alphaNum <|> char '_' <|> char '-'
                    , opStart = oneOf ":!#$%&*+./<=>?@\\^|-~"
                    , opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~"
                    , reservedNames = pitchClasses ++ keywords
                    , reservedOpNames = catOps ++ mathOps ++ boolOps
                    , caseSensitive = True
                    }

-- extract the parsers we need
TokenParser { identifier = b_identifier
{'fraction_non_alphanumeric': 0.17194682569263262, 'fraction_numerical': 0.004969561436203255, 'mean_word_length': 1.9925650557620818, 'pattern_counts': {'":': 12, '<': 25, '<?xml version=': 0, '>': 21, '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': '573054', 'n_tokens_mistral': 2825, 'n_tokens_neox': 2682, 'n_words': 870}