Skip to content

Commit

Permalink
Add Lexer for BrainFuck
Browse files Browse the repository at this point in the history
  • Loading branch information
kamil-adam committed May 16, 2020
1 parent 65ed758 commit d99e5d3
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 7 deletions.
6 changes: 5 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Revision history for helcam
# Revision history for HelCam

## 0.2.0.0 -- 2020-05-16

* Add BrainFuck Lexer

## 0.1.0.0 -- 2020-05-09

Expand Down
2 changes: 1 addition & 1 deletion docs/NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

**New features.**

*We do not have **news** now.*
* Add BrainFuck Lexer

For more see [CHANGELOG](CHANGELOG.md).
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# HELCAM
HELCAM - Heavenly Esoteric Little Concrete Absolute Machine for esoteric languages implemented in Haskell/Eta
**HELCAM** - Heavenly Esoteric Little Concrete Absolute Machine for Esoteric Languages implemented in Haskell/Eta

```
FOR everyone
WHO want to run esoteric languages
THE HELCAM IS a Heavenly Esoteric Little Concrete Absolute Machine for esoteric languages implemented in Haskell/Eta
THAT is an Evaluator and an Interpreter for esoteric languages
THE HELCAM IS a Heavenly Esoteric Little Concrete Absolute Machine for Esoteric Languages implemented in Haskell/Eta
THAT is an Evaluator and an Interpreter for Esoteric Languages (EsoLangs)
```

## For User
Expand Down
2 changes: 1 addition & 1 deletion docs/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**Future Features**

Features to do:
* [ ] BrainFuck Tokenizer
* [x] BrainFuck Lexer
* [ ] BrainFuck Evaluator
* [ ] BrainFuck Interpreter

Expand Down
5 changes: 4 additions & 1 deletion helcam.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- documentation, see http://eta-lang.org/docs/

name: helcam
version: 0.0.0.0
version: 0.2.0.0

synopsis: Heavenly Esoteric Little Concrete Absolute Machine
description: Please see the README on GitHub at <https://github.com/helvm/helcam#readme>
Expand All @@ -26,7 +26,9 @@ source-repository head

library
other-modules:
HelVM.HelCam.BrainFuck.Token
exposed-modules:
HelVM.HelCam.BrainFuck.Tokens
other-extensions:
build-depends: base >=4.11 && <4.12
hs-source-dirs: src/main/eta
Expand All @@ -37,6 +39,7 @@ test-suite helcam-test
type: exitcode-stdio-1.0
main-is: Test.hs
other-modules:
HelVM.HelCam.BrainFuck.TokensTest
exposed-modules:
other-extensions:
build-depends:
Expand Down
35 changes: 35 additions & 0 deletions src/main/eta/helvm/helcam/BrainFuck/Token.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module HelVM.HelCam.BrainFuck.Token where

data Token = MoveR
| MoveL
| Inc
| Dec
| Output
| Input
| JmpPast
| JmpBack
deriving (Eq, Ord, Enum)

type TokenList = [Token]

instance Show Token where
show MoveR = ">"
show MoveL = "<"
show Inc = "+"
show Dec = "-"
show Output = "."
show Input = ","
show JmpPast = "["
show JmpBack = "]"

instance Read Token where
readsPrec _ ">" = [( MoveR , "")]
readsPrec _ "<" = [( MoveL , "")]
readsPrec _ "+" = [( Inc , "")]
readsPrec _ "-" = [( Dec , "")]
readsPrec _ "." = [( Output , "")]
readsPrec _ "," = [( Input , "")]
readsPrec _ "[" = [( JmpPast, "")]
readsPrec _ "]" = [( JmpBack, "")]
readsPrec _ _ = []

30 changes: 30 additions & 0 deletions src/main/eta/helvm/helcam/BrainFuck/Tokens.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module HelVM.HelCam.BrainFuck.Tokens where

import HelVM.HelCam.BrainFuck.Token

import Data.Maybe
import Text.Read

newtype Tokens = Tokens TokenList

--

instance Show Tokens where
show (Tokens tokens) = tokens >>= show

charToString :: Char -> String
charToString = (:[])

instance Read Tokens where
readsPrec _ text = [( Tokens $ text >>= maybeToList . readMaybe . charToString, "")]

--

tokenList :: Tokens -> TokenList
tokenList (Tokens tokens) = tokens

readTokens :: String -> Tokens
readTokens text = read text :: Tokens

tokenize :: String -> TokenList
tokenize = tokenList . readTokens
3 changes: 3 additions & 0 deletions src/test/eta/Test.hs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
module Main(main) where

import HelVM.HelCam.BrainFuck.TokensTest

import Test.HUnit

testExample :: Test
testExample = TestCase (assertEqual "test" "test" "test")

testList :: Test
testList = TestList [ TestLabel "testExample" testExample
, TestLabel "testsOfTokens" testsOfTokens
]

main :: IO ()
Expand Down
65 changes: 65 additions & 0 deletions src/test/eta/helvm/helcam/BrainFuck/TokensTest.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module HelVM.HelCam.BrainFuck.TokensTest where

import HelVM.HelCam.BrainFuck.Tokens

import Test.HUnit

helloWorldWithComments :: String
helloWorldWithComments = " \
\ 1 +++++ +++ Set Cell #0 to 8 \
\ 2 [ \
\ 3 >++++ Add 4 to Cell #1; this will always set Cell #1 to 4 \
\ 4 [ as the cell will be cleared by the loop \
\ 5 >++ Add 4*2 to Cell #2 \
\ 6 >+++ Add 4*3 to Cell #3 \
\ 7 >+++ Add 4*3 to Cell #4 \
\ 8 >+ Add 4 to Cell #5 \
\ 9 <<<<- Decrement the loop counter in Cell #1 \
\10 ] Loop till Cell #1 is zero \
\11 >+ Add 1 to Cell #2 \
\12 >+ Add 1 to Cell #3 \
\13 >- Subtract 1 from Cell #4 \
\14 >>+ Add 1 to Cell #6 \
\15 [<] Move back to the first zero cell you find; this will \
\16 be Cell #1 which was cleared by the previous loop \
\17 <- Decrement the loop Counter in Cell #0 \
\18 ] Loop till Cell #0 is zero \
\19 \
\20 The result of this is: \
\21 Cell No : 0 1 2 3 4 5 6 \
\22 Contents: 0 0 72 104 88 32 8 \
\23 Pointer : ^ \
\24 \
\25 >>. Cell #2 has value 72 which is 'H' \
\26 >---. Subtract 3 from Cell #3 to get 101 which is 'e' \
\27 +++++ ++..+++. Likewise for 'llo' from Cell #3 \
\28 >>. Cell #5 is 32 for the space \
\29 <-. Subtract 1 from Cell #4 for 87 to give a 'W' \
\30 <. Cell #3 was set to 'o' from the end of 'Hello' \
\31 +++.----- -.----- ---. Cell #3 for 'rl' and 'd' \
\32 >>+. Add 1 to Cell #5 gives us an exclamation point \
\33 >++. And finally a newline from Cell #6 \
\"

helloWorld :: String
helloWorld = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."

helloWorldAsList :: String
helloWorldAsList = "[+,+,+,+,+,+,+,+,[,>,+,+,+,+,[,>,+,+,>,+,+,+,>,+,+,+,>,+,<,<,<,<,-,],>,+,>,+,>,-,>,>,+,[,<,],<,-,],>,>,.,>,-,-,-,.,+,+,+,+,+,+,+,.,.,+,+,+,.,>,>,.,<,-,.,<,.,+,+,+,.,-,-,-,-,-,-,.,-,-,-,-,-,-,-,-,.,>,>,+,.,>,+,+,.]"

--------------------------------------------------------------------------------

testHelloWorld :: Test
testHelloWorld = TestCase (assertEqual "testHelloWorld" helloWorld (show $ readTokens helloWorld))

testHelloWorldWithComments :: Test
testHelloWorldWithComments = TestCase (assertEqual "testHelloWorldWithComments" helloWorld (show $ readTokens helloWorldWithComments))

testTokenAsList :: Test
testTokenAsList = TestCase (assertEqual "testTokenAsList" helloWorldAsList (show $ tokenList $ readTokens helloWorldWithComments))

testsOfTokens :: Test
testsOfTokens = TestList [ TestLabel "testHelloWorld" testHelloWorld
, TestLabel "testHelloWorldWithComments" testHelloWorldWithComments
, TestLabel "testTokenAsList" testTokenAsList
]

0 comments on commit d99e5d3

Please sign in to comment.