1
+ {-# LANGUAGE OverloadedStrings #-}
2
+
1
3
module JavaScriptSyntax
2
4
( printModule
3
5
) where
4
6
5
7
import Data.List (intercalate )
8
+ import qualified Data.List.NonEmpty as NE
6
9
import Data.List.NonEmpty (toList )
10
+ import Data.Semigroup
11
+ import Data.Text (Text )
12
+ import qualified Data.Text as T
7
13
import Language
8
14
9
- indent :: Int -> String -> String
15
+ showT :: Show a => a -> Text
16
+ showT = T. pack . show
17
+
18
+ indent :: Int -> Text -> Text
10
19
indent level str =
11
- intercalate " \n " $ map (\ line -> replicate level ' ' ++ line) (lines str)
20
+ T. intercalate " \n " $
21
+ map (\ line -> T. replicate level " " <> line) (T. lines str)
12
22
13
- indent2 :: String -> String
23
+ indent2 :: Text -> Text
14
24
indent2 = indent 2
15
25
16
- printModule :: Module -> String
26
+ printModule :: Module -> Text
17
27
printModule (Module topLevels) =
18
- (intercalate " \n\n " $ map printTopLevel topLevels) ++ " \n "
28
+ (T. intercalate " \n\n " $ map printTopLevel topLevels) <> " \n "
19
29
20
- printTopLevel :: TopLevel -> String
30
+ printTopLevel :: TopLevel -> Text
21
31
printTopLevel topLevel =
22
32
case topLevel of
23
33
Function declaration -> printDeclaration declaration
24
- DataType _ -> undefined
34
+ DataType (ADT name generics ctors) ->
35
+ " type " <> s name <> printedGenerics <> " =" <>
36
+ indent 2 printedCtors
37
+ where printedGenerics =
38
+ case generics of
39
+ [] -> " "
40
+ _ -> " <" <> T. intercalate " , " (s <$> generics) <> " >"
41
+ printedCtors = T. intercalate " | " (printCtor <$> (NE. toList ctors))
42
+ printCtor (Constructor name maybeType) =
43
+ s name <> " " <> maybe " " printConstructorType maybeType
44
+ printConstructorType ctorType =
45
+ case ctorType of
46
+ CTConcrete i -> s i
47
+ CTApplied a b ->
48
+ printConstructorType a <> " " <> printConstructorType b
49
+ CTParenthesized ct -> parens (printConstructorType ct)
25
50
26
- printDeclaration :: Declaration -> String
51
+ printDeclaration :: Declaration -> Text
27
52
printDeclaration (Declaration _ name args expression) =
28
- " function " ++
29
- s name ++
30
- printedArgs ++ " { \n return " ++ printExpression expression ++ " \n }"
53
+ " function " <> s name <> printedArgs <> " { \n return " <>
54
+ printExpression expression <>
55
+ " \n }"
31
56
where
32
- printedArgs = parens $ intercalate " , " $ map s args
57
+ printedArgs = parens $ T. intercalate " , " $ map printArgument args
33
58
34
- printExpression :: Expression -> String
59
+ printExpression :: Expression -> Text
35
60
printExpression expression =
36
61
case expression of
37
- Number number -> show number
62
+ Number number -> showT number
63
+ Float f -> showT f
38
64
Identifier identifier -> s identifier
39
65
Infix operator a b ->
40
- intercalate
66
+ T. intercalate
41
67
" "
42
68
[printExpression a, printOperator operator, printExpression b]
43
- String' string -> show string
44
- Call name args ->
45
- s name ++ parens (intercalate " , " (map printExpression args))
69
+ String' string -> showT string
70
+ Apply a b -> printExpression a <> parens (printExpression b)
46
71
BetweenParens expression -> parens $ printExpression expression
47
72
Case expression branches ->
48
- " switch " ++
49
- parens (printExpression expression) ++
50
- " {\n " ++ indent 4 (printBranches branches) ++ " \n }"
51
- _ -> error $ " not implemented " ++ show expression
73
+ " switch " <> parens (printExpression expression) <> " {\n " <>
74
+ indent 4 (printBranches branches) <>
75
+ " \n }"
76
+ Let declarations expr ->
77
+ indent
78
+ 2
79
+ (T. intercalate
80
+ " \n "
81
+ ((printDeclaration <$>
82
+ (NE. toList declarations)) <> [printExpression expr]))
52
83
where
53
84
printBranches branches =
54
- intercalate " \n " $ toList $ fmap printBranch branches
85
+ T. intercalate " \n " $ toList $ fmap printBranch branches
55
86
printBranch (condition, body) =
56
- " case " ++
57
- printExpression condition ++ " :\n " ++ indent2 (printExpression body)
87
+ " case " <> printArgument condition <> " :\n " <>
88
+ indent2 (printExpression body)
89
+
90
+ printArgument :: Argument -> Text
91
+ printArgument a =
92
+ case a of
93
+ AIdentifier n -> s n
94
+ ADeconstruction name args ->
95
+ s name <> parens (T. intercalate " , " (printArgument <$> args))
96
+ ANumberLiteral i -> showT i
58
97
59
- printOperator :: OperatorExpr -> String
98
+ printOperator :: OperatorExpr -> Text
60
99
printOperator operator =
61
100
case operator of
62
101
Add -> " +"
@@ -65,5 +104,5 @@ printOperator operator =
65
104
Multiply -> " *"
66
105
StringAdd -> " ++"
67
106
68
- parens :: String -> String
69
- parens s = " (" ++ s ++ " )"
107
+ parens :: Text -> Text
108
+ parens s = " (" <> s <> " )"
0 commit comments