module Axel.Denormalize where import Axel.AST ( Expression(ECaseBlock, EEmptySExpression, EFunctionApplication, EIdentifier, EIfBlock, ELambda, ELetBlock, ELiteral, ERawExpression, ERecordDefinition, ERecordType) , Import(ImportItem, ImportType) , ImportSpecification(ImportAll, ImportOnly) , Literal(LChar, LInt, LString) , Statement(SDataDeclaration, SFunctionDefinition, SMacroDefinition, SMacroImport, SModuleDeclaration, SNewtypeDeclaration, SPragma, SQualifiedImport, SRawStatement, SRestrictedImport, STopLevel, STypeSignature, STypeSynonym, STypeclassDefinition, STypeclassInstance, SUnrestrictedImport) , TopLevel(TopLevel) , TypeDefinition(ProperType, TypeConstructor) , alias , arguments , bindings , body , cond , constraints , constructor , constructors , definition , definitions , expr , fields , function , functionDefinition , ifFalse , ifTrue , imports , instanceName , matches , moduleName , name , pragmaSpecification , signatures , typeDefinition , whereBindings ) 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 (EIfBlock ifBlock) = Parse.SExpression [ Parse.Symbol "if" , denormalizeExpression (ifBlock ^. cond) , denormalizeExpression (ifBlock ^. ifTrue) , denormalizeExpression (ifBlock ^. ifFalse) ] denormalizeExpression (ELambda lambda) = let denormalizedArguments = Parse.SExpression $ map denormalizeExpression (lambda ^. arguments) in Parse.SExpression [ Parse.Symbol "\\" , 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 LString string -> Parse.LiteralString string denormalizeExpression (ERawExpression rawSource) = Parse.SExpression [Parse.Symbol "raw", Parse.LiteralString rawSource] denormalizeExpression (ERecordDefinition recordDefinition) = let denormalizedBindings = map (\(var, val) -> Parse.SExpression [Parse.Symbol var, denormalizeExpression val]) (recordDefinition ^. bindings) in Parse.SExpression (Parse.Symbol "record" : denormalizedBindings) denormalizeExpression (ERecordType recordType) = let denormalizedFields = map (\(field, ty) -> Parse.SExpression [Parse.Symbol field, denormalizeExpression ty]) (recordType ^. fields) in Parse.SExpression (Parse.Symbol "recordType" : denormalizedFields) 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 : map (denormalizeExpression . EFunctionApplication) (dataDeclaration ^. constructors)) denormalizeStatement (SFunctionDefinition fnDef) = Parse.SExpression $ Parse.Symbol "=" : Parse.Symbol (fnDef ^. name) : Parse.SExpression (map denormalizeExpression (fnDef ^. arguments)) : denormalizeExpression (fnDef ^. body) : map (denormalizeStatement . SFunctionDefinition) (fnDef ^. whereBindings) denormalizeStatement (SMacroDefinition macroDef) = Parse.SExpression $ Parse.Symbol "=macro" : Parse.Symbol (macroDef ^. functionDefinition . name) : Parse.SExpression (map denormalizeExpression (macroDef ^. functionDefinition . arguments)) : denormalizeExpression (macroDef ^. functionDefinition . body) : map (denormalizeStatement . SFunctionDefinition) (macroDef ^. functionDefinition . whereBindings) denormalizeStatement (SMacroImport macroImport) = Parse.SExpression [ Parse.Symbol "importm" , Parse.Symbol $ macroImport ^. moduleName , Parse.SExpression $ map Parse.Symbol (macroImport ^. imports) ] denormalizeStatement (SModuleDeclaration identifier) = Parse.SExpression [Parse.Symbol "module", Parse.Symbol identifier] denormalizeStatement (SNewtypeDeclaration newtypeDeclaration) = let denormalizedTypeDefinition = case newtypeDeclaration ^. typeDefinition of TypeConstructor typeConstructor -> denormalizeExpression $ EFunctionApplication typeConstructor ProperType properType -> Parse.Symbol properType in Parse.SExpression [ Parse.Symbol "newtype" , denormalizedTypeDefinition , denormalizeExpression $ EFunctionApplication (newtypeDeclaration ^. constructor) ] denormalizeStatement (SPragma pragma) = Parse.SExpression [Parse.Symbol "pragma", Parse.LiteralString (pragma ^. pragmaSpecification)] denormalizeStatement (SQualifiedImport qualifiedImport) = Parse.SExpression [ Parse.Symbol "importq" , Parse.Symbol $ qualifiedImport ^. moduleName , Parse.Symbol $ qualifiedImport ^. alias , denormalizeImportSpecification (qualifiedImport ^. imports) ] denormalizeStatement (SRawStatement rawSource) = Parse.SExpression [Parse.Symbol "raw", Parse.LiteralString rawSource] 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 (STypeclassDefinition typeclassDefinition) = Parse.SExpression (Parse.Symbol "class" : Parse.SExpression (Parse.Symbol "list" : map denormalizeExpression (typeclassDefinition ^. constraints)) : denormalizeExpression (typeclassDefinition ^. name) : map (denormalizeStatement . STypeSignature) (typeclassDefinition ^. signatures)) denormalizeStatement (STypeclassInstance typeclassInstance) = Parse.SExpression (Parse.Symbol "instance" : denormalizeExpression (typeclassInstance ^. instanceName) : map (denormalizeStatement . SFunctionDefinition) (typeclassInstance ^. definitions)) denormalizeStatement (STypeSignature typeSig) = Parse.SExpression [ Parse.Symbol "::" , Parse.Symbol (typeSig ^. name) , denormalizeExpression (typeSig ^. typeDefinition) ] 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]