I am building on bisserlis bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory (underHead (+1))
'-' -> memory (atPtr (subtract 1))
Reads almost like the specification!
I am building on bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory (underHead (+1))
'-' -> memory (atPtr (subtract 1))
Reads almost like the specification!
I am building on bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory (underHead (+1))
'-' -> memory (atPtr (subtract 1))
Reads almost like the specification!
I am building on bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory (underHead (+1))
'-' -> memory (atPtr (subtract 1))
Reads almost like the specification!
I am building on bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory underHead (+1)
'-' -> memory atPtr (subtract 1)
Reads almost like the specification!
I am building on bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory (underHead (+1))
'-' -> memory (atPtr (subtract 1))
Reads almost like the specification!
I am building on bisserlis' answer here. interpret
uses a lot of repetition that can be reduced with case
..of
. That allows a where clause which factors out common code that modifies memory and simply advances the instruction pointer:
interpret m@(ZL _ x _) i@(ZL _ cmd _) = case cmd of '>' -> memory znxt '<' -> memory zprv '+' -> memory zinc '-' -> memory zdec '[' -> interpret m (if x /= 0 then znxt i else zjmp znxt 0 i) ']' -> interpret m (if x == 0 then znxt i else zjmp zprv 0 i) '.' -> putChar (toEnum x)>> memory id ',' -> getChar>>= memory . zapp . const . fromEnum _ -> memory id -- Comment `Char` where memory :: (ZL Int -> ZL Int) -> IO () memory f = interpret (f m) (znxt i)
I would use longer names for znxt
etc., then you might consider renaming zapp
to underHead
or atPtr
and then your code might read like this (I am mixing styles here):
'>' -> memory advancePtr
'<' -> memory moveHeadLeft
'+' -> memory underHead (+1)
'-' -> memory atPtr (subtract 1)
Reads almost like the specification!