2016-09-07 22:14:20 +03:00
{- # LANGUAGE DataKinds # -}
2016-02-11 01:30:14 +03:00
module Language where
2016-09-07 22:14:20 +03:00
import Data.Record
import Info
2016-05-26 19:58:04 +03:00
import Prologue
2016-09-07 22:14:20 +03:00
import Source
import qualified Syntax as S
import Term
2016-02-11 01:32:11 +03:00
2016-02-11 01:30:14 +03:00
-- | A programming language.
data Language =
2016-09-08 23:22:05 +03:00
C
2016-02-11 01:35:08 +03:00
| CoffeeScript
| CPlusPlus
| CSharp
| CSS
| Haskell
| HTML
| Java
2016-02-11 01:30:14 +03:00
| JavaScript
2016-08-29 19:47:55 +03:00
| Markdown
2016-02-11 01:35:08 +03:00
| ObjectiveC
| Perl
| PHP
| Python
| R
| Ruby
| Swift
2016-10-17 22:30:55 +03:00
| Go
2016-05-26 18:34:02 +03:00
deriving ( Show )
2016-02-11 01:32:11 +03:00
-- | Returns a Language based on the file extension (including the ".").
languageForType :: Text -> Maybe Language
languageForType mediaType = case mediaType of
" .h " -> Just C
" .c " -> Just C
" .js " -> Just JavaScript
2016-08-29 19:48:26 +03:00
" .md " -> Just Markdown
2016-02-22 06:57:44 +03:00
" .rb " -> Just Ruby
2016-11-15 03:05:02 +03:00
" .go " -> Just Language . Go
2016-02-11 01:32:11 +03:00
_ -> Nothing
2016-09-07 22:14:20 +03:00
termConstructor
:: Source Char -- ^ The source that the term occurs within.
-> IO SourceSpan -- ^ The span that the term occupies. This is passed in 'IO' to guarantee some access constraints & encourage its use only when needed (improving performance).
-> Text -- ^ The name of the production for this node.
-> Range -- ^ The character range that the term occupies.
2016-12-06 22:21:31 +03:00
-> [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -- ^ The child nodes of the term.
-> IO [ SyntaxTerm Text '[Range, Category, SourceSpan] ] -- ^ All child nodes (included unnamed productions) of the term as 'IO'. Only use this if you need it.
-> IO ( SyntaxTerm Text '[Range, Category, SourceSpan] ) -- ^ The resulting term, in IO.
termConstructor source sourceSpan name range children _ =
2016-10-06 00:27:45 +03:00
withDefaultInfo $ case ( name , children ) of
( " ERROR " , _ ) -> S . Error children
( _ , [] ) -> S . Leaf ( toText $ slice range source )
_ -> S . Indexed children
where
withDefaultInfo syntax = do
sourceSpan' <- sourceSpan
pure $! cofree ( ( range .: Other name .: sourceSpan' .: RNil ) :< syntax )
2016-10-24 20:43:31 +03:00
toVarDecl :: ( HasField fields Category ) => Term ( S . Syntax Text ) ( Record fields ) -> Term ( S . Syntax Text ) ( Record fields )
toVarDecl child = cofree $ setCategory ( extract child ) VarDecl :< S . VarDecl child
toTuple :: Term ( S . Syntax Text ) ( Record fields ) -> [ Term ( S . Syntax Text ) ( Record fields ) ]
toTuple child | S . Indexed [ key , value ] <- unwrap child = [ cofree ( extract child :< S . Pair key value ) ]
toTuple child | S . Fixed [ key , value ] <- unwrap child = [ cofree ( extract child :< S . Pair key value ) ]
toTuple child | S . Leaf c <- unwrap child = [ cofree ( extract child :< S . Comment c ) ]
toTuple child = pure child