From 2788df88e6261ac641adf9f39bbfe517a7d77d9c Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 19 Jul 2017 12:25:45 +0000 Subject: Add else if --- Sil/Compile.icl | 38 +++++++++++++++++--------------------- Sil/Parse.icl | 19 +++++++++++++------ Sil/Syntax.dcl | 2 +- Sil/Syntax.icl | 2 +- Sil/Util/Printer.icl | 13 +++++++------ 5 files changed, 39 insertions(+), 35 deletions(-) (limited to 'Sil') diff --git a/Sil/Compile.icl b/Sil/Compile.icl index 42fa162..abed973 100644 --- a/Sil/Compile.icl +++ b/Sil/Compile.icl @@ -190,28 +190,24 @@ where gen (Return (Just app)) = comment "Return" *> gen app *> cleanup *> tell ['ABC'.Rtn] gen (Return Nothing) = comment "Return" *> cleanup *> tell ['ABC'.Rtn] gen (MachineStm s) = tell ['ABC'.Raw s] - gen (If c t Nothing) = + gen (If blocks else) = fresh "ifend" >>= \end -> - comment "condition" *> - gen c *> - toBStack 'ABC'.BT_Bool 1 *> - tell [ 'ABC'.JmpFalse end ] *> - comment "if-true" *> - gen t *> - tell [ 'ABC'.Label end ] - gen (If c t (Just e)) = - fresh "else" >>= \else -> fresh "ifend" >>= \end -> - comment "condition" *> - gen c *> - toBStack 'ABC'.BT_Bool 1 *> - tell [ 'ABC'.JmpFalse else ] *> - comment "if-true" *> - gen t *> - tell [ 'ABC'.Jmp end - , 'ABC'.Label else ] *> - comment "if-false" *> - gen e *> - tell [ 'ABC'.Label end ] + mapM_ (genifblock end) blocks *> + genelse end else + where + genifblock :: 'ABC'.Label (Application, CodeBlock) -> Gen () + genifblock end (cond, cb) = + fresh "ifelse" >>= \else -> + gen cond *> + toBStack 'ABC'.BT_Bool 1 *> + tell [ 'ABC'.JmpFalse else ] *> + gen cb *> + tell [ 'ABC'.Jmp end + , 'ABC'.Label else ] + + genelse :: 'ABC'.Label (Maybe CodeBlock) -> Gen () + genelse end Nothing = tell ['ABC'.Label end] + genelse end (Just cb) = gen cb *> tell ['ABC'.Label end] instance gen Application where diff --git a/Sil/Parse.icl b/Sil/Parse.icl index 3a11622..2e21d08 100644 --- a/Sil/Parse.icl +++ b/Sil/Parse.icl @@ -138,17 +138,18 @@ initialisation = pure [{init_type=t, init_name=n} \\ n <- ns] statement :: Parser Token Statement -statement = ((declaration - <|> liftM Application application +statement = declaration + <|> liftM Application (application <* item TSemicolon) <|> return <|> if` - /*<|> while*/) <* item TSemicolon) <|> machinecode + //<|> while + <|> machinecode where declaration :: Parser Token Statement - declaration = liftM2 Declaration name (item TAssign *> application) + declaration = liftM2 Declaration name (item TAssign *> application <* item TSemicolon) return :: Parser Token Statement - return = liftM Return (item TReturn *> optional application) + return = liftM Return (item TReturn *> optional application <* item TSemicolon) machinecode :: Parser Token Statement machinecode = (\(TMachineCode s) -> MachineStm s) <$> satisfy isMachineCode @@ -158,8 +159,14 @@ where if` = item TIf *> parenthised application >>= \cond -> braced codeblock >>= \iftrue -> + many elseif >>= \elseifs -> optional (item TElse *> braced codeblock) >>= \iffalse -> - pure $ If cond iftrue iffalse + pure $ If [(cond,iftrue):elseifs] iffalse + where + elseif = list [TElse, TIf] *> + parenthised application >>= \cond -> + braced codeblock >>= \block -> + pure (cond, block) application :: Parser Token Application application diff --git a/Sil/Syntax.dcl b/Sil/Syntax.dcl index 5c91dc6..b3ecdb7 100644 --- a/Sil/Syntax.dcl +++ b/Sil/Syntax.dcl @@ -34,7 +34,7 @@ from Data.Maybe import :: Maybe = Declaration Name Application | Application Application | Return (Maybe Application) - | If Application CodeBlock (Maybe CodeBlock) + | If [(Application, CodeBlock)] (Maybe CodeBlock) | While Application CodeBlock | MachineStm String diff --git a/Sil/Syntax.icl b/Sil/Syntax.icl index 934a300..ec7aafa 100644 --- a/Sil/Syntax.icl +++ b/Sil/Syntax.icl @@ -14,7 +14,7 @@ where toString (Application app) = toString app <+ ";" toString (Return Nothing) = "return;" toString (Return (Just a)) = "return " <+ a <+ ";" - toString (If c t e) = "if (" <+ c <+ ") ..." + toString (If bs e) = "if ..." toString (MachineStm s) = "|~" <+ s toString _ = "<>" diff --git a/Sil/Util/Printer.icl b/Sil/Util/Printer.icl index 2252ee4..af3d072 100644 --- a/Sil/Util/Printer.icl +++ b/Sil/Util/Printer.icl @@ -91,12 +91,13 @@ where instance PrettyPrinter Statement where - print st (If c t Nothing) = st <+ "if (" <+ c <+ ") {\r\n" <+ - print (incIndent st) t <+ "\r\n" <+ st <+ "}" - print st (If c t (Just e)) = st <+ "if (" <+ c <+ ") {\r\n" <+ - print st` t <+ "\r\n" <+ st <+ "} else {\r\n" <+ - print st` e <+ "\r\n" <+ st <+ "}" - where st` = incIndent st + print st (If bs else) = st <+ printersperse " else " (map oneblock bs) <+ else` + where + st` = incIndent st + oneblock (c,b) = "if (" <+ c <+ ") {\r\n" <+ print st` b <+ "\r\n" <+ st <+ "}" + else` = case else of + Nothing -> "" + Just e -> " else {\r\n" <+ print st` e <+ "\r\n" <+ st <+ "}" print st stm = st <+ stm printersperse :: a [b] -> String | toString a & toString b -- cgit v1.2.3