Skip to content

Commit d3ca283

Browse files
committed
Implement printing of cases, parens, fill in operators (js)
1 parent fd46de9 commit d3ca283

8 files changed

+82
-21
lines changed

src/JavaScriptSyntax.hs

+30-5
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ module JavaScriptSyntax
33
) where
44

55
import Data.List (intercalate)
6+
import Data.List.NonEmpty (toList)
67
import Language
78

9+
indent :: Int -> String -> String
10+
indent level str =
11+
intercalate "\n" $ map (\line -> replicate level ' ' ++ line) (lines str)
12+
13+
indent2 :: String -> String
14+
indent2 = indent 2
15+
816
printModule :: Module -> String
917
printModule (Module topLevels) =
10-
intercalate "\n\n" $ map printTopLevel topLevels
18+
(intercalate "\n\n" $ map printTopLevel topLevels) ++ "\n"
1119

1220
printTopLevel :: TopLevel -> String
1321
printTopLevel topLevel =
@@ -19,9 +27,9 @@ printDeclaration :: Declaration -> String
1927
printDeclaration (Declaration _ name args expression) =
2028
"function " ++
2129
s name ++
22-
"(" ++ printedArgs ++ ") { return " ++ printExpression expression ++ " }"
30+
printedArgs ++ " {\n return " ++ printExpression expression ++ "\n}"
2331
where
24-
printedArgs = intercalate ", " $ map s args
32+
printedArgs = parens $ intercalate ", " $ map s args
2533

2634
printExpression :: Expression -> String
2735
printExpression expression =
@@ -34,11 +42,28 @@ printExpression expression =
3442
[printExpression a, printOperator operator, printExpression b]
3543
String' string -> show string
3644
Call name args ->
37-
s name ++ "(" ++ intercalate ", " (map printExpression args) ++ ")"
45+
s name ++ parens (intercalate ", " (map printExpression args))
46+
BetweenParens expression -> parens $ printExpression expression
47+
Case expression branches ->
48+
"switch " ++
49+
parens (printExpression expression) ++
50+
" {\n" ++ indent 4 (printBranches branches) ++ "\n }"
3851
_ -> error $ "not implemented " ++ show expression
52+
where
53+
printBranches branches =
54+
intercalate "\n" $ toList $ fmap printBranch branches
55+
printBranch (condition, body) =
56+
"case " ++
57+
printExpression condition ++ ":\n" ++ indent2 (printExpression body)
3958

4059
printOperator :: OperatorExpr -> String
4160
printOperator operator =
4261
case operator of
4362
Add -> "+"
44-
_ -> undefined
63+
Subtract -> "-"
64+
Divide -> "/"
65+
Multiply -> "*"
66+
StringAdd -> "++"
67+
68+
parens :: String -> String
69+
parens s = "(" ++ s ++ ")"

test/JavaScriptSyntaxSpec.hs

+29-16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module JavaScriptSyntaxSpec
88

99
import Control.Monad
1010
import qualified Data.List.NonEmpty as NE
11+
import Debug.Trace
1112
import System.Exit
1213
import System.IO.Temp
1314
import System.Process
@@ -24,23 +25,12 @@ javaScriptSyntaxSpecs :: SpecWith ()
2425
javaScriptSyntaxSpecs =
2526
describe "Forest JavaScript syntax" $ do
2627
it "prints a simple program" $ do
28+
expected <- readFixture "js/simple"
2729
let code =
2830
Module [Function $ Declaration Nothing (ne "test") [] (Number 1)]
29-
expected = "function test() { return 1 }"
30-
in printModule code `shouldBe` expected
31-
it "prints a function with an argument" $ do
32-
let code =
33-
Module
34-
[ Function $
35-
Declaration
36-
Nothing
37-
(ne "test")
38-
[ne "num"]
39-
(Identifier (ne "num"))
40-
]
41-
expected = "function test(num) { return num }"
4231
in printModule code `shouldBe` expected
4332
it "prints a function with many arguments" $ do
33+
expected <- readFixture "js/arguments"
4434
let code =
4535
Module
4636
[ Function $
@@ -50,15 +40,15 @@ javaScriptSyntaxSpecs =
5040
[ne "a", ne "b"]
5141
(Infix Add (Identifier (ne "a")) (Identifier (ne "b")))
5242
]
53-
expected = "function test(a, b) { return a + b }"
5443
in printModule code `shouldBe` expected
5544
it "prints a function that returns a string" $ do
45+
expected <- readFixture "js/string"
5646
let code =
5747
Module
5848
[Function $ Declaration Nothing (ne "test") [] (String' "hey")]
59-
expected = "function test() { return \"hey\" }"
6049
in printModule code `shouldBe` expected
6150
it "prints a function call with arguments" $ do
51+
expected <- readFixture "js/call-with-arguments"
6252
let code =
6353
Module
6454
[ Function $
@@ -70,7 +60,30 @@ javaScriptSyntaxSpecs =
7060
(ne "func")
7161
[(Identifier (ne "a")), (Identifier (ne "b"))])
7262
]
73-
expected = "function test(a, b) { return func(a, b) }"
63+
in printModule code `shouldBe` expected
64+
it "prints a function with an expression inside of parens" $ do
65+
expected <- readFixture "js/parens"
66+
let code =
67+
Module
68+
[ Function $
69+
Declaration Nothing (ne "test") [] (BetweenParens (Number 1))
70+
]
71+
in printModule code `shouldBe` expected
72+
it "prints a function with a case" $ do
73+
expected <- readFixture "js/case"
74+
let code =
75+
Module
76+
[ Function $
77+
Declaration
78+
Nothing
79+
(ne "test")
80+
[ne "a"]
81+
(Case
82+
(Identifier (ne "a"))
83+
[ (String' "Foo", String' "Bar")
84+
, (String' "Ahh", String' "Woo")
85+
])
86+
]
7487
in printModule code `shouldBe` expected
7588

7689
ne :: String -> Ident

test/fixtures/js/arguments.tree

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function test(a, b) {
2+
return a + b
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function test(a, b) {
2+
return func(a, b)
3+
}

test/fixtures/js/case.tree

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function test(a) {
2+
return switch (a) {
3+
case "Foo":
4+
"Bar"
5+
case "Ahh":
6+
"Woo"
7+
}
8+
}

test/fixtures/js/parens.tree

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function test() {
2+
return (1)
3+
}

test/fixtures/js/simple.tree

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function test() {
2+
return 1
3+
}

test/fixtures/js/string.tree

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function test() {
2+
return "hey"
3+
}

0 commit comments

Comments
 (0)