hydra-lisp-0.17.2: src/main/haskell/Hydra/Lisp/Serde.hs
-- Note: this is an automatically generated file. Do not edit.
-- | Lisp serializer: converts Lisp AST to concrete syntax for Clojure, Emacs Lisp, Common Lisp, or Scheme
module Hydra.Lisp.Serde where
import qualified Hydra.Ast as Ast
import qualified Hydra.Coders as Coders
import qualified Hydra.Constants as Constants
import qualified Hydra.Core as Core
import qualified Hydra.Docs as Docs
import qualified Hydra.Error.Checking as Checking
import qualified Hydra.Error.Core as ErrorCore
import qualified Hydra.Error.File as ErrorFile
import qualified Hydra.Error.Packaging as ErrorPackaging
import qualified Hydra.Error.System as ErrorSystem
import qualified Hydra.Errors as Errors
import qualified Hydra.File as File
import qualified Hydra.Formatting as Formatting
import qualified Hydra.Graph as Graph
import qualified Hydra.Json.Model as Model
import qualified Hydra.Overlay.Haskell.Lib.Equality as Equality
import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
import qualified Hydra.Overlay.Haskell.Lib.Literals as Literals
import qualified Hydra.Overlay.Haskell.Lib.Logic as Logic
import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals
import qualified Hydra.Overlay.Haskell.Lib.Pairs as Pairs
import qualified Hydra.Overlay.Haskell.Lib.Strings as Strings
import qualified Hydra.Lisp.Syntax as Syntax
import qualified Hydra.Packaging as Packaging
import qualified Hydra.Parsing as Parsing
import qualified Hydra.Paths as Paths
import qualified Hydra.Query as Query
import qualified Hydra.Regex as Regex
import qualified Hydra.Relational as Relational
import qualified Hydra.Serialization as Serialization
import qualified Hydra.System as System
import qualified Hydra.Tabular as Tabular
import qualified Hydra.Testing as Testing
import qualified Hydra.Time as Time
import qualified Hydra.Topology as Topology
import qualified Hydra.Typed as Typed
import qualified Hydra.Typing as Typing
import qualified Hydra.Util as Util
import qualified Hydra.Validation as Validation
import qualified Hydra.Variants as Variants
import Prelude hiding (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
import qualified Data.Scientific as Sci
-- | Serialize an and expression: (and expr1 expr2 ...)
andExpressionToExpr :: Syntax.Dialect -> Syntax.AndExpression -> Ast.Expr
andExpressionToExpr d andExpr =
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "and"] (Lists.map (expressionToExpr d) (Syntax.andExpressionExpressions andExpr))))
-- | Serialize a function application, using funcall for computed function positions in Lisp-2 dialects
applicationToExpr :: Syntax.Dialect -> Syntax.Application -> Ast.Expr
applicationToExpr d app =
let funExpr = Syntax.applicationFunction app
fun = expressionToExpr d funExpr
args = Lists.map (expressionToExpr d) (Syntax.applicationArguments app)
funcallWhenComputed =
case funExpr of
Syntax.ExpressionVariable _ -> False
_ -> True
needsFuncall =
case d of
Syntax.DialectCommonLisp -> funcallWhenComputed
Syntax.DialectEmacsLisp -> funcallWhenComputed
_ -> False
allParts =
Logic.ifElse needsFuncall (Lists.concat2 [
Serialization.cst "funcall",
fun] args) (Lists.concat2 [
fun] args)
in (Serialization.parens (Serialization.spaceSepAdaptive allParts))
-- | Serialize a case expression
caseExpressionToExpr :: Syntax.Dialect -> Syntax.CaseExpression -> Ast.Expr
caseExpressionToExpr d caseExpr =
let scrutinee = expressionToExpr d (Syntax.caseExpressionScrutinee caseExpr)
clauses = Syntax.caseExpressionClauses caseExpr
dflt = Syntax.caseExpressionDefault caseExpr
clauseExprs =
Lists.map (\c -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.parens (Serialization.spaceSepAdaptive (Lists.map (expressionToExpr d) (Syntax.caseClauseKeys c))),
(expressionToExpr d (Syntax.caseClauseBody c))])) clauses
defaultPart =
Optionals.cases dflt [] (\e -> [
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "else",
(expressionToExpr d e)])])
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "case",
scrutinee],
clauseExprs,
defaultPart])))
-- | Serialize a comment
commentToExpr :: Syntax.Comment -> Ast.Expr
commentToExpr c =
let text = Syntax.commentText c
in (Serialization.cst (Logic.ifElse (Equality.equal text "") ";" (Strings.cat2 "; " text)))
-- | Serialize a cond expression
condExpressionToExpr :: Syntax.Dialect -> Syntax.CondExpression -> Ast.Expr
condExpressionToExpr d condExpr =
let clauses = Syntax.condExpressionClauses condExpr
dflt = Syntax.condExpressionDefault condExpr
in case d of
Syntax.DialectClojure ->
let clauseExprs =
Lists.concat (Lists.map (\c -> [
expressionToExpr d (Syntax.condClauseCondition c),
(expressionToExpr d (Syntax.condClauseBody c))]) clauses)
defaultPart =
Optionals.cases dflt [] (\e -> [
Serialization.cst ":else",
(expressionToExpr d e)])
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "cond"],
clauseExprs,
defaultPart])))
Syntax.DialectEmacsLisp ->
let clauseExprs =
Lists.map (\c -> Serialization.parens (Serialization.spaceSepAdaptive [
expressionToExpr d (Syntax.condClauseCondition c),
(expressionToExpr d (Syntax.condClauseBody c))])) clauses
defaultPart =
Optionals.cases dflt [] (\e -> [
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "t",
(expressionToExpr d e)])])
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "cond"],
clauseExprs,
defaultPart])))
Syntax.DialectCommonLisp ->
let clauseExprs =
Lists.map (\c -> Serialization.parens (Serialization.spaceSepAdaptive [
expressionToExpr d (Syntax.condClauseCondition c),
(expressionToExpr d (Syntax.condClauseBody c))])) clauses
defaultPart =
Optionals.cases dflt [] (\e -> [
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "t",
(expressionToExpr d e)])])
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "cond"],
clauseExprs,
defaultPart])))
Syntax.DialectScheme ->
let clauseExprs =
Lists.map (\c -> Serialization.parens (Serialization.spaceSepAdaptive [
expressionToExpr d (Syntax.condClauseCondition c),
(expressionToExpr d (Syntax.condClauseBody c))])) clauses
defaultPart =
Optionals.cases dflt [] (\e -> [
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "else",
(expressionToExpr d e)])])
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "cond"],
clauseExprs,
defaultPart])))
-- | Serialize a constant definition
constantDefinitionToExpr :: Syntax.Dialect -> Syntax.ConstantDefinition -> Ast.Expr
constantDefinitionToExpr d cdef =
let name = symbolToExpr (Syntax.constantDefinitionName cdef)
value = expressionToExpr d (Syntax.constantDefinitionValue cdef)
in (Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst (defconstKeyword d),
name,
value]))
-- | The keyword for variable definitions
defKeyword :: Syntax.Dialect -> String
defKeyword d =
case d of
Syntax.DialectClojure -> "def"
Syntax.DialectEmacsLisp -> "defvar"
Syntax.DialectCommonLisp -> "cl:defvar"
Syntax.DialectScheme -> "define"
-- | The keyword for constant definitions
defconstKeyword :: Syntax.Dialect -> String
defconstKeyword d =
case d of
Syntax.DialectClojure -> "def"
Syntax.DialectEmacsLisp -> "defconst"
Syntax.DialectCommonLisp -> "cl:defconstant"
Syntax.DialectScheme -> "define"
-- | The keyword for named function definitions
defnKeyword :: Syntax.Dialect -> String
defnKeyword d =
case d of
Syntax.DialectClojure -> "defn"
Syntax.DialectEmacsLisp -> "defun"
Syntax.DialectCommonLisp -> "cl:defun"
Syntax.DialectScheme -> "define"
-- | The keyword for record/struct definitions
defrecordKeyword :: Syntax.Dialect -> String
defrecordKeyword d =
case d of
Syntax.DialectClojure -> "defrecord"
Syntax.DialectEmacsLisp -> "cl-defstruct"
Syntax.DialectCommonLisp -> "cl:defstruct"
Syntax.DialectScheme -> "define-record-type"
-- | Serialize a do/progn/begin expression
doExpressionToExpr :: Syntax.Dialect -> Syntax.DoExpression -> Ast.Expr
doExpressionToExpr d doExpr =
let kw =
case d of
Syntax.DialectClojure -> "do"
Syntax.DialectEmacsLisp -> "progn"
Syntax.DialectCommonLisp -> "progn"
Syntax.DialectScheme -> "begin"
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst kw] (Lists.map (expressionToExpr d) (Syntax.doExpressionExpressions doExpr)))))
-- | Serialize a docstring as a comment
docstringToExpr :: Syntax.Docstring -> Ast.Expr
docstringToExpr ds =
let text = Syntax.unDocstring ds
in (Serialization.cst (Logic.ifElse (Equality.equal text "") ";;" (Strings.cat [
";; ",
text])))
-- | Serialize an export declaration
exportDeclarationToExpr :: Syntax.Dialect -> Syntax.ExportDeclaration -> Ast.Expr
exportDeclarationToExpr d edecl =
let syms = Lists.map symbolToExpr (Syntax.exportDeclarationSymbols edecl)
in case d of
Syntax.DialectClojure -> Serialization.cst ""
Syntax.DialectEmacsLisp -> Serialization.newlineSep (Lists.map (\s -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "provide",
(Serialization.noSep [
Serialization.cst "'",
s])])) syms)
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst ":export"] (Lists.map (\s -> Serialization.noSep [
Serialization.cst ":",
s]) syms)))
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "export"] syms))
-- | Serialize a Lisp expression
expressionToExpr :: Syntax.Dialect -> Syntax.Expression -> Ast.Expr
expressionToExpr d expr =
case expr of
Syntax.ExpressionApplication v0 -> applicationToExpr d v0
Syntax.ExpressionLambda v0 -> lambdaToExpr d v0
Syntax.ExpressionLet v0 -> letExpressionToExpr d v0
Syntax.ExpressionIf v0 -> ifExpressionToExpr d v0
Syntax.ExpressionCond v0 -> condExpressionToExpr d v0
Syntax.ExpressionCase v0 -> caseExpressionToExpr d v0
Syntax.ExpressionAnd v0 -> andExpressionToExpr d v0
Syntax.ExpressionOr v0 -> orExpressionToExpr d v0
Syntax.ExpressionNot v0 -> notExpressionToExpr d v0
Syntax.ExpressionDo v0 -> doExpressionToExpr d v0
Syntax.ExpressionBegin v0 -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "begin"] (Lists.map (expressionToExpr d) (Syntax.beginExpressionExpressions v0))))
Syntax.ExpressionVariable v0 -> variableReferenceToExpr d v0
Syntax.ExpressionLiteral v0 -> literalToExpr d v0
Syntax.ExpressionList v0 -> listLiteralToExpr d v0
Syntax.ExpressionVector v0 -> vectorLiteralToExpr d v0
Syntax.ExpressionMap v0 -> mapLiteralToExpr d v0
Syntax.ExpressionSet v0 -> setLiteralToExpr d v0
Syntax.ExpressionCons v0 -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "cons",
(expressionToExpr d (Syntax.consExpressionHead v0)),
(expressionToExpr d (Syntax.consExpressionTail v0))])
Syntax.ExpressionDottedPair v0 -> Serialization.parens (Serialization.spaceSepAdaptive [
expressionToExpr d (Syntax.dottedPairCar v0),
(Serialization.cst "."),
(expressionToExpr d (Syntax.dottedPairCdr v0))])
Syntax.ExpressionFieldAccess v0 -> fieldAccessToExpr d v0
Syntax.ExpressionTypeAnnotation v0 -> expressionToExpr d (Syntax.typeAnnotationExpression v0)
Syntax.ExpressionQuote v0 -> Serialization.noSep [
Serialization.cst "'",
(expressionToExpr d (Syntax.quoteExpressionBody v0))]
Syntax.ExpressionQuasiquote v0 -> Serialization.noSep [
Serialization.cst "`",
(expressionToExpr d (Syntax.quasiquoteExpressionBody v0))]
Syntax.ExpressionUnquote v0 -> case d of
Syntax.DialectClojure -> Serialization.noSep [
Serialization.cst "~",
(expressionToExpr d (Syntax.unquoteExpressionBody v0))]
Syntax.DialectEmacsLisp -> Serialization.noSep [
Serialization.cst ",",
(expressionToExpr d (Syntax.unquoteExpressionBody v0))]
Syntax.DialectCommonLisp -> Serialization.noSep [
Serialization.cst ",",
(expressionToExpr d (Syntax.unquoteExpressionBody v0))]
Syntax.DialectScheme -> Serialization.noSep [
Serialization.cst ",",
(expressionToExpr d (Syntax.unquoteExpressionBody v0))]
Syntax.ExpressionSplicingUnquote v0 -> case d of
Syntax.DialectClojure -> Serialization.noSep [
Serialization.cst "~@",
(expressionToExpr d (Syntax.splicingUnquoteExpressionBody v0))]
Syntax.DialectEmacsLisp -> Serialization.noSep [
Serialization.cst ",@",
(expressionToExpr d (Syntax.splicingUnquoteExpressionBody v0))]
Syntax.DialectCommonLisp -> Serialization.noSep [
Serialization.cst ",@",
(expressionToExpr d (Syntax.splicingUnquoteExpressionBody v0))]
Syntax.DialectScheme -> Serialization.noSep [
Serialization.cst ",@",
(expressionToExpr d (Syntax.splicingUnquoteExpressionBody v0))]
Syntax.ExpressionSExpression v0 -> sExpressionToExpr v0
-- | The boolean false expression
falseExpr :: Syntax.Dialect -> Ast.Expr
falseExpr d =
case d of
Syntax.DialectClojure -> Serialization.cst "false"
Syntax.DialectEmacsLisp -> Serialization.cst "nil"
Syntax.DialectCommonLisp -> Serialization.cst "cl:nil"
Syntax.DialectScheme -> Serialization.cst "#f"
-- | Serialize a field access expression
fieldAccessToExpr :: Syntax.Dialect -> Syntax.FieldAccess -> Ast.Expr
fieldAccessToExpr d fa =
let rtype = symbolToExpr (Syntax.fieldAccessRecordType fa)
field = symbolToExpr (Syntax.fieldAccessField fa)
target = expressionToExpr d (Syntax.fieldAccessTarget fa)
in case d of
Syntax.DialectClojure -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.noSep [
Serialization.cst ":",
field],
target])
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.noSep [
rtype,
(Serialization.cst "-"),
field],
target])
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.noSep [
rtype,
(Serialization.cst "-"),
field],
target])
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.noSep [
rtype,
(Serialization.cst "-"),
field],
target])
-- | Format a float64 value as a dialect-specific literal string, including special values like NaN and infinities
formatLispFloat :: Syntax.Dialect -> Double -> String
formatLispFloat d v =
let s = Literals.showFloat64 v
in (Logic.ifElse (Equality.equal s "NaN") (case d of
Syntax.DialectClojure -> "Double/NaN"
Syntax.DialectScheme -> "+nan.0"
Syntax.DialectCommonLisp -> "+hydra-nan+"
Syntax.DialectEmacsLisp -> "0.0e+NaN") (Logic.ifElse (Equality.equal s "Infinity") (case d of
Syntax.DialectClojure -> "Double/POSITIVE_INFINITY"
Syntax.DialectScheme -> "+inf.0"
Syntax.DialectCommonLisp -> "+hydra-pos-inf+"
Syntax.DialectEmacsLisp -> "1.0e+INF") (Logic.ifElse (Equality.equal s "-Infinity") (case d of
Syntax.DialectClojure -> "Double/NEGATIVE_INFINITY"
Syntax.DialectScheme -> "-inf.0"
Syntax.DialectCommonLisp -> "+hydra-neg-inf+"
Syntax.DialectEmacsLisp -> "-1.0e+INF") s)))
-- | Serialize a function definition
functionDefinitionToExpr :: Syntax.Dialect -> Syntax.FunctionDefinition -> Ast.Expr
functionDefinitionToExpr d fdef =
let name = symbolToExpr (Syntax.functionDefinitionName fdef)
params = Lists.map symbolToExpr (Syntax.functionDefinitionParams fdef)
body = Lists.map (expressionToExpr d) (Syntax.functionDefinitionBody fdef)
in case d of
Syntax.DialectClojure -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defn",
name],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep params)],
body]))
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defun",
name],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defun",
name],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "define"],
[
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
name] params))],
body]))
-- | Serialize an if expression: (if test then else)
ifExpressionToExpr :: Syntax.Dialect -> Syntax.IfExpression -> Ast.Expr
ifExpressionToExpr d ifExpr =
let cond = expressionToExpr d (Syntax.ifExpressionCondition ifExpr)
then_ = expressionToExpr d (Syntax.ifExpressionThen ifExpr)
else_ = Syntax.ifExpressionElse ifExpr
elsePart = Optionals.cases else_ [] (\e -> [
expressionToExpr d e])
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "if",
cond,
then_],
elsePart])))
-- | Serialize an import declaration
importDeclarationToExpr :: Syntax.Dialect -> Syntax.ImportDeclaration -> Ast.Expr
importDeclarationToExpr d idecl =
let modName = Syntax.unNamespaceName (Syntax.importDeclarationModule idecl)
in case d of
Syntax.DialectClojure -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst ":require",
(Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep [
Serialization.cst modName]))])
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "require",
(Serialization.noSep [
Serialization.cst "'",
(Serialization.cst modName)])])
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst ":use",
(Serialization.cst (Strings.cat2 ":" modName))])
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "import",
(Serialization.parens (Serialization.cst modName))])
-- | Serialize a keyword
keywordToExpr :: Syntax.Dialect -> Syntax.Keyword -> Ast.Expr
keywordToExpr d k =
let name = Syntax.keywordName k
ns = Syntax.keywordNamespace k
in case d of
Syntax.DialectScheme -> Serialization.noSep [
Serialization.cst "'",
(Serialization.cst name)]
_ -> Serialization.cst (Optionals.cases ns (Strings.cat2 ":" name) (\n -> Strings.cat [
n,
"/:",
name]))
-- | The keyword for anonymous functions
lambdaKeyword :: Syntax.Dialect -> String
lambdaKeyword d =
case d of
Syntax.DialectClojure -> "fn"
Syntax.DialectEmacsLisp -> "lambda"
Syntax.DialectCommonLisp -> "cl:lambda"
Syntax.DialectScheme -> "lambda"
-- | Serialize a lambda expression
lambdaToExpr :: Syntax.Dialect -> Syntax.Lambda -> Ast.Expr
lambdaToExpr d lam =
let params = Lists.map symbolToExpr (Syntax.lambdaParams lam)
body = Lists.map (expressionToExpr d) (Syntax.lambdaBody lam)
mname = Syntax.lambdaName lam
kw = lambdaKeyword d
in case d of
Syntax.DialectClojure -> Optionals.cases mname (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep params)],
body]))) (\sym -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw,
(symbolToExpr sym)],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep params)],
body])))
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
-- | Serialize a let expression
letExpressionToExpr :: Syntax.Dialect -> Syntax.LetExpression -> Ast.Expr
letExpressionToExpr d letExpr =
let kind = Syntax.letExpressionKind letExpr
bindings = Syntax.letExpressionBindings letExpr
body = Lists.map (expressionToExpr d) (Syntax.letExpressionBody letExpr)
bindingPairs =
Lists.map (\b -> case b of
Syntax.LetBindingSimple v0 -> (symbolToExpr (Syntax.simpleBindingName v0), (expressionToExpr d (Syntax.simpleBindingValue v0)))
Syntax.LetBindingDestructuring _ -> (Serialization.cst "<destructuring>", (Serialization.cst "<destructuring>"))) bindings
in case d of
Syntax.DialectClojure -> case kind of
Syntax.LetKindRecursive ->
let fnSpecs =
Lists.map (\b -> case b of
Syntax.LetBindingSimple v2 ->
let name = symbolToExpr (Syntax.simpleBindingName v2)
val = Syntax.simpleBindingValue v2
in case val of
Syntax.ExpressionLambda v3 ->
let params = Lists.map symbolToExpr (Syntax.lambdaParams v3)
lbody = Lists.map (expressionToExpr d) (Syntax.lambdaBody v3)
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
name],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep params)],
lbody])))
_ -> Serialization.parens (Serialization.spaceSepAdaptive [
name,
(expressionToExpr d val)])
Syntax.LetBindingDestructuring _ -> Serialization.cst "<destructuring>") bindings
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "letfn"],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep fnSpecs)],
body])))
Syntax.LetKindParallel -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "let"],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep (Lists.concat (Lists.map (\p -> [
Pairs.first p,
(Pairs.second p)]) bindingPairs)))],
body]))
Syntax.LetKindSequential -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "let"],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep (Lists.concat (Lists.map (\p -> [
Pairs.first p,
(Pairs.second p)]) bindingPairs)))],
body]))
Syntax.DialectEmacsLisp ->
let kw =
case kind of
Syntax.LetKindParallel -> "let"
Syntax.LetKindSequential -> "let*"
Syntax.LetKindRecursive -> "letrec"
bindingExprs =
Lists.map (\p -> Serialization.parens (Serialization.spaceSepAdaptive [
Pairs.first p,
(Pairs.second p)])) bindingPairs
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.parens (Serialization.spaceSepAdaptive bindingExprs)],
body])))
Syntax.DialectCommonLisp ->
let kw =
case kind of
Syntax.LetKindParallel -> "let"
Syntax.LetKindSequential -> "let*"
Syntax.LetKindRecursive -> "letrec"
bindingExprs =
Lists.map (\p -> Serialization.parens (Serialization.spaceSepAdaptive [
Pairs.first p,
(Pairs.second p)])) bindingPairs
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.parens (Serialization.spaceSepAdaptive bindingExprs)],
body])))
Syntax.DialectScheme ->
let kw =
case kind of
Syntax.LetKindParallel -> "let"
Syntax.LetKindSequential -> "let*"
Syntax.LetKindRecursive -> "letrec"
bindingExprs =
Lists.map (\p -> Serialization.parens (Serialization.spaceSepAdaptive [
Pairs.first p,
(Pairs.second p)])) bindingPairs
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst kw],
[
Serialization.parens (Serialization.spaceSepAdaptive bindingExprs)],
body])))
-- | The keyword for list construction
listKeyword :: Syntax.Dialect -> String
listKeyword d =
case d of
Syntax.DialectClojure -> "list"
Syntax.DialectEmacsLisp -> "list"
Syntax.DialectCommonLisp -> "cl:list"
Syntax.DialectScheme -> "list"
-- | Serialize a list literal
listLiteralToExpr :: Syntax.Dialect -> Syntax.ListLiteral -> Ast.Expr
listLiteralToExpr d ll =
let elems = Lists.map (expressionToExpr d) (Syntax.listLiteralElements ll)
quoted = Syntax.listLiteralQuoted ll
in (Logic.ifElse quoted (Serialization.noSep [
Serialization.cst "'",
(Serialization.parens (Serialization.spaceSepAdaptive elems))]) (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst (listKeyword d)] elems))))
-- | Serialize a literal value
literalToExpr :: Syntax.Dialect -> Syntax.Literal -> Ast.Expr
literalToExpr d lit =
case lit of
Syntax.LiteralInteger v0 -> Serialization.cst (Literals.showBigint (Syntax.integerLiteralValue v0))
Syntax.LiteralFloat v0 -> Serialization.cst (formatLispFloat d (Syntax.floatLiteralValue v0))
Syntax.LiteralString v0 ->
let e1 = Strings.intercalate "\\\\" (Strings.splitOn "\\" v0)
in case d of
Syntax.DialectCommonLisp ->
let escaped = Strings.intercalate "\\\"" (Strings.splitOn "\"" e1)
in (Serialization.cst (Strings.cat [
"\"",
escaped,
"\""]))
Syntax.DialectClojure ->
let e2 = Strings.intercalate "\\n" (Strings.splitOn (Strings.fromList [
10]) e1)
e3 = Strings.intercalate "\\r" (Strings.splitOn (Strings.fromList [
13]) e2)
e4 = Strings.intercalate "\\t" (Strings.splitOn (Strings.fromList [
9]) e3)
escaped = Strings.intercalate "\\\"" (Strings.splitOn "\"" e4)
in (Serialization.cst (Strings.cat [
"\"",
escaped,
"\""]))
Syntax.DialectEmacsLisp ->
let e2 = Strings.intercalate "\\n" (Strings.splitOn (Strings.fromList [
10]) e1)
e3 = Strings.intercalate "\\r" (Strings.splitOn (Strings.fromList [
13]) e2)
e4 = Strings.intercalate "\\t" (Strings.splitOn (Strings.fromList [
9]) e3)
escaped = Strings.intercalate "\\\"" (Strings.splitOn "\"" e4)
in (Serialization.cst (Strings.cat [
"\"",
escaped,
"\""]))
Syntax.DialectScheme ->
let e2 = Strings.intercalate "\\n" (Strings.splitOn (Strings.fromList [
10]) e1)
e3 = Strings.intercalate "\\r" (Strings.splitOn (Strings.fromList [
13]) e2)
e4 = Strings.intercalate "\\t" (Strings.splitOn (Strings.fromList [
9]) e3)
escaped = Strings.intercalate "\\\"" (Strings.splitOn "\"" e4)
in (Serialization.cst (Strings.cat [
"\"",
escaped,
"\""]))
Syntax.LiteralCharacter v0 ->
let ch = Syntax.characterLiteralValue v0
in case d of
Syntax.DialectClojure -> Serialization.cst (Strings.cat2 "\\" ch)
Syntax.DialectEmacsLisp -> Serialization.cst (Strings.cat2 "?" ch)
Syntax.DialectCommonLisp -> Serialization.cst (Strings.cat2 "#\\" ch)
Syntax.DialectScheme -> Serialization.cst (Strings.cat2 "#\\" ch)
Syntax.LiteralBoolean v0 -> Logic.ifElse v0 (trueExpr d) (falseExpr d)
Syntax.LiteralNil -> nilExpr d
Syntax.LiteralKeyword v0 -> keywordToExpr d v0
Syntax.LiteralSymbol v0 -> Serialization.noSep [
Serialization.cst "'",
(symbolToExpr v0)]
-- | Serialize a macro definition
macroDefinitionToExpr :: Syntax.Dialect -> Syntax.MacroDefinition -> Ast.Expr
macroDefinitionToExpr d mdef =
let name = symbolToExpr (Syntax.macroDefinitionName mdef)
params = Lists.map symbolToExpr (Syntax.macroDefinitionParams mdef)
body = Lists.map (expressionToExpr d) (Syntax.macroDefinitionBody mdef)
in case d of
Syntax.DialectClojure -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defmacro",
name],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep params)],
body]))
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defmacro",
name],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defmacro",
name],
[
Serialization.parens (Serialization.spaceSepAdaptive params)],
body]))
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "define-syntax",
name],
body]))
-- | Serialize a map literal
mapLiteralToExpr :: Syntax.Dialect -> Syntax.MapLiteral -> Ast.Expr
mapLiteralToExpr d ml =
let entries = Syntax.mapLiteralEntries ml
in case d of
Syntax.DialectClojure -> Serialization.brackets Serialization.curlyBraces Serialization.inlineStyle (Serialization.spaceSep (Lists.concat (Lists.map (\e -> [
expressionToExpr d (Syntax.mapEntryKey e),
(expressionToExpr d (Syntax.mapEntryValue e))]) entries)))
Syntax.DialectEmacsLisp -> Serialization.noSep [
Serialization.cst "'",
(Serialization.parens (Serialization.spaceSepAdaptive (Lists.map (\e -> Serialization.parens (Serialization.spaceSepAdaptive [
expressionToExpr d (Syntax.mapEntryKey e),
(Serialization.cst "."),
(expressionToExpr d (Syntax.mapEntryValue e))])) entries)))]
Syntax.DialectCommonLisp -> Serialization.noSep [
Serialization.cst "'",
(Serialization.parens (Serialization.spaceSepAdaptive (Lists.map (\e -> Serialization.parens (Serialization.spaceSepAdaptive [
expressionToExpr d (Syntax.mapEntryKey e),
(Serialization.cst "."),
(expressionToExpr d (Syntax.mapEntryValue e))])) entries)))]
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "list"] (Lists.map (\e -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "cons",
(expressionToExpr d (Syntax.mapEntryKey e)),
(expressionToExpr d (Syntax.mapEntryValue e))])) entries)))
-- | Serialize a module declaration
moduleDeclarationToExpr :: Syntax.Dialect -> Syntax.ModuleDeclaration -> Ast.Expr
moduleDeclarationToExpr d mdecl =
let name = Syntax.unNamespaceName (Syntax.moduleDeclarationName mdecl)
in case d of
Syntax.DialectClojure -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "ns",
(Serialization.cst name)])
Syntax.DialectEmacsLisp -> Serialization.newlineSep [
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "require",
(Serialization.noSep [
Serialization.cst "'",
(Serialization.cst "cl-lib")])]),
(Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "provide",
(Serialization.noSep [
Serialization.cst "'",
(Serialization.cst name)])]))]
Syntax.DialectCommonLisp -> Serialization.newlineSep [
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "defpackage",
(Serialization.cst (Strings.cat2 ":" name))]),
(Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "in-package",
(Serialization.cst (Strings.cat2 ":" name))]))]
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "define-library",
(Serialization.parens (Serialization.cst name))])
-- | The nil expression
nilExpr :: Syntax.Dialect -> Ast.Expr
nilExpr d =
case d of
Syntax.DialectClojure -> Serialization.cst "nil"
Syntax.DialectEmacsLisp -> Serialization.cst "nil"
Syntax.DialectCommonLisp -> Serialization.cst "cl:nil"
Syntax.DialectScheme -> Serialization.cst "'()"
-- | Serialize a not expression: (not expr)
notExpressionToExpr :: Syntax.Dialect -> Syntax.NotExpression -> Ast.Expr
notExpressionToExpr d notExpr =
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "not",
(expressionToExpr d (Syntax.notExpressionExpression notExpr))])
-- | Serialize an or expression: (or expr1 expr2 ...)
orExpressionToExpr :: Syntax.Dialect -> Syntax.OrExpression -> Ast.Expr
orExpressionToExpr d orExpr =
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "or"] (Lists.map (expressionToExpr d) (Syntax.orExpressionExpressions orExpr))))
-- | Serialize a full Lisp program
programToExpr :: Syntax.Program -> Ast.Expr
programToExpr prog =
let d = Syntax.programDialect prog
modDecl = Syntax.programModule prog
imports = Syntax.programImports prog
exports = Syntax.programExports prog
forms = Syntax.programForms prog
formPart = Lists.map (topLevelFormWithCommentsToExpr d) forms
warning =
case d of
Syntax.DialectEmacsLisp -> [
Serialization.cst ";; -*- lexical-binding: t -*-",
(Serialization.cst (Strings.cat2 "; " Constants.warningAutoGeneratedFile))]
_ -> [
Serialization.cst (Strings.cat2 "; " Constants.warningAutoGeneratedFile)]
importNames = Lists.map (\idecl -> Syntax.unNamespaceName (Syntax.importDeclarationModule idecl)) imports
exportSyms = Lists.concat (Lists.map (\edecl -> Lists.map symbolToExpr (Syntax.exportDeclarationSymbols edecl)) exports)
in case d of
Syntax.DialectClojure -> Optionals.cases modDecl (Serialization.doubleNewlineSep (Lists.concat2 warning formPart)) (\m ->
let nameStr = Syntax.unNamespaceName (Syntax.moduleDeclarationName m)
requireClauses =
Lists.map (\imp -> Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep [
Serialization.cst imp,
(Serialization.cst ":refer"),
(Serialization.cst ":all")])) importNames
nsForm =
Logic.ifElse (Lists.null requireClauses) (Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "ns",
(Serialization.cst nameStr)])) (Serialization.parens (Serialization.newlineSep [
Serialization.spaceSep [
Serialization.cst "ns",
(Serialization.cst nameStr)],
(Serialization.spaceSep (Lists.concat2 [
Serialization.cst " (:require"] requireClauses)),
(Serialization.cst ")")]))
varNames =
Lists.concat (Lists.map (\fwc ->
let form = Syntax.topLevelFormWithCommentsForm fwc
in case form of
Syntax.TopLevelFormVariable v1 -> [
symbolToExpr (Syntax.variableDefinitionName v1)]
Syntax.TopLevelFormFunction v1 -> [
symbolToExpr (Syntax.functionDefinitionName v1)]
_ -> []) forms)
declareForm =
Logic.ifElse (Lists.null varNames) [] [
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "declare"] varNames))]
in (Serialization.doubleNewlineSep (Lists.concat [
warning,
[
nsForm],
declareForm,
formPart])))
Syntax.DialectEmacsLisp -> Optionals.cases modDecl (Serialization.doubleNewlineSep (Lists.concat2 warning formPart)) (\m ->
let nameStr = Syntax.unNamespaceName (Syntax.moduleDeclarationName m)
requireClLib =
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "require",
(Serialization.noSep [
Serialization.cst "'",
(Serialization.cst "cl-lib")])])
requireImports =
Lists.map (\imp -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "require",
(Serialization.noSep [
Serialization.cst "'",
(Serialization.cst imp)])])) importNames
provideForm =
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "provide",
(Serialization.noSep [
Serialization.cst "'",
(Serialization.cst nameStr)])])
in (Serialization.doubleNewlineSep (Lists.concat [
warning,
[
requireClLib],
requireImports,
formPart,
[
provideForm]])))
Syntax.DialectCommonLisp -> Optionals.cases modDecl (Serialization.doubleNewlineSep (Lists.concat2 warning formPart)) (\m ->
let nameStr = Syntax.unNamespaceName (Syntax.moduleDeclarationName m)
colonName = Strings.cat2 ":" nameStr
useClause =
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst ":use",
(Serialization.cst ":cl")] (Lists.map (\imp -> Serialization.cst (Strings.cat2 ":" imp)) importNames)))
exportClause =
Logic.ifElse (Lists.null exportSyms) [] [
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst ":export"] (Lists.map (\s -> Serialization.noSep [
Serialization.cst ":",
s]) exportSyms)))]
defpkgForm =
Serialization.parens (Serialization.newlineSep (Lists.concat [
[
Serialization.spaceSep [
Serialization.cst "defpackage",
(Serialization.cst colonName)]],
[
useClause],
exportClause]))
inpkgForm =
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "in-package",
(Serialization.cst colonName)])
in (Serialization.doubleNewlineSep (Lists.concat [
warning,
[
defpkgForm,
inpkgForm],
formPart])))
Syntax.DialectScheme -> Optionals.cases modDecl (Serialization.doubleNewlineSep (Lists.concat2 warning formPart)) (\m ->
let nameStr = Syntax.unNamespaceName (Syntax.moduleDeclarationName m)
nameParts = Lists.map (\p -> Formatting.convertCaseCamelToLowerSnake p) (Strings.splitOn "." nameStr)
nameExpr = Serialization.parens (Serialization.spaceSepAdaptive (Lists.map (\p -> Serialization.cst p) nameParts))
domainImportExprs =
Lists.map (\idecl ->
let nsName = Syntax.unNamespaceName (Syntax.importDeclarationModule idecl)
nsParts = Lists.map (\p -> Formatting.convertCaseCamelToLowerSnake p) (Strings.splitOn "." nsName)
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.map (\p -> Serialization.cst p) nsParts)))) imports
schemeBaseExpr =
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "scheme",
(Serialization.cst "base")])
allImportExprs = Lists.concat2 [
schemeBaseExpr] domainImportExprs
importClause =
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "import"] allImportExprs))
exportClauses = Lists.map (\edecl -> exportDeclarationToExpr d edecl) exports
beginClause = Serialization.parens (Serialization.newlineSep (Lists.concat2 [
Serialization.cst "begin"] formPart))
libraryExpr =
Serialization.parens (Serialization.newlineSep (Lists.concat [
[
Serialization.spaceSep [
Serialization.cst "define-library",
nameExpr]],
exportClauses,
[
importClause],
[
beginClause]]))
in (Serialization.doubleNewlineSep (Lists.concat2 warning [
libraryExpr])))
-- | Serialize a record type definition
recordTypeDefinitionToExpr :: Syntax.Dialect -> Syntax.RecordTypeDefinition -> Ast.Expr
recordTypeDefinitionToExpr d rdef =
let name = symbolToExpr (Syntax.recordTypeDefinitionName rdef)
fields = Lists.map (\f -> symbolToExpr (Syntax.fieldDefinitionName f)) (Syntax.recordTypeDefinitionFields rdef)
in case d of
Syntax.DialectClojure ->
let nameStr = Syntax.unSymbol (Syntax.recordTypeDefinitionName rdef)
fieldNames = Lists.map (\f -> Syntax.unSymbol (Syntax.fieldDefinitionName f)) (Syntax.recordTypeDefinitionFields rdef)
defrecordForm =
Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst "defrecord",
name,
(Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep fields))])
makeAlias =
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "defn",
(Serialization.cst (Strings.cat2 "make-" nameStr))],
[
Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep fields)],
[
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst (Strings.cat2 "->" nameStr)] (Lists.map (\fn -> Serialization.cst fn) fieldNames)))]]))
in (Serialization.newlineSep [
defrecordForm,
makeAlias])
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "cl-defstruct",
name],
fields]))
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "cl:defstruct",
name],
fields]))
Syntax.DialectScheme ->
let nameStr = Syntax.unSymbol (Syntax.recordTypeDefinitionName rdef)
fieldNames = Lists.map (\f -> Syntax.unSymbol (Syntax.fieldDefinitionName f)) (Syntax.recordTypeDefinitionFields rdef)
constructor =
Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst (Strings.cat2 "make-" nameStr)] (Lists.map (\fn -> Serialization.cst fn) fieldNames)))
predicate = Serialization.cst (Strings.cat2 nameStr "?")
accessors =
Lists.map (\fn -> Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst fn,
(Serialization.cst (Strings.cat [
nameStr,
"-",
fn]))])) fieldNames
in (Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat [
[
Serialization.cst "define-record-type",
name,
constructor,
predicate],
accessors])))
-- | Serialize an S-expression escape hatch
sExpressionToExpr :: Syntax.SExpression -> Ast.Expr
sExpressionToExpr sexpr =
case sexpr of
Syntax.SExpressionAtom v0 -> Serialization.cst v0
Syntax.SExpressionList v0 -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.map sExpressionToExpr v0))
-- | Serialize a set literal
setLiteralToExpr :: Syntax.Dialect -> Syntax.SetLiteral -> Ast.Expr
setLiteralToExpr d sl =
let elems = Lists.map (expressionToExpr d) (Syntax.setLiteralElements sl)
in case d of
Syntax.DialectClojure -> Serialization.noSep [
Serialization.cst "#",
(Serialization.brackets Serialization.curlyBraces Serialization.inlineStyle (Serialization.spaceSep elems))]
Syntax.DialectEmacsLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "list"] elems))
Syntax.DialectCommonLisp -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "cl:list"] elems))
Syntax.DialectScheme -> Serialization.parens (Serialization.spaceSepAdaptive (Lists.concat2 [
Serialization.cst "list"] elems))
-- | Serialize a symbol
symbolToExpr :: Syntax.Symbol -> Ast.Expr
symbolToExpr s = Serialization.cst (Syntax.unSymbol s)
-- | Serialize a top-level form
topLevelFormToExpr :: Syntax.Dialect -> Syntax.TopLevelForm -> Ast.Expr
topLevelFormToExpr d form =
case form of
Syntax.TopLevelFormFunction v0 -> functionDefinitionToExpr d v0
Syntax.TopLevelFormVariable v0 -> variableDefinitionToExpr d v0
Syntax.TopLevelFormConstant v0 -> constantDefinitionToExpr d v0
Syntax.TopLevelFormRecordType v0 -> recordTypeDefinitionToExpr d v0
Syntax.TopLevelFormMacro v0 -> macroDefinitionToExpr d v0
Syntax.TopLevelFormExpression v0 -> expressionToExpr d v0
-- | Serialize a top-level form together with its comments
topLevelFormWithCommentsToExpr :: Syntax.Dialect -> Syntax.TopLevelFormWithComments -> Ast.Expr
topLevelFormWithCommentsToExpr d fwc =
let mdoc = Syntax.topLevelFormWithCommentsDoc fwc
mcomment = Syntax.topLevelFormWithCommentsComment fwc
form = Syntax.topLevelFormWithCommentsForm fwc
docPart = Optionals.cases mdoc [] (\ds -> [
docstringToExpr ds])
commentPart = Optionals.cases mcomment [] (\c -> [
commentToExpr c])
formExpr = topLevelFormToExpr d form
in (Serialization.newlineSep (Lists.concat [
commentPart,
docPart,
[
formExpr]]))
-- | The boolean true expression
trueExpr :: Syntax.Dialect -> Ast.Expr
trueExpr d =
case d of
Syntax.DialectClojure -> Serialization.cst "true"
Syntax.DialectEmacsLisp -> Serialization.cst "t"
Syntax.DialectCommonLisp -> Serialization.cst "cl:t"
Syntax.DialectScheme -> Serialization.cst "#t"
-- | Serialize a variable definition
variableDefinitionToExpr :: Syntax.Dialect -> Syntax.VariableDefinition -> Ast.Expr
variableDefinitionToExpr d vdef =
let name = symbolToExpr (Syntax.variableDefinitionName vdef)
value = expressionToExpr d (Syntax.variableDefinitionValue vdef)
in (Serialization.parens (Serialization.spaceSepAdaptive [
Serialization.cst (defKeyword d),
name,
value]))
-- | Serialize a variable reference
variableReferenceToExpr :: Syntax.Dialect -> Syntax.VariableReference -> Ast.Expr
variableReferenceToExpr d vref =
let name = symbolToExpr (Syntax.variableReferenceName vref)
isFnNs = Syntax.variableReferenceFunctionNamespace vref
in (Logic.ifElse isFnNs (case d of
Syntax.DialectCommonLisp -> Serialization.noSep [
Serialization.cst "#'",
name]
Syntax.DialectClojure -> name
Syntax.DialectEmacsLisp -> name
Syntax.DialectScheme -> name) name)
-- | Serialize a vector literal
vectorLiteralToExpr :: Syntax.Dialect -> Syntax.VectorLiteral -> Ast.Expr
vectorLiteralToExpr d vl =
let elems = Lists.map (expressionToExpr d) (Syntax.vectorLiteralElements vl)
in case d of
Syntax.DialectClojure -> Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep elems)
Syntax.DialectEmacsLisp -> Serialization.brackets Serialization.squareBrackets Serialization.inlineStyle (Serialization.spaceSep elems)
Syntax.DialectCommonLisp -> Serialization.noSep [
Serialization.cst "#",
(Serialization.parens (Serialization.spaceSepAdaptive elems))]
Syntax.DialectScheme -> Serialization.noSep [
Serialization.cst "#",
(Serialization.parens (Serialization.spaceSepAdaptive elems))]