axel-0.0.1: src/Axel/Denormalize.hs
module Axel.Denormalize where
import Axel.AST
( ArgumentList(ArgumentList)
, Expression(ECaseBlock, EEmptySExpression, EFunctionApplication,
EIdentifier, ELambda, ELetBlock, ELiteral)
, Import(ImportItem, ImportType)
, ImportSpecification(ImportAll, ImportOnly)
, Literal(LChar, LInt, LList, LString)
, Statement(SDataDeclaration, SFunctionDefinition, SLanguagePragma,
SMacroDefinition, SModuleDeclaration, SQualifiedImport,
SRestrictedImport, STopLevel, STypeSynonym, STypeclassInstance,
SUnrestrictedImport)
, TopLevel(TopLevel)
, TypeDefinition(ProperType, TypeConstructor)
, alias
, arguments
, bindings
, body
, constructors
, definition
, definitions
, expr
, function
, imports
, instanceName
, language
, matches
, moduleName
, name
, typeDefinition
, typeSignature
)
import qualified Axel.Parse as Parse
( Expression(LiteralChar, LiteralInt, LiteralString, SExpression,
Symbol)
)
import Control.Lens.Operators ((^.))
denormalizeExpression :: Expression -> Parse.Expression
denormalizeExpression (ECaseBlock caseBlock) =
let denormalizedCases =
map
(\(pat, res) ->
Parse.SExpression
[denormalizeExpression pat, denormalizeExpression res])
(caseBlock ^. matches)
in Parse.SExpression $
Parse.Symbol "case" :
denormalizeExpression (caseBlock ^. expr) : denormalizedCases
denormalizeExpression EEmptySExpression = Parse.SExpression []
denormalizeExpression (EFunctionApplication functionApplication) =
Parse.SExpression $
denormalizeExpression (functionApplication ^. function) :
map denormalizeExpression (functionApplication ^. arguments)
denormalizeExpression (EIdentifier x) = Parse.Symbol x
denormalizeExpression (ELambda lambda) =
let denormalizedArguments =
Parse.SExpression $ map denormalizeExpression (lambda ^. arguments)
in Parse.SExpression
[ Parse.Symbol "fn"
, denormalizedArguments
, denormalizeExpression (lambda ^. body)
]
denormalizeExpression (ELetBlock letBlock) =
let denormalizedBindings =
Parse.SExpression $
map
(\(var, val) ->
Parse.SExpression
[denormalizeExpression var, denormalizeExpression val])
(letBlock ^. bindings)
in Parse.SExpression
[ Parse.Symbol "let"
, denormalizedBindings
, denormalizeExpression (letBlock ^. body)
]
denormalizeExpression (ELiteral x) =
case x of
LChar char -> Parse.LiteralChar char
LInt int -> Parse.LiteralInt int
LList list ->
Parse.SExpression $ Parse.Symbol "list" : map denormalizeExpression list
LString string -> Parse.LiteralString string
denormalizeBinding :: (ArgumentList, Expression) -> Parse.Expression
denormalizeBinding (ArgumentList argumentList, expression) =
Parse.SExpression
[ Parse.SExpression $ map denormalizeExpression argumentList
, denormalizeExpression expression
]
denormalizeImportSpecification :: ImportSpecification -> Parse.Expression
denormalizeImportSpecification ImportAll = Parse.Symbol "all"
denormalizeImportSpecification (ImportOnly importList) =
Parse.SExpression $ map denormalizeImport importList
where
denormalizeImport (ImportItem item) = Parse.Symbol item
denormalizeImport (ImportType type' items) =
Parse.SExpression (Parse.Symbol type' : map Parse.Symbol items)
denormalizeStatement :: Statement -> Parse.Expression
denormalizeStatement (SDataDeclaration dataDeclaration) =
let denormalizedTypeDefinition =
case dataDeclaration ^. typeDefinition of
TypeConstructor typeConstructor ->
denormalizeExpression $ EFunctionApplication typeConstructor
ProperType properType -> Parse.Symbol properType
in Parse.SExpression
[ Parse.Symbol "data"
, denormalizedTypeDefinition
, Parse.SExpression $
map
(denormalizeExpression . EFunctionApplication)
(dataDeclaration ^. constructors)
]
denormalizeStatement (SFunctionDefinition functionDefinition) =
Parse.SExpression $
Parse.Symbol "=" :
Parse.Symbol (functionDefinition ^. name) :
denormalizeExpression
(EFunctionApplication (functionDefinition ^. typeSignature)) :
map denormalizeBinding (functionDefinition ^. definitions)
denormalizeStatement (SLanguagePragma languagePragma) =
Parse.SExpression
[Parse.Symbol "language", Parse.Symbol $ languagePragma ^. language]
denormalizeStatement (SMacroDefinition macroDefinition) =
Parse.SExpression $
Parse.Symbol "defmacro" :
Parse.Symbol (macroDefinition ^. name) :
map denormalizeBinding (macroDefinition ^. definitions)
denormalizeStatement (SModuleDeclaration identifier) =
Parse.SExpression [Parse.Symbol "module", Parse.Symbol identifier]
denormalizeStatement (SQualifiedImport qualifiedImport) =
Parse.SExpression
[ Parse.Symbol "importq"
, Parse.Symbol $ qualifiedImport ^. moduleName
, Parse.Symbol $ qualifiedImport ^. alias
, denormalizeImportSpecification (qualifiedImport ^. imports)
]
denormalizeStatement (SRestrictedImport restrictedImport) =
Parse.SExpression
[ Parse.Symbol "import"
, Parse.Symbol $ restrictedImport ^. moduleName
, denormalizeImportSpecification (restrictedImport ^. imports)
]
denormalizeStatement (STopLevel (TopLevel statements)) =
Parse.SExpression $ Parse.Symbol "begin" : map denormalizeStatement statements
denormalizeStatement (STypeclassInstance typeclassInstance) =
Parse.SExpression
[ Parse.Symbol "instance"
, denormalizeExpression (typeclassInstance ^. instanceName)
, Parse.SExpression $
map
(denormalizeStatement . SFunctionDefinition)
(typeclassInstance ^. definitions)
]
denormalizeStatement (STypeSynonym typeSynonym) =
Parse.SExpression
[ Parse.Symbol "type"
, denormalizeExpression (typeSynonym ^. alias)
, denormalizeExpression (typeSynonym ^. definition)
]
denormalizeStatement (SUnrestrictedImport identifier) =
Parse.SExpression [Parse.Symbol "importUnrestricted", Parse.Symbol identifier]