hydra-0.15.0: src/main/haskell/Hydra/Cpp/Serde.hs
-- Note: this is an automatically generated file. Do not edit.
-- | Serialization functions for converting C++ AST to abstract expressions
module Hydra.Cpp.Serde where
import qualified Hydra.Ast as Ast
import qualified Hydra.Cpp.Syntax as Syntax
import qualified Hydra.Lib.Equality as Equality
import qualified Hydra.Lib.Lists as Lists
import qualified Hydra.Lib.Literals as Literals
import qualified Hydra.Lib.Logic as Logic
import qualified Hydra.Lib.Maybes as Maybes
import qualified Hydra.Lib.Strings as Strings
import qualified Hydra.Serialization as Serialization
import Prelude hiding (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci
-- | Convert an access specifier to an expression
encodeAccessSpecifier :: Syntax.AccessSpecifier -> Ast.Expr
encodeAccessSpecifier a =
case a of
Syntax.AccessSpecifierPublic -> Serialization.cst "public"
Syntax.AccessSpecifierProtected -> Serialization.cst "protected"
Syntax.AccessSpecifierPrivate -> Serialization.cst "private"
Syntax.AccessSpecifierNone -> Serialization.cst ""
-- | Convert an add operation to an expression
encodeAddOperation :: Syntax.AddOperation -> Ast.Expr
encodeAddOperation op =
let left = Syntax.addOperationLeft op
right = Syntax.addOperationRight op
in (Serialization.spaceSep [
encodeAdditiveExpression left,
(Serialization.cst "+"),
(encodeMultiplicativeExpression right)])
-- | Convert an additive expression to an expression
encodeAdditiveExpression :: Syntax.AdditiveExpression -> Ast.Expr
encodeAdditiveExpression e =
case e of
Syntax.AdditiveExpressionMultiplicative v0 -> encodeMultiplicativeExpression v0
Syntax.AdditiveExpressionAdd v0 -> encodeAddOperation v0
Syntax.AdditiveExpressionSubtract v0 -> encodeSubtractOperation v0
-- | Convert an and expression to an expression
encodeAndExpression :: Syntax.AndExpression -> Ast.Expr
encodeAndExpression e =
case e of
Syntax.AndExpressionEquality v0 -> encodeEqualityExpression v0
Syntax.AndExpressionBitwiseAnd v0 -> encodeBitwiseAndOperation v0
-- | Convert an assignment expression to an expression
encodeAssignmentExpression :: Syntax.AssignmentExpression -> Ast.Expr
encodeAssignmentExpression a =
case a of
Syntax.AssignmentExpressionConditional v0 -> encodeConditionalExpression v0
Syntax.AssignmentExpressionAssignment v0 -> encodeExplicitAssignment v0
-- | Convert an assignment operator to an expression
encodeAssignmentOperator :: Syntax.AssignmentOperator -> Ast.Expr
encodeAssignmentOperator op =
case op of
Syntax.AssignmentOperatorAssign -> Serialization.cst "="
Syntax.AssignmentOperatorPlusAssign -> Serialization.cst "+="
Syntax.AssignmentOperatorMinusAssign -> Serialization.cst "-="
Syntax.AssignmentOperatorMultiplyAssign -> Serialization.cst "*="
Syntax.AssignmentOperatorDivideAssign -> Serialization.cst "/="
Syntax.AssignmentOperatorModuloAssign -> Serialization.cst "%="
Syntax.AssignmentOperatorLeftShiftAssign -> Serialization.cst "<<="
Syntax.AssignmentOperatorRightShiftAssign -> Serialization.cst ">>="
Syntax.AssignmentOperatorBitwiseAndAssign -> Serialization.cst "&="
Syntax.AssignmentOperatorBitwiseXorAssign -> Serialization.cst "^="
Syntax.AssignmentOperatorBitwiseOrAssign -> Serialization.cst "|="
-- | Convert a base specifier to an expression
encodeBaseSpecifier :: Syntax.BaseSpecifier -> Ast.Expr
encodeBaseSpecifier bs =
let access = Syntax.baseSpecifierAccess bs
name = Syntax.baseSpecifierName bs
in (Serialization.spaceSep [
encodeAccessSpecifier access,
(Serialization.cst name)])
-- | Convert a basic type to an expression
encodeBasicType :: Syntax.BasicType -> Ast.Expr
encodeBasicType t =
case t of
Syntax.BasicTypeVoid -> Serialization.cst "void"
Syntax.BasicTypeBool -> Serialization.cst "bool"
Syntax.BasicTypeChar -> Serialization.cst "char"
Syntax.BasicTypeInt -> Serialization.cst "int"
Syntax.BasicTypeFloat -> Serialization.cst "float"
Syntax.BasicTypeDouble -> Serialization.cst "double"
Syntax.BasicTypeString -> Serialization.cst "std::string"
Syntax.BasicTypeAuto -> Serialization.cst "auto"
Syntax.BasicTypeNamed v0 -> Serialization.cst v0
-- | Convert a bitwise and operation to an expression
encodeBitwiseAndOperation :: Syntax.BitwiseAndOperation -> Ast.Expr
encodeBitwiseAndOperation op =
let left = Syntax.bitwiseAndOperationLeft op
right = Syntax.bitwiseAndOperationRight op
in (Serialization.spaceSep [
encodeAndExpression left,
(Serialization.cst "&"),
(encodeEqualityExpression right)])
-- | Convert a bitwise or operation to an expression
encodeBitwiseOrOperation :: Syntax.BitwiseOrOperation -> Ast.Expr
encodeBitwiseOrOperation op =
let left = Syntax.bitwiseOrOperationLeft op
right = Syntax.bitwiseOrOperationRight op
in (Serialization.spaceSep [
encodeInclusiveOrExpression left,
(Serialization.cst "|"),
(encodeExclusiveOrExpression right)])
-- | Convert a bitwise xor operation to an expression
encodeBitwiseXorOperation :: Syntax.BitwiseXorOperation -> Ast.Expr
encodeBitwiseXorOperation op =
let left = Syntax.bitwiseXorOperationLeft op
right = Syntax.bitwiseXorOperationRight op
in (Serialization.spaceSep [
encodeExclusiveOrExpression left,
(Serialization.cst "^"),
(encodeAndExpression right)])
-- | Convert a boolean literal to an expression
encodeBooleanLiteral :: Syntax.BooleanLiteral -> Ast.Expr
encodeBooleanLiteral bl = Logic.ifElse (Syntax.unBooleanLiteral bl) (Serialization.cst "true") (Serialization.cst "false")
-- | Convert a capture to an expression
encodeCapture :: Syntax.Capture -> Ast.Expr
encodeCapture cap =
let name = Syntax.captureName cap
byRef = Syntax.captureByReference cap
in (Logic.ifElse byRef (Serialization.cst (Strings.cat2 "&" name)) (Serialization.cst name))
-- | Convert a capture list to an expression
encodeCaptureList :: Syntax.CaptureList -> Ast.Expr
encodeCaptureList cl =
case cl of
Syntax.CaptureListCaptureByValue -> Serialization.cst "[=]"
Syntax.CaptureListCaptures v0 -> Serialization.bracketList Serialization.inlineStyle (Lists.map encodeCapture v0)
-- | Convert a case statement to an expression
encodeCaseStatement :: Syntax.CaseStatement -> Ast.Expr
encodeCaseStatement stmt =
case stmt of
Syntax.CaseStatementCase v0 -> encodeCaseValue v0
Syntax.CaseStatementDefault v0 -> Serialization.spaceSep [
Serialization.cst "default:",
(encodeStatement v0)]
-- | Convert a case value to an expression
encodeCaseValue :: Syntax.CaseValue -> Ast.Expr
encodeCaseValue cv =
let value = Syntax.caseValueValue cv
statement = Syntax.caseValueStatement cv
in (Serialization.spaceSep [
Serialization.cst "case",
(Serialization.noSep [
encodeExpression value,
(Serialization.cst ":")]),
(encodeStatement statement)])
-- | Convert a class body to an expression
encodeClassBody :: Bool -> Syntax.ClassBody -> Ast.Expr
encodeClassBody commas cb =
Serialization.curlyBlock Serialization.fullBlockStyle (Serialization.doubleNewlineSep (Lists.map (encodeMemberSpecification commas) (Syntax.unClassBody cb)))
-- | Convert a class declaration to an expression
encodeClassDeclaration :: Syntax.ClassDeclaration -> Ast.Expr
encodeClassDeclaration cd =
let spec = Syntax.classDeclarationSpecifier cd
mbody = Syntax.classDeclarationBody cd
key = Syntax.classSpecifierKey spec
isEnum = Logic.or (Equality.equal key Syntax.ClassKeyEnum) (Equality.equal key Syntax.ClassKeyEnumClass)
in (Serialization.withSemi (Serialization.spaceSep (Maybes.cat [
Just (encodeClassSpecifier spec),
(Maybes.map (\body -> encodeClassBody isEnum body) mbody)])))
-- | Convert a class key to an expression
encodeClassKey :: Syntax.ClassKey -> Ast.Expr
encodeClassKey k =
case k of
Syntax.ClassKeyClass -> Serialization.cst "class"
Syntax.ClassKeyEnum -> Serialization.cst "enum"
Syntax.ClassKeyEnumClass -> Serialization.cst "enum class"
Syntax.ClassKeyStruct -> Serialization.cst "struct"
-- | Convert a class specifier to an expression
encodeClassSpecifier :: Syntax.ClassSpecifier -> Ast.Expr
encodeClassSpecifier cs =
let key = Syntax.classSpecifierKey cs
name = Syntax.classSpecifierName cs
inheritance = Syntax.classSpecifierInheritance cs
in (Serialization.spaceSep (Lists.concat [
[
encodeClassKey key,
(Serialization.cst name)],
(Logic.ifElse (Lists.null inheritance) [] [
Serialization.cst ":",
(Serialization.commaSep Serialization.inlineStyle (Lists.map encodeBaseSpecifier inheritance))])]))
-- | Convert a comma expression to an expression
encodeCommaExpression :: Syntax.CommaExpression -> Ast.Expr
encodeCommaExpression ce =
let left = Syntax.commaExpressionLeft ce
right = Syntax.commaExpressionRight ce
in (Serialization.spaceSep [
encodeExpression left,
(Serialization.cst ","),
(encodeAssignmentExpression right)])
-- | Convert a comment to an expression
encodeComment :: Syntax.Comment -> Ast.Expr
encodeComment c =
let text = Syntax.commentText c
isMultiline = Syntax.commentIsMultiline c
in (Serialization.cst (toCppComments text isMultiline))
-- | Convert a compound statement to an expression
encodeCompoundStatement :: Syntax.CompoundStatement -> Ast.Expr
encodeCompoundStatement cs =
Serialization.curlyBracesList (Just "") Serialization.fullBlockStyle (Lists.map encodeStatement (Syntax.unCompoundStatement cs))
-- | Convert a conditional expression to an expression
encodeConditionalExpression :: Syntax.ConditionalExpression -> Ast.Expr
encodeConditionalExpression c =
case c of
Syntax.ConditionalExpressionLogicalOr v0 -> encodeLogicalOrExpression v0
Syntax.ConditionalExpressionTernary v0 -> encodeTernaryExpression v0
-- | Convert a constructor declaration to an expression
encodeConstructorDeclaration :: Syntax.ConstructorDeclaration -> Ast.Expr
encodeConstructorDeclaration cd =
let name = Syntax.constructorDeclarationName cd
params = Syntax.constructorDeclarationParameters cd
inits = Syntax.constructorDeclarationInitializers cd
body = Syntax.constructorDeclarationBody cd
in (Serialization.spaceSep (Maybes.cat [
Just (Serialization.noSep [
Serialization.cst name,
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeParameter params)))]),
(Logic.ifElse (Lists.null inits) Nothing (Just (Serialization.spaceSep [
Serialization.cst ":",
(Serialization.commaSep Serialization.inlineStyle (Lists.map encodeMemInitializer inits))]))),
(Just (encodeFunctionBody body))]))
-- | Convert a declaration to an expression
encodeDeclaration :: Syntax.Declaration -> Ast.Expr
encodeDeclaration d =
case d of
Syntax.DeclarationPreprocessor v0 -> encodePreprocessorDirective v0
Syntax.DeclarationClass v0 -> encodeClassDeclaration v0
Syntax.DeclarationFunction v0 -> encodeFunctionDeclaration v0
Syntax.DeclarationVariable v0 -> encodeVariableDeclaration False v0
Syntax.DeclarationTypedef v0 -> encodeTypedefDeclaration v0
Syntax.DeclarationNamespace v0 -> encodeNamespaceDeclaration v0
Syntax.DeclarationTemplate v0 -> encodeTemplateDeclaration v0
-- | Convert a define directive to an expression
encodeDefineDirective :: Syntax.DefineDirective -> Ast.Expr
encodeDefineDirective dd =
let name = Syntax.defineDirectiveName dd
params = Syntax.defineDirectiveParameters dd
replacement = Syntax.defineDirectiveReplacement dd
in (Serialization.spaceSep (Lists.concat [
[
Serialization.cst "#define",
(Serialization.cst name)],
(Maybes.maybe [] (\ps -> [
Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map (\p -> Serialization.cst p) ps))]) params),
(Maybes.maybe [] (\r -> [
Serialization.cst r]) replacement)]))
-- | Convert a destructor declaration to an expression
encodeDestructorDeclaration :: Syntax.DestructorDeclaration -> Ast.Expr
encodeDestructorDeclaration dd =
let prefixSpecs = Syntax.destructorDeclarationPrefixSpecifiers dd
name = Syntax.destructorDeclarationName dd
suffixSpecs = Syntax.destructorDeclarationSuffixSpecifiers dd
body = Syntax.destructorDeclarationBody dd
in (Serialization.spaceSep (Lists.concat [
Lists.map encodeFunctionSpecifierPrefix prefixSpecs,
[
Serialization.noSep [
Serialization.cst (Strings.cat2 "~" name),
(Serialization.parens (Serialization.cst ""))]],
(Lists.map encodeFunctionSpecifierSuffix suffixSpecs),
[
encodeFunctionBody body]]))
-- | Convert a divide operation to an expression
encodeDivideOperation :: Syntax.DivideOperation -> Ast.Expr
encodeDivideOperation op =
let left = Syntax.divideOperationLeft op
right = Syntax.divideOperationRight op
in (Serialization.spaceSep [
encodeMultiplicativeExpression left,
(Serialization.cst "/"),
(encodeUnaryExpression right)])
-- | Convert a do statement to an expression
encodeDoStatement :: Syntax.DoStatement -> Ast.Expr
encodeDoStatement ds =
let body = Syntax.doStatementBody ds
cond = Syntax.doStatementCondition ds
in (Serialization.newlineSep [
Serialization.cst "do",
(encodeStatement body),
(Serialization.withSemi (Serialization.spaceSep [
Serialization.cst "while",
(Serialization.parens (encodeExpression cond))]))])
-- | Convert an elif directive to an expression
encodeElifDirective :: Syntax.ElifDirective -> Ast.Expr
encodeElifDirective ed =
Serialization.spaceSep [
Serialization.cst "#elif",
(Serialization.cst (Syntax.elifDirectiveCondition ed))]
-- | Convert an else directive to an expression
encodeElseDirective :: t0 -> Ast.Expr
encodeElseDirective ed = Serialization.cst "#else"
-- | Convert an endif directive to an expression
encodeEndifDirective :: t0 -> Ast.Expr
encodeEndifDirective ed = Serialization.cst "#endif"
-- | Convert an equal operation to an expression
encodeEqualOperation :: Syntax.EqualOperation -> Ast.Expr
encodeEqualOperation op =
let left = Syntax.equalOperationLeft op
right = Syntax.equalOperationRight op
in (Serialization.spaceSep [
encodeEqualityExpression left,
(Serialization.cst "=="),
(encodeRelationalExpression right)])
-- | Convert an equality expression to an expression
encodeEqualityExpression :: Syntax.EqualityExpression -> Ast.Expr
encodeEqualityExpression e =
case e of
Syntax.EqualityExpressionRelational v0 -> encodeRelationalExpression v0
Syntax.EqualityExpressionEqual v0 -> encodeEqualOperation v0
Syntax.EqualityExpressionNotEqual v0 -> encodeNotEqualOperation v0
-- | Convert an error directive to an expression
encodeErrorDirective :: Syntax.ErrorDirective -> Ast.Expr
encodeErrorDirective ed =
Serialization.spaceSep [
Serialization.cst "#error",
(Serialization.cst (Syntax.errorDirectiveMessage ed))]
-- | Convert an exclusive or expression to an expression
encodeExclusiveOrExpression :: Syntax.ExclusiveOrExpression -> Ast.Expr
encodeExclusiveOrExpression e =
case e of
Syntax.ExclusiveOrExpressionAnd v0 -> encodeAndExpression v0
Syntax.ExclusiveOrExpressionBitwiseXor v0 -> encodeBitwiseXorOperation v0
-- | Convert an explicit assignment to an expression
encodeExplicitAssignment :: Syntax.ExplicitAssignment -> Ast.Expr
encodeExplicitAssignment ea =
let left = Syntax.explicitAssignmentLeft ea
op = Syntax.explicitAssignmentOp ea
right = Syntax.explicitAssignmentRight ea
in (Serialization.spaceSep [
encodeLogicalOrExpression left,
(encodeAssignmentOperator op),
(encodeAssignmentExpression right)])
-- | Convert an expression to an expression
encodeExpression :: Syntax.Expression -> Ast.Expr
encodeExpression e =
case e of
Syntax.ExpressionAssignment v0 -> encodeAssignmentExpression v0
Syntax.ExpressionComma v0 -> encodeCommaExpression v0
-- | Convert a for-init to an expression
encodeForInit :: Syntax.ForInit -> Ast.Expr
encodeForInit i =
case i of
Syntax.ForInitExpression v0 -> encodeExpression v0
Syntax.ForInitDeclaration v0 -> encodeVariableDeclaration False v0
Syntax.ForInitEmpty -> Serialization.cst ""
-- | Convert a for statement to an expression
encodeForStatement :: Syntax.ForStatement -> Ast.Expr
encodeForStatement fs =
let init = Syntax.forStatementInit fs
cond = Syntax.forStatementCondition fs
inc = Syntax.forStatementIncrement fs
body = Syntax.forStatementBody fs
in (Serialization.newlineSep [
Serialization.spaceSep [
Serialization.cst "for",
(Serialization.parens (Serialization.noSep [
encodeForInit init,
(Serialization.cst ";"),
(encodeExpression cond),
(Serialization.cst ";"),
(encodeExpression inc)]))],
(encodeStatement body)])
-- | Convert a function application to an expression
encodeFunctionApplication :: Syntax.FunctionApplication -> Ast.Expr
encodeFunctionApplication fa =
let func = Syntax.functionApplicationFunction fa
args = Syntax.functionApplicationArguments fa
in (Serialization.spaceSep [
encodeFunctionIdentifier func,
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeExpression args)))])
-- | Convert a function body to an expression
encodeFunctionBody :: Syntax.FunctionBody -> Ast.Expr
encodeFunctionBody b =
case b of
Syntax.FunctionBodyCompound v0 -> encodeCompoundStatement v0
Syntax.FunctionBodyDeclaration -> Serialization.cst ";"
Syntax.FunctionBodyPure -> Serialization.withSemi (Serialization.cst "= 0")
Syntax.FunctionBodyDefault -> Serialization.withSemi (Serialization.cst "= default")
-- | Convert a function call operation to an expression
encodeFunctionCallOperation :: Syntax.FunctionCallOperation -> Ast.Expr
encodeFunctionCallOperation fco =
let func = Syntax.functionCallOperationFunction fco
args = Syntax.functionCallOperationArguments fco
in (Serialization.noSep [
encodePostfixExpression func,
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeExpression args)))])
-- | Convert a function declaration to an expression
encodeFunctionDeclaration :: Syntax.FunctionDeclaration -> Ast.Expr
encodeFunctionDeclaration fd =
let prefixSpecs = Syntax.functionDeclarationPrefixSpecifiers fd
retType = Syntax.functionDeclarationReturnType fd
name = Syntax.functionDeclarationName fd
params = Syntax.functionDeclarationParameters fd
suffixSpecs = Syntax.functionDeclarationSuffixSpecifiers fd
body = Syntax.functionDeclarationBody fd
in (Serialization.spaceSep (Lists.concat [
Lists.map encodeFunctionSpecifierPrefix prefixSpecs,
[
encodeTypeExpression retType,
(Serialization.noSep [
Serialization.cst name,
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeParameter params)))])],
(Lists.map encodeFunctionSpecifierSuffix suffixSpecs),
[
encodeFunctionBody body]]))
-- | Convert a function identifier to an expression
encodeFunctionIdentifier :: Syntax.FunctionIdentifier -> Ast.Expr
encodeFunctionIdentifier f =
case f of
Syntax.FunctionIdentifierSimple v0 -> Serialization.cst v0
Syntax.FunctionIdentifierQualified v0 -> encodeQualifiedIdentifier v0
-- | Convert a function specifier prefix to an expression
encodeFunctionSpecifierPrefix :: Syntax.FunctionSpecifierPrefix -> Ast.Expr
encodeFunctionSpecifierPrefix s =
case s of
Syntax.FunctionSpecifierPrefixInline -> Serialization.cst "inline"
Syntax.FunctionSpecifierPrefixVirtual -> Serialization.cst "virtual"
Syntax.FunctionSpecifierPrefixStatic -> Serialization.cst "static"
Syntax.FunctionSpecifierPrefixExplicit -> Serialization.cst "explicit"
-- | Convert a function specifier suffix to an expression
encodeFunctionSpecifierSuffix :: Syntax.FunctionSpecifierSuffix -> Ast.Expr
encodeFunctionSpecifierSuffix s =
case s of
Syntax.FunctionSpecifierSuffixConst -> Serialization.cst "const"
Syntax.FunctionSpecifierSuffixNoexcept -> Serialization.cst "noexcept"
Syntax.FunctionSpecifierSuffixOverride -> Serialization.cst "override"
Syntax.FunctionSpecifierSuffixFinal -> Serialization.cst "final"
-- | Convert a function type to an expression
encodeFunctionType :: Syntax.FunctionType -> Ast.Expr
encodeFunctionType ft =
let retType = Syntax.functionTypeReturnType ft
params = Syntax.functionTypeParameters ft
in (Serialization.spaceSep [
encodeTypeExpression retType,
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeParameter params)))])
-- | Convert a greater-than-or-equal operation to an expression
encodeGreaterEqualOperation :: Syntax.GreaterEqualOperation -> Ast.Expr
encodeGreaterEqualOperation op =
let left = Syntax.greaterEqualOperationLeft op
right = Syntax.greaterEqualOperationRight op
in (Serialization.spaceSep [
encodeRelationalExpression left,
(Serialization.cst ">="),
(encodeShiftExpression right)])
-- | Convert a greater-than operation to an expression
encodeGreaterOperation :: Syntax.GreaterOperation -> Ast.Expr
encodeGreaterOperation op =
let left = Syntax.greaterOperationLeft op
right = Syntax.greaterOperationRight op
in (Serialization.spaceSep [
encodeRelationalExpression left,
(Serialization.cst ">"),
(encodeShiftExpression right)])
-- | Convert an if directive to an expression
encodeIfDirective :: Syntax.IfDirective -> Ast.Expr
encodeIfDirective ifd =
Serialization.spaceSep [
Serialization.cst "#if",
(Serialization.cst (Syntax.ifDirectiveCondition ifd))]
-- | Convert an ifdef directive to an expression
encodeIfdefDirective :: Syntax.IfdefDirective -> Ast.Expr
encodeIfdefDirective id =
Serialization.spaceSep [
Serialization.cst "#ifdef",
(Serialization.cst (Syntax.ifdefDirectiveIdentifier id))]
-- | Convert an ifndef directive to an expression
encodeIfndefDirective :: Syntax.IfndefDirective -> Ast.Expr
encodeIfndefDirective ind =
Serialization.spaceSep [
Serialization.cst "#ifndef",
(Serialization.cst (Syntax.ifndefDirectiveIdentifier ind))]
-- | Convert an include directive to an expression
encodeIncludeDirective :: Syntax.IncludeDirective -> Ast.Expr
encodeIncludeDirective incl =
let name = Syntax.includeDirectiveName incl
isSystem = Syntax.includeDirectiveIsSystem incl
in (Logic.ifElse isSystem (Serialization.cst (Strings.cat [
"#include <",
name,
">"])) (Serialization.cst (Strings.cat [
"#include \"",
name,
"\""])))
-- | Convert an inclusive or expression to an expression
encodeInclusiveOrExpression :: Syntax.InclusiveOrExpression -> Ast.Expr
encodeInclusiveOrExpression e =
case e of
Syntax.InclusiveOrExpressionExclusiveOr v0 -> encodeExclusiveOrExpression v0
Syntax.InclusiveOrExpressionBitwiseOr v0 -> encodeBitwiseOrOperation v0
-- | Convert an integer literal to an expression
encodeIntegerLiteral :: Syntax.IntegerLiteral -> Ast.Expr
encodeIntegerLiteral i =
case i of
Syntax.IntegerLiteralDecimal v0 -> Serialization.cst (Literals.showBigint v0)
Syntax.IntegerLiteralHexadecimal v0 -> Serialization.cst (Strings.cat2 "0x" v0)
Syntax.IntegerLiteralOctal v0 -> Serialization.cst (Strings.cat2 "0" v0)
Syntax.IntegerLiteralBinary v0 -> Serialization.cst (Strings.cat2 "0b" v0)
-- | Convert an iteration statement to an expression
encodeIterationStatement :: Syntax.IterationStatement -> Ast.Expr
encodeIterationStatement i =
case i of
Syntax.IterationStatementWhile v0 -> encodeWhileStatement v0
Syntax.IterationStatementDo v0 -> encodeDoStatement v0
Syntax.IterationStatementFor v0 -> encodeForStatement v0
Syntax.IterationStatementRangeFor v0 -> encodeRangeForStatement v0
-- | Convert a jump statement to an expression
encodeJumpStatement :: Syntax.JumpStatement -> Ast.Expr
encodeJumpStatement j =
case j of
Syntax.JumpStatementBreak -> Serialization.withSemi (Serialization.cst "break")
Syntax.JumpStatementContinue -> Serialization.withSemi (Serialization.cst "continue")
Syntax.JumpStatementReturnValue v0 -> Serialization.withSemi (Serialization.spaceSep [
Serialization.cst "return",
(encodeExpression v0)])
Syntax.JumpStatementReturnVoid -> Serialization.withSemi (Serialization.cst "return")
Syntax.JumpStatementThrow v0 -> Serialization.withSemi (Serialization.spaceSep [
Serialization.cst "throw",
(encodeExpression v0)])
-- | Convert a labeled statement to an expression
encodeLabeledStatement :: Syntax.LabeledStatement -> Ast.Expr
encodeLabeledStatement ls =
let label = Syntax.labeledStatementLabel ls
stmt = Syntax.labeledStatementStatement ls
in (Serialization.newlineSep [
Serialization.cst (Strings.cat2 label ":"),
(encodeStatement stmt)])
-- | Convert a lambda expression to an expression
encodeLambdaExpression :: Syntax.LambdaExpression -> Ast.Expr
encodeLambdaExpression le =
let captures = Syntax.lambdaExpressionCaptures le
params = Syntax.lambdaExpressionParameters le
retType = Syntax.lambdaExpressionReturnType le
body = Syntax.lambdaExpressionBody le
in (Serialization.spaceSep [
encodeCaptureList captures,
(Logic.ifElse (Lists.null params) (Serialization.parens (Serialization.cst "")) (Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeParameter params)))),
(Maybes.maybe (Serialization.cst "") (\t -> Serialization.spaceSep [
Serialization.cst "->",
(encodeTypeExpression t)]) retType),
(encodeCompoundStatement body)])
-- | Convert a left shift operation to an expression
encodeLeftShiftOperation :: Syntax.LeftShiftOperation -> Ast.Expr
encodeLeftShiftOperation op =
let left = Syntax.leftShiftOperationLeft op
right = Syntax.leftShiftOperationRight op
in (Serialization.spaceSep [
encodeShiftExpression left,
(Serialization.cst "<<"),
(encodeAdditiveExpression right)])
-- | Convert a less-than-or-equal operation to an expression
encodeLessEqualOperation :: Syntax.LessEqualOperation -> Ast.Expr
encodeLessEqualOperation op =
let left = Syntax.lessEqualOperationLeft op
right = Syntax.lessEqualOperationRight op
in (Serialization.spaceSep [
encodeRelationalExpression left,
(Serialization.cst "<="),
(encodeShiftExpression right)])
-- | Convert a less-than operation to an expression
encodeLessOperation :: Syntax.LessOperation -> Ast.Expr
encodeLessOperation op =
let left = Syntax.lessOperationLeft op
right = Syntax.lessOperationRight op
in (Serialization.spaceSep [
encodeRelationalExpression left,
(Serialization.cst "<"),
(encodeShiftExpression right)])
-- | Convert a line directive to an expression
encodeLineDirective :: Syntax.LineDirective -> Ast.Expr
encodeLineDirective ld =
let lineNumber = Syntax.lineDirectiveLineNumber ld
filename = Syntax.lineDirectiveFilename ld
in (Serialization.spaceSep (Lists.concat [
[
Serialization.cst "#line",
(Serialization.cst (Literals.showInt32 lineNumber))],
(Maybes.maybe [] (\f -> [
Serialization.cst (Strings.cat [
"\"",
f,
"\""])]) filename)]))
-- | Convert a literal to an expression
encodeLiteral :: Syntax.Literal -> Ast.Expr
encodeLiteral l =
case l of
Syntax.LiteralInteger v0 -> encodeIntegerLiteral v0
Syntax.LiteralFloating v0 -> Serialization.cst (Literals.showBigfloat (Syntax.unFloatingLiteral v0))
Syntax.LiteralCharacter v0 -> Serialization.cst (Strings.cat [
"'",
(Syntax.unCharacterLiteral v0),
"'"])
Syntax.LiteralString v0 -> Serialization.cst (Strings.cat [
"\"",
(Syntax.unStringLiteral v0),
"\""])
Syntax.LiteralBoolean v0 -> encodeBooleanLiteral v0
Syntax.LiteralNull -> Serialization.cst "nullptr"
-- | Convert a logical and expression to an expression
encodeLogicalAndExpression :: Syntax.LogicalAndExpression -> Ast.Expr
encodeLogicalAndExpression e =
case e of
Syntax.LogicalAndExpressionInclusiveOr v0 -> encodeInclusiveOrExpression v0
Syntax.LogicalAndExpressionLogicalAnd v0 -> encodeLogicalAndOperation v0
-- | Convert a logical and operation to an expression
encodeLogicalAndOperation :: Syntax.LogicalAndOperation -> Ast.Expr
encodeLogicalAndOperation op =
let left = Syntax.logicalAndOperationLeft op
right = Syntax.logicalAndOperationRight op
in (Serialization.spaceSep [
encodeLogicalAndExpression left,
(Serialization.cst "&&"),
(encodeInclusiveOrExpression right)])
-- | Convert a logical or expression to an expression
encodeLogicalOrExpression :: Syntax.LogicalOrExpression -> Ast.Expr
encodeLogicalOrExpression e =
case e of
Syntax.LogicalOrExpressionLogicalAnd v0 -> encodeLogicalAndExpression v0
Syntax.LogicalOrExpressionLogicalOr v0 -> encodeLogicalOrOperation v0
-- | Convert a logical or operation to an expression
encodeLogicalOrOperation :: Syntax.LogicalOrOperation -> Ast.Expr
encodeLogicalOrOperation op =
let left = Syntax.logicalOrOperationLeft op
right = Syntax.logicalOrOperationRight op
in (Serialization.spaceSep [
encodeLogicalOrExpression left,
(Serialization.cst "||"),
(encodeLogicalAndExpression right)])
-- | Convert a map to an expression
encodeMap :: Syntax.Map -> Ast.Expr
encodeMap m =
let keyType = Syntax.mapKeyType m
valType = Syntax.mapValueType m
entries = Syntax.mapEntries m
in (Serialization.spaceSep [
Serialization.cst "std::map<",
(Serialization.commaSep Serialization.inlineStyle [
encodeTypeExpression keyType,
(encodeTypeExpression valType)]),
(Serialization.cst ">"),
(Serialization.curlyBracesList Nothing Serialization.inlineStyle (Lists.map encodeMapEntry entries))])
-- | Convert a map entry to an expression
encodeMapEntry :: Syntax.MapEntry -> Ast.Expr
encodeMapEntry me =
let key = Syntax.mapEntryKey me
val = Syntax.mapEntryValue me
in (Serialization.spaceSep [
Serialization.curlyBracesList Nothing Serialization.inlineStyle [
encodeExpression key],
(Serialization.cst "->"),
(encodeExpression val)])
-- | Convert a member initializer to an expression
encodeMemInitializer :: Syntax.MemInitializer -> Ast.Expr
encodeMemInitializer mi =
let name = Syntax.memInitializerName mi
args = Syntax.memInitializerArguments mi
in (Serialization.noSep [
Serialization.cst name,
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeExpression args)))])
-- | Convert a member access operation to an expression
encodeMemberAccessOperation :: Syntax.MemberAccessOperation -> Ast.Expr
encodeMemberAccessOperation mao =
let obj = Syntax.memberAccessOperationObject mao
member = Syntax.memberAccessOperationMember mao
in (Serialization.noSep [
encodePostfixExpression obj,
(Serialization.cst "."),
(Serialization.cst member)])
-- | Convert a member declaration to an expression
encodeMemberDeclaration :: Bool -> Syntax.MemberDeclaration -> Ast.Expr
encodeMemberDeclaration commas m =
case m of
Syntax.MemberDeclarationFunction v0 -> encodeFunctionDeclaration v0
Syntax.MemberDeclarationVariable v0 -> encodeVariableDeclaration commas v0
Syntax.MemberDeclarationConstructor v0 -> encodeConstructorDeclaration v0
Syntax.MemberDeclarationDestructor v0 -> encodeDestructorDeclaration v0
Syntax.MemberDeclarationNestedClass v0 -> encodeClassDeclaration v0
Syntax.MemberDeclarationTemplate v0 -> encodeTemplateDeclaration v0
-- | Convert a member specification to an expression
encodeMemberSpecification :: Bool -> Syntax.MemberSpecification -> Ast.Expr
encodeMemberSpecification commas m =
case m of
Syntax.MemberSpecificationAccessLabel v0 -> Serialization.noSep [
encodeAccessSpecifier v0,
(Serialization.cst ":")]
Syntax.MemberSpecificationMember v0 -> encodeMemberDeclaration commas v0
-- | Convert a modulo operation to an expression
encodeModuloOperation :: Syntax.ModuloOperation -> Ast.Expr
encodeModuloOperation op =
let left = Syntax.moduloOperationLeft op
right = Syntax.moduloOperationRight op
in (Serialization.spaceSep [
encodeMultiplicativeExpression left,
(Serialization.cst "%"),
(encodeUnaryExpression right)])
-- | Convert a multiplicative expression to an expression
encodeMultiplicativeExpression :: Syntax.MultiplicativeExpression -> Ast.Expr
encodeMultiplicativeExpression e =
case e of
Syntax.MultiplicativeExpressionUnary v0 -> encodeUnaryExpression v0
Syntax.MultiplicativeExpressionMultiply v0 -> encodeMultiplyOperation v0
Syntax.MultiplicativeExpressionDivide v0 -> encodeDivideOperation v0
Syntax.MultiplicativeExpressionModulo v0 -> encodeModuloOperation v0
-- | Convert a multiply operation to an expression
encodeMultiplyOperation :: Syntax.MultiplyOperation -> Ast.Expr
encodeMultiplyOperation op =
let left = Syntax.multiplyOperationLeft op
right = Syntax.multiplyOperationRight op
in (Serialization.spaceSep [
encodeMultiplicativeExpression left,
(Serialization.cst "*"),
(encodeUnaryExpression right)])
-- | Convert a namespace declaration to an expression
encodeNamespaceDeclaration :: Syntax.NamespaceDeclaration -> Ast.Expr
encodeNamespaceDeclaration nd =
let name = Syntax.namespaceDeclarationName nd
decls = Syntax.namespaceDeclarationDeclarations nd
in (Serialization.spaceSep [
Serialization.cst (Strings.cat2 "namespace " name),
(Serialization.curlyBlock Serialization.fullBlockStyle (Serialization.doubleNewlineSep (Lists.map encodeDeclaration decls)))])
-- | Convert a not-equal operation to an expression
encodeNotEqualOperation :: Syntax.NotEqualOperation -> Ast.Expr
encodeNotEqualOperation op =
let left = Syntax.notEqualOperationLeft op
right = Syntax.notEqualOperationRight op
in (Serialization.spaceSep [
encodeEqualityExpression left,
(Serialization.cst "!="),
(encodeRelationalExpression right)])
-- | Convert an optional to an expression
encodeOptional :: Syntax.Optional -> Ast.Expr
encodeOptional opt =
let valType = Syntax.optionalValueType opt
val = Syntax.optionalValue opt
in (Serialization.spaceSep [
Serialization.cst "std::optional<",
(encodeTypeExpression valType),
(Serialization.cst ">"),
(Maybes.maybe (Serialization.cst "{}") (\v -> Serialization.curlyBracesList Nothing Serialization.inlineStyle [
encodeExpression v]) val)])
-- | Convert overloaded lambdas to an expression
encodeOverloadedLambdas :: Syntax.OverloadedLambdas -> Ast.Expr
encodeOverloadedLambdas ol =
Serialization.spaceSep [
Serialization.cst "overloaded",
(Serialization.curlyBlock Serialization.fullBlockStyle (Serialization.newlineSep (Lists.map encodeLambdaExpression (Syntax.unOverloadedLambdas ol))))]
-- | Convert a parameter to an expression
encodeParameter :: Syntax.Parameter -> Ast.Expr
encodeParameter p =
let typ = Syntax.parameterType p
name = Syntax.parameterName p
unnamed = Syntax.parameterUnnamed p
defaultVal = Syntax.parameterDefaultValue p
nameExpr =
Serialization.cst (Logic.ifElse unnamed (Strings.cat [
"/*",
name,
"*/"]) name)
in (Serialization.spaceSep (Lists.concat [
[
encodeTypeExpression typ,
nameExpr],
(Maybes.maybe [] (\expr -> [
Serialization.cst "=",
(encodeExpression expr)]) defaultVal)]))
-- | Convert a pattern match to an expression
encodePatternMatch :: Syntax.PatternMatch -> Ast.Expr
encodePatternMatch pm =
let visitor = Syntax.patternMatchVisitor pm
variant = Syntax.patternMatchVariant pm
in (Serialization.spaceSep [
Serialization.cst "std::visit",
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle [
encodeVisitor visitor,
(encodeExpression variant)]))])
-- | Convert a pointer member access operation to an expression
encodePointerMemberAccessOperation :: Syntax.PointerMemberAccessOperation -> Ast.Expr
encodePointerMemberAccessOperation pmao =
let ptr = Syntax.pointerMemberAccessOperationPointer pmao
member = Syntax.pointerMemberAccessOperationMember pmao
in (Serialization.noSep [
encodePostfixExpression ptr,
(Serialization.cst "->"),
(Serialization.cst member)])
-- | Convert a postfix expression to an expression
encodePostfixExpression :: Syntax.PostfixExpression -> Ast.Expr
encodePostfixExpression e =
case e of
Syntax.PostfixExpressionPrimary v0 -> encodePrimaryExpression v0
Syntax.PostfixExpressionSubscript v0 -> encodeSubscriptOperation v0
Syntax.PostfixExpressionFunctionCall v0 -> encodeFunctionCallOperation v0
Syntax.PostfixExpressionTemplateFunctionCall v0 -> encodeTemplateFunctionCallOperation v0
Syntax.PostfixExpressionMemberAccess v0 -> encodeMemberAccessOperation v0
Syntax.PostfixExpressionPointerMemberAccess v0 -> encodePointerMemberAccessOperation v0
Syntax.PostfixExpressionPostIncrement v0 -> Serialization.noSep [
encodePostfixExpression v0,
(Serialization.cst "++")]
Syntax.PostfixExpressionPostDecrement v0 -> Serialization.noSep [
encodePostfixExpression v0,
(Serialization.cst "--")]
-- | Convert a pragma directive to an expression
encodePragmaDirective :: Syntax.PragmaDirective -> Ast.Expr
encodePragmaDirective pd = Serialization.cst (Strings.cat2 "#pragma " (Syntax.pragmaDirectiveContent pd))
-- | Convert a preprocessor directive to an expression
encodePreprocessorDirective :: Syntax.PreprocessorDirective -> Ast.Expr
encodePreprocessorDirective d =
case d of
Syntax.PreprocessorDirectiveInclude v0 -> encodeIncludeDirective v0
Syntax.PreprocessorDirectivePragma v0 -> encodePragmaDirective v0
Syntax.PreprocessorDirectiveDefine v0 -> encodeDefineDirective v0
Syntax.PreprocessorDirectiveUndef v0 -> encodeUndefDirective v0
Syntax.PreprocessorDirectiveIfdef v0 -> encodeIfdefDirective v0
Syntax.PreprocessorDirectiveIfndef v0 -> encodeIfndefDirective v0
Syntax.PreprocessorDirectiveIf v0 -> encodeIfDirective v0
Syntax.PreprocessorDirectiveElif v0 -> encodeElifDirective v0
Syntax.PreprocessorDirectiveElse v0 -> encodeElseDirective v0
Syntax.PreprocessorDirectiveEndif v0 -> encodeEndifDirective v0
Syntax.PreprocessorDirectiveLine v0 -> encodeLineDirective v0
Syntax.PreprocessorDirectiveError v0 -> encodeErrorDirective v0
Syntax.PreprocessorDirectiveWarning v0 -> encodeWarningDirective v0
-- | Convert a primary expression to an expression
encodePrimaryExpression :: Syntax.PrimaryExpression -> Ast.Expr
encodePrimaryExpression e =
case e of
Syntax.PrimaryExpressionIdentifier v0 -> Serialization.cst v0
Syntax.PrimaryExpressionLiteral v0 -> encodeLiteral v0
Syntax.PrimaryExpressionParenthesized v0 -> Serialization.parens (encodeExpression v0)
Syntax.PrimaryExpressionLambda v0 -> encodeLambdaExpression v0
-- | Convert a program to an expression
encodeProgram :: Syntax.Program -> Ast.Expr
encodeProgram prog =
let preps = Syntax.programPreprocessorDirectives prog
includes = Syntax.programIncludes prog
decls = Syntax.programDeclarations prog
separate = \sep -> \defs -> Logic.ifElse (Lists.null defs) Nothing (Just (sep defs))
in (Serialization.doubleNewlineSep (Maybes.cat [
separate Serialization.newlineSep (Lists.map encodePreprocessorDirective preps),
(separate Serialization.newlineSep (Lists.map encodeIncludeDirective includes)),
(separate Serialization.doubleNewlineSep (Lists.map encodeDeclaration decls))]))
-- | Convert a qualified identifier to an expression
encodeQualifiedIdentifier :: Syntax.QualifiedIdentifier -> Ast.Expr
encodeQualifiedIdentifier qi =
let ns = Syntax.qualifiedIdentifierNamespace qi
name = Syntax.qualifiedIdentifierName qi
in (Serialization.cst (Strings.cat [
ns,
"::",
name]))
-- | Convert a qualified type to an expression
encodeQualifiedType :: Syntax.QualifiedType -> Ast.Expr
encodeQualifiedType qt =
let baseType = Syntax.qualifiedTypeBaseType qt
qualifier = Syntax.qualifiedTypeQualifier qt
in case qualifier of
Syntax.TypeQualifierConst -> Serialization.spaceSep [
Serialization.cst "const",
(encodeTypeExpression baseType)]
Syntax.TypeQualifierLvalueRef -> Serialization.noSep [
encodeTypeExpression baseType,
(Serialization.cst "&")]
Syntax.TypeQualifierRvalueRef -> Serialization.noSep [
encodeTypeExpression baseType,
(Serialization.cst "&&")]
Syntax.TypeQualifierPointer -> Serialization.noSep [
encodeTypeExpression baseType,
(Serialization.cst "*")]
-- | Convert a range-for statement to an expression
encodeRangeForStatement :: Syntax.RangeForStatement -> Ast.Expr
encodeRangeForStatement rfs =
let typ = Syntax.rangeForStatementType rfs
var = Syntax.rangeForStatementVariable rfs
range = Syntax.rangeForStatementRange rfs
body = Syntax.rangeForStatementBody rfs
in (Serialization.newlineSep [
Serialization.spaceSep [
Serialization.cst "for",
(Serialization.parens (Serialization.spaceSep [
encodeTypeExpression typ,
(Serialization.cst var),
(Serialization.cst ":"),
(encodeExpression range)]))],
(encodeStatement body)])
-- | Convert a relational expression to an expression
encodeRelationalExpression :: Syntax.RelationalExpression -> Ast.Expr
encodeRelationalExpression e =
case e of
Syntax.RelationalExpressionShift v0 -> encodeShiftExpression v0
Syntax.RelationalExpressionLess v0 -> encodeLessOperation v0
Syntax.RelationalExpressionGreater v0 -> encodeGreaterOperation v0
Syntax.RelationalExpressionLessEqual v0 -> encodeLessEqualOperation v0
Syntax.RelationalExpressionGreaterEqual v0 -> encodeGreaterEqualOperation v0
-- | Convert a right shift operation to an expression
encodeRightShiftOperation :: Syntax.RightShiftOperation -> Ast.Expr
encodeRightShiftOperation op =
let left = Syntax.rightShiftOperationLeft op
right = Syntax.rightShiftOperationRight op
in (Serialization.spaceSep [
encodeShiftExpression left,
(Serialization.cst ">>"),
(encodeAdditiveExpression right)])
-- | Convert a selection statement to an expression
encodeSelectionStatement :: Syntax.SelectionStatement -> Ast.Expr
encodeSelectionStatement ss =
let cond = Syntax.selectionStatementCondition ss
thenBranch = Syntax.selectionStatementThenBranch ss
elseBranch = Syntax.selectionStatementElseBranch ss
in (Serialization.newlineSep [
Serialization.spaceSep [
Serialization.cst "if",
(Serialization.parens (encodeExpression cond))],
(encodeStatement thenBranch),
(Maybes.maybe (Serialization.cst "") (\stmt -> Serialization.newlineSep [
Serialization.cst "else",
(encodeStatement stmt)]) elseBranch)])
-- | Convert a set to an expression
encodeSet :: Syntax.Set -> Ast.Expr
encodeSet s =
let elemType = Syntax.setElementType s
elems = Syntax.setElements s
in (Serialization.spaceSep [
Serialization.cst "std::set<",
(encodeTypeExpression elemType),
(Serialization.cst ">"),
(Serialization.curlyBracesList Nothing Serialization.inlineStyle (Lists.map encodeExpression elems))])
-- | Convert a shift expression to an expression
encodeShiftExpression :: Syntax.ShiftExpression -> Ast.Expr
encodeShiftExpression e =
case e of
Syntax.ShiftExpressionAdditive v0 -> encodeAdditiveExpression v0
Syntax.ShiftExpressionLeftShift v0 -> encodeLeftShiftOperation v0
Syntax.ShiftExpressionRightShift v0 -> encodeRightShiftOperation v0
-- | Convert a sizeof expression to an expression
encodeSizeofExpression :: Syntax.SizeofExpression -> Ast.Expr
encodeSizeofExpression se =
Serialization.spaceSep [
Serialization.cst "sizeof",
(Serialization.parens (encodeTypeExpression (Syntax.unSizeofExpression se)))]
-- | Convert a statement to an expression
encodeStatement :: Syntax.Statement -> Ast.Expr
encodeStatement s =
case s of
Syntax.StatementLabeled v0 -> encodeLabeledStatement v0
Syntax.StatementCompound v0 -> encodeCompoundStatement v0
Syntax.StatementSelection v0 -> encodeSelectionStatement v0
Syntax.StatementSwitch v0 -> encodeSwitchStatement v0
Syntax.StatementIteration v0 -> encodeIterationStatement v0
Syntax.StatementJump v0 -> encodeJumpStatement v0
Syntax.StatementDeclaration v0 -> Serialization.withSemi (encodeVariableDeclaration False v0)
Syntax.StatementExpression v0 -> Serialization.withSemi (encodeExpression v0)
-- | Convert a subscript operation to an expression
encodeSubscriptOperation :: Syntax.SubscriptOperation -> Ast.Expr
encodeSubscriptOperation so =
let array = Syntax.subscriptOperationArray so
index = Syntax.subscriptOperationIndex so
in (Serialization.noSep [
encodePostfixExpression array,
(Serialization.cst "["),
(encodeExpression index),
(Serialization.cst "]")])
-- | Convert a subtract operation to an expression
encodeSubtractOperation :: Syntax.SubtractOperation -> Ast.Expr
encodeSubtractOperation op =
let left = Syntax.subtractOperationLeft op
right = Syntax.subtractOperationRight op
in (Serialization.spaceSep [
encodeAdditiveExpression left,
(Serialization.cst "-"),
(encodeMultiplicativeExpression right)])
-- | Convert a switch statement to an expression
encodeSwitchStatement :: Syntax.SwitchStatement -> Ast.Expr
encodeSwitchStatement ss =
let value = Syntax.switchStatementValue ss
cases = Syntax.switchStatementCases ss
in (Serialization.spaceSep [
Serialization.cst "switch",
(Serialization.parens (encodeExpression value)),
(Serialization.curlyBlock Serialization.fullBlockStyle (Serialization.newlineSep (Lists.map encodeCaseStatement cases)))])
-- | Convert a template argument to an expression
encodeTemplateArgument :: Syntax.TemplateArgument -> Ast.Expr
encodeTemplateArgument a =
case a of
Syntax.TemplateArgumentType v0 -> encodeTypeExpression v0
Syntax.TemplateArgumentValue v0 -> encodeExpression v0
-- | Convert a template declaration to an expression
encodeTemplateDeclaration :: Syntax.TemplateDeclaration -> Ast.Expr
encodeTemplateDeclaration td =
let inline = Syntax.templateDeclarationInline td
params = Syntax.templateDeclarationParameters td
declaration = Syntax.templateDeclarationDeclaration td
sep = Logic.ifElse inline Serialization.spaceSep Serialization.newlineSep
in (sep [
Serialization.noSep [
Serialization.cst "template",
(Serialization.angleBracesList Serialization.inlineStyle (Lists.map (\p -> Serialization.cst p) params))],
(encodeDeclaration declaration)])
-- | Convert a template function call operation to an expression
encodeTemplateFunctionCallOperation :: Syntax.TemplateFunctionCallOperation -> Ast.Expr
encodeTemplateFunctionCallOperation tfco =
let func = Syntax.templateFunctionCallOperationFunction tfco
templateArgs = Syntax.templateFunctionCallOperationTemplateArguments tfco
args = Syntax.templateFunctionCallOperationArguments tfco
in (Serialization.noSep [
encodePostfixExpression func,
(Serialization.angleBracesList Serialization.inlineStyle (Lists.map encodeTemplateArgument templateArgs)),
(Serialization.parens (Serialization.commaSep Serialization.inlineStyle (Lists.map encodeExpression args)))])
-- | Convert a template type to an expression
encodeTemplateType :: Syntax.TemplateType -> Ast.Expr
encodeTemplateType tt =
let name = Syntax.templateTypeName tt
args = Syntax.templateTypeArguments tt
in (Serialization.noSep [
Serialization.cst name,
(Serialization.angleBracesList Serialization.inlineStyle (Lists.map encodeTemplateArgument args))])
-- | Convert a ternary expression to an expression
encodeTernaryExpression :: Syntax.TernaryExpression -> Ast.Expr
encodeTernaryExpression te =
let cond = Syntax.ternaryExpressionCondition te
trueExpr = Syntax.ternaryExpressionTrueExpr te
falseExpr = Syntax.ternaryExpressionFalseExpr te
in (Serialization.spaceSep [
encodeLogicalOrExpression cond,
(Serialization.cst "?"),
(encodeExpression trueExpr),
(Serialization.cst ":"),
(encodeConditionalExpression falseExpr)])
-- | Convert a type expression to an expression
encodeTypeExpression :: Syntax.TypeExpression -> Ast.Expr
encodeTypeExpression t =
case t of
Syntax.TypeExpressionBasic v0 -> encodeBasicType v0
Syntax.TypeExpressionQualified v0 -> encodeQualifiedType v0
Syntax.TypeExpressionTemplate v0 -> encodeTemplateType v0
Syntax.TypeExpressionFunction v0 -> encodeFunctionType v0
Syntax.TypeExpressionAuto -> Serialization.cst "auto"
-- | Convert a typedef declaration to an expression
encodeTypedefDeclaration :: Syntax.TypedefDeclaration -> Ast.Expr
encodeTypedefDeclaration td =
let name = Syntax.typedefDeclarationName td
typ = Syntax.typedefDeclarationType td
isUsing = Syntax.typedefDeclarationIsUsing td
in (Logic.ifElse isUsing (Serialization.withSemi (Serialization.spaceSep [
Serialization.cst (Strings.cat2 "using " name),
(Serialization.cst "="),
(encodeTypeExpression typ)])) (Serialization.withSemi (Serialization.spaceSep [
Serialization.cst "typedef",
(encodeTypeExpression typ),
(Serialization.cst name)])))
-- | Convert a unary expression to an expression
encodeUnaryExpression :: Syntax.UnaryExpression -> Ast.Expr
encodeUnaryExpression e =
case e of
Syntax.UnaryExpressionPostfix v0 -> encodePostfixExpression v0
Syntax.UnaryExpressionUnaryOp v0 -> encodeUnaryOperation v0
Syntax.UnaryExpressionSizeof v0 -> encodeSizeofExpression v0
-- | Convert a unary operation to an expression
encodeUnaryOperation :: Syntax.UnaryOperation -> Ast.Expr
encodeUnaryOperation uo =
let op = Syntax.unaryOperationOperator uo
operand = Syntax.unaryOperationOperand uo
in (Serialization.spaceSep [
encodeUnaryOperator op,
(encodeUnaryExpression operand)])
-- | Convert a unary operator to an expression
encodeUnaryOperator :: Syntax.UnaryOperator -> Ast.Expr
encodeUnaryOperator op =
case op of
Syntax.UnaryOperatorPlus -> Serialization.cst "+"
Syntax.UnaryOperatorMinus -> Serialization.cst "-"
Syntax.UnaryOperatorLogicalNot -> Serialization.cst "!"
Syntax.UnaryOperatorBitwiseNot -> Serialization.cst "~"
Syntax.UnaryOperatorDereference -> Serialization.cst "*"
Syntax.UnaryOperatorAddressOf -> Serialization.cst "&"
Syntax.UnaryOperatorPreIncrement -> Serialization.cst "++"
Syntax.UnaryOperatorPreDecrement -> Serialization.cst "--"
-- | Convert an undef directive to an expression
encodeUndefDirective :: Syntax.UndefDirective -> Ast.Expr
encodeUndefDirective ud =
Serialization.spaceSep [
Serialization.cst "#undef",
(Serialization.cst (Syntax.undefDirectiveName ud))]
-- | Convert a variable declaration to an expression
encodeVariableDeclaration :: Bool -> Syntax.VariableDeclaration -> Ast.Expr
encodeVariableDeclaration commas vd =
let typ = Syntax.variableDeclarationType vd
name = Syntax.variableDeclarationName vd
init = Syntax.variableDeclarationInitializer vd
isAuto = Syntax.variableDeclarationIsAuto vd
terminator = Logic.ifElse commas Serialization.withComma Serialization.withSemi
in (terminator (Serialization.spaceSep (Lists.concat [
Logic.ifElse isAuto [
Serialization.cst "auto"] (Maybes.maybe [] (\t -> [
encodeTypeExpression t]) typ),
[
Serialization.cst name],
(Maybes.maybe [] (\expr -> [
Serialization.cst "=",
(encodeExpression expr)]) init)])))
-- | Convert a vector to an expression
encodeVector :: Syntax.Vector -> Ast.Expr
encodeVector v =
let elemType = Syntax.vectorElementType v
elems = Syntax.vectorElements v
in (Serialization.spaceSep [
Serialization.cst "std::vector<",
(encodeTypeExpression elemType),
(Serialization.cst ">"),
(Serialization.curlyBracesList Nothing Serialization.inlineStyle (Lists.map encodeExpression elems))])
-- | Convert a visitor to an expression
encodeVisitor :: Syntax.Visitor -> Ast.Expr
encodeVisitor v =
case v of
Syntax.VisitorLambda v0 -> encodeLambdaExpression v0
Syntax.VisitorOverloaded v0 -> encodeOverloadedLambdas v0
-- | Convert a warning directive to an expression
encodeWarningDirective :: Syntax.WarningDirective -> Ast.Expr
encodeWarningDirective wd =
Serialization.spaceSep [
Serialization.cst "#warning",
(Serialization.cst (Syntax.warningDirectiveMessage wd))]
-- | Convert a while statement to an expression
encodeWhileStatement :: Syntax.WhileStatement -> Ast.Expr
encodeWhileStatement ws =
let cond = Syntax.whileStatementCondition ws
body = Syntax.whileStatementBody ws
in (Serialization.newlineSep [
Serialization.spaceSep [
Serialization.cst "while",
(Serialization.parens (encodeExpression cond))],
(encodeStatement body)])
-- | Convert a string to a C++ comment
toCppComments :: String -> Bool -> String
toCppComments s isMultiline =
Logic.ifElse isMultiline (Strings.cat [
"/* ",
s,
" */"]) (Strings.cat2 "// " s)