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]