aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--Sil/Compile.icl38
-rw-r--r--Sil/Parse.icl19
-rw-r--r--Sil/Syntax.dcl2
-rw-r--r--Sil/Syntax.icl2
-rw-r--r--Sil/Util/Printer.icl13
-rw-r--r--examples/fib.sil10
7 files changed, 44 insertions, 41 deletions
diff --git a/README.md b/README.md
index 94cba01..bacfd06 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@ or can be interpreted with the [ABCMachine][abc-github] project.
| <Expression> ';'
| 'return' [<Expression>] ';'
| 'if' '(' <Expression> ')' '{' <CodeBlock> '}'
+ ['else' 'if' '(' <Expression> ')' '{' <CodeBlock> '}']-list
['else' '{' <CodeBlock> '}'] ';'
| 'while' '(' <Expression> ')' '{' <CodeBlock> '}' ';'
| '|~' <MachineCode>
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 _ = "<<unimplemented Statement>>"
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
diff --git a/examples/fib.sil b/examples/fib.sil
index b974722..71a9bb1 100644
--- a/examples/fib.sil
+++ b/examples/fib.sil
@@ -1,13 +1,11 @@
Int fib(Int n) {
if (n == 100) {
return 100;
- } else {
- if (n == 200) {
+ } else if (n == 200) {
return 100;
- } else {
- return fib(n - 100) + fib(n - 200);
- };
- };
+ } else {
+ return fib(n - 100) + fib(n - 200);
+ }
}
Int main() {