@@ -103,20 +103,47 @@ assocOf ".." = ARight
103103assocOf " ^" = ARight
104104assocOf _ = ALeft
105105
106- -- | Emit an indented block of objects, with a header and footer
106+ contained :: Doc -> [Doc ] -> Doc -> Doc
107+ contained header body footer = header <> nest 2 (line <> vsep body) <> line <> footer
108+
109+ -- | Emit an indented block of statements, with a header and footer
107110--
108111-- We have this weird asymmetry of 'line' as we need to indent the first line
109112-- line of the body but don't want to indent the footer.
110- block :: Doc -> [Doc ] -> Doc -> Doc
111- block header body footer = header <> nest 2 (line <> vsep body) <> line <> footer
113+ block :: Doc -> [LuaStmt ] -> Doc -> Doc
114+ block header body footer = header <> nest 2 (line <> stmts body) <> line <> footer
115+
116+ stmts :: [LuaStmt ] -> Doc
117+ stmts [] = mempty
118+ stmts [x] = pretty x
119+ stmts (a: b: cs)
120+ | trailingExpr a && leadingS b = pretty a <> " ;" <#> stmts (b: cs)
121+ | otherwise = pretty a <#> stmts (b: cs) where
122+ trailingExpr LuaAssign {} = True
123+ trailingExpr LuaRepeat {} = True
124+ trailingExpr LuaReturn {} = True
125+ trailingExpr LuaLocal {} = True
126+ trailingExpr LuaCallS {} = True
127+ trailingExpr _ = False
128+
129+ leadingS (LuaCallS c) = leadingC c
130+ leadingS (LuaAssign (v: _) _) = leadingVar v
131+ leadingS _ = False
112132
113- -- | A 'block', which may potentially be simplified to a single line.
114- miniBlock :: Doc -> Doc -> Doc -> Doc
115- miniBlock header body footer = header <> nest 2 (softline <> body) <> softline <> footer
133+ leadingC (LuaCall e _) = leadingFn e
134+ leadingC (LuaInvoke e _ _) = leadingFn e
116135
136+ leadingFn (LuaCallE c) = leadingC c
137+ leadingFn (LuaRef LuaName {}) = False
138+ leadingFn _ = True
139+
140+ leadingVar LuaName {} = False
141+ leadingVar (LuaIndex (LuaRef v) _) = leadingVar v
142+ leadingVar (LuaIndex _ _) = True
143+ leadingVar LuaQuoteV {} = False
117144
118145-- | A variant of 'block' but with an empty footer
119- headedBlock :: Doc -> [Doc ] -> Doc
146+ headedBlock :: Doc -> [LuaStmt ] -> Doc
120147headedBlock header body = block header body empty
121148
122149-- | Build a series of function arguments
@@ -126,42 +153,42 @@ args = parens . hsep . punctuate comma
126153instance Pretty LuaStmt where
127154 pretty (LuaDo xs) =
128155 block (keyword " do" )
129- ( map pretty xs)
156+ xs
130157 (keyword " end" )
131158 pretty (LuaAssign ns xs) = hsep (punctuate comma (map pretty ns)) <+> equals <+> hsep (punctuate comma (map pretty xs))
132159 pretty (LuaWhile c t) =
133160 block (keyword " while" <+> pretty c <+> keyword " do" )
134- ( map pretty t)
161+ t
135162 (keyword " end" )
136163 pretty (LuaRepeat t c) =
137164 block (keyword " repeat" )
138- ( map pretty t)
165+ t
139166 (keyword " until" <+> pretty c)
140167 pretty (LuaIfElse [(c,[t])]) =
141- miniBlock (keyword " if" <+> pretty c <+> keyword " then" ) (pretty t) (keyword " end" )
168+ group $ block (keyword " if" <+> pretty c <+> keyword " then" ) [t] (keyword " end" )
142169 pretty (LuaIfElse ((c,t): bs)) =
143170 let pprintElse [] = keyword " end"
144171 pprintElse [(LuaTrue , b)] =
145- headedBlock (keyword " else" ) ( map pretty b)
172+ headedBlock (keyword " else" ) b
146173 <> keyword " end"
147174 pprintElse ((c, b): xs) =
148175 headedBlock (keyword " elseif" <+> pretty c <+> keyword " then" )
149- ( map pretty b)
176+ b
150177 <> pprintElse xs
151178 in headedBlock (keyword " if" <+> pretty c <+> keyword " then" )
152- ( map pretty t)
179+ t
153180 <> pprintElse bs
154181 pretty (LuaIfElse [] ) = error " impossible"
155182 pretty (LuaFornum v s e i b) =
156183 block ( keyword " for" <+> pretty v <+> equals
157184 <+> pretty s <+> comma <+> pretty e <+> comma <+> pretty i <+> keyword " do" )
158- ( map pretty b)
185+ b
159186 (keyword " end" )
160187 pretty (LuaFor vs es b) =
161188 block ( keyword " for" <+> hsep (punctuate comma (map pretty vs))
162189 <+> keyword " in" <+> hsep (punctuate comma (map pretty es))
163190 <+> keyword " do" )
164- ( map pretty b)
191+ b
165192 (keyword " end" )
166193 pretty (LuaLocalFun n a b) =
167194 funcBlock (keyword " local function" <+> pretty n <> args (map pretty a))
@@ -172,9 +199,12 @@ instance Pretty LuaStmt where
172199 <+> equals <+> hsep (punctuate comma (map pretty xs))
173200 pretty (LuaQuoteS x) = " @" <> text x
174201 pretty LuaBreak = keyword " break"
175- pretty (LuaReturn v) = keyword " return" <+> pretty v
202+ pretty (LuaReturn [] ) = keyword " return"
203+ pretty (LuaReturn vs) = keyword " return" <+> hsep (punctuate comma (map pretty vs))
176204 pretty (LuaCallS x) = pretty x
177205
206+ prettyList = stmts
207+
178208instance Pretty LuaVar where
179209 pretty (LuaName x) = text x
180210 pretty (LuaIndex e (LuaString k))
@@ -206,16 +236,16 @@ instance Pretty LuaExpr where
206236 op " and" = skeyword " and"
207237 op " or" = skeyword " or"
208238 op o = text o
209- pretty e@ (LuaUnOp o x) = op o <> prettyWith (precedenceOf e) x where
210- op " not " = skeyword " not "
211- op o = text o
239+ pretty e@ (LuaUnOp " not " x) = skeyword " not " <> prettyWith (precedenceOf e) x
240+ pretty ( LuaUnOp " - " x @ LuaUnOp {}) = text " - " <> parens (pretty x)
241+ pretty e @ ( LuaUnOp o x) = text o <> prettyWith (precedenceOf e) x
212242 pretty (LuaRef x) = pretty x
213243 pretty (LuaFunction a b) =
214244 funcBlock (keyword " function" <> args (map pretty a))
215245 b
216246 (keyword " end" )
217247 pretty (LuaTable [] ) = lbrace <> rbrace
218- pretty (LuaTable ps) = group (block lbrace (punctuate comma . entries 1 $ ps) rbrace) where
248+ pretty (LuaTable ps) = group (contained lbrace (punctuate comma . entries 1 $ ps) rbrace) where
219249 entries _ [] = []
220250 entries n ((LuaString k, v): es) | validKey k = text k <+> value v : entries n es
221251 entries n ((LuaInteger k, v): es) | k == n = pretty v : entries (n + 1 ) es
@@ -239,8 +269,8 @@ prettyWith desired expr =
239269-- | An alternative to 'block' which may group simple functions onto one line
240270funcBlock :: Doc -> [LuaStmt ] -> Doc -> Doc
241271funcBlock header [] = group . block header []
242- funcBlock header [r @ LuaReturn {}] = group . block header [pretty r]
243- funcBlock header body = block header ( map pretty body)
272+ funcBlock header r @ [ LuaReturn {}] = group . block header r
273+ funcBlock header body = block header body
244274
245275validKey :: Text -> Bool
246276validKey t = case T. uncons t of
0 commit comments