packages feed

huckleberry 0.9.0.0 → 0.9.0.1

raw patch · 3 files changed

+405/−24 lines, 3 filesdep +HUnitdep +huckleberrydep ~base

Dependencies added: HUnit, huckleberry

Dependency ranges changed: base

Files

Language/Huckleberry/V10101.hs view
@@ -1,5 +1,93 @@ {-# LANGUAGE GADTs #-} +{-|+The EDSL Provides bridge between IchigoJam BASIC and Haskell.++References for IchigoJam BASIC are available at+<http://ichigojam.net/IchigoJam-1.0.1.html>.+++For example,+\"Jumping rome girl Sacchan\" <http://pcn.club/ns/diprogram.en.html>+could be expressed like this.++@+sacchan = do+  label  10 $ y=:25 >> v=:99 >> x=:17 >> u=:5 >> s=:0+  label  20 $ ifThen (v\/=99) $ y=:y+v >> v=:v+1+  label  30 $ ifThen (25\<y) $ y=:25 >> v=:99 >> s=:s+1+  label  40 $ x=:x+u+  label  50 $ ifThen (17\<x) $ u=:u-1+  label  60 $ ifThen (x\<17) $ u=:u+1+  label  70 $ k=:inkey+  label  80 $ ifThen (k==32) $ v=:(-3)+  label  90 $ cls+  label 100 $ locate 17 y >> print "\@"+  label 110 $ locate x 25 >> print \"-\"+  label 120 $ locate 0  0 >> print (\"SCORE:\" ++ s)+  label 130 $ ifThen (pre(y==25)*pre(x==17)) end+  label 140 $ wait 2+  label 150 $ goto 20+@+++Get IchigoJam BASIC code like this.++@+showSacchan = putStr $ translate sacchan+@++Also, you can send the code to IchigoJam directly.++@+sendSacchan = do+  h \<- IJ.opend "\/dev\/ttyUSB0"+  IJ.send h $ translate sacchan+  IJ.close h+@+++To use this, your code should begin with this code block.++@+\{\-\# LANGUAGE OverloadedStrings \#\-\}+import Prelude hiding (print,(++),(+),(-),(*),(\/),(%),(==),(\/=),(>=),(>),(\<=),(\<),(&&),(||),not,abs,return)+import qualified Prelude as P+import qualified IchigoJam as IJ+import Language.Huckleberry.V10101+@++For more example.+<https://github.com/mitsuji/huckleberry>+++() is 'pre'.++Put line number by 'label'.++\[n\] is 'arr'.++LET is 'let''.++\= is '=:'.++\; is '++'.++IN is 'in''.++& is '.&.'.++| is '.|.'.++^ is 'xor'.++\>\> is 'shiftR'.++\<\< is 'shiftL'.++~ is 'complement'.++-} module Language.Huckleberry.V10101 (   translate   ,pre@@ -35,6 +123,7 @@   ,y   ,z   ,arr+   -- * Commands for beginners   ,let'   ,(=:)   ,print@@ -87,6 +176,7 @@   ,(&&)   ,(||)   ,not+   -- * Commands for experts   ,clv   ,clear   ,clk@@ -146,7 +236,7 @@   Number :: (Num r) => r -> Expr r   Str :: (S.IsString r) => r -> Expr r   -  -- 優先して評価(カッコの代わり)+  -- Bracket operator   Pre :: Expr Int16 -> Expr Int16    A :: Expr Int16@@ -181,10 +271,10 @@     ---  -- Beginner's+  -- Commands for beginners   -- -  -- [TODO] 数:0(付属ボタン)/UP/DOWN/RIGHT/LEFT/SPACE、省略で0+  -- [TODO] [num]:0(button)/UP/DOWN/RIGHT/LEFT/SPACE, defautl 0   Btn :: Expr Int16 -> Expr Int16    Rnd :: Expr Int16 -> Expr Int16@@ -203,7 +293,7 @@   Asc :: String -> Expr Int16    Scr :: Expr Int16 -> Expr Int16 -> Expr Int16-  Scr' :: Expr Int16 -- 指定なしで現在位置+  Scr' :: Expr Int16      Equal :: Expr Int16 -> Expr Int16 -> Expr Int16   NotEqual :: Expr Int16 -> Expr Int16 -> Expr Int16@@ -217,7 +307,7 @@     ---  -- Expert's+  -- Commands for experts   --   Abs :: Expr Int16 -> Expr Int16   Sound :: Expr Int16@@ -228,13 +318,13 @@   Ana :: Expr Int16 -> Expr Int16    In' :: Expr Int16 -> Expr Int16-  In'' :: Expr Int16 -- 数を省略してまとめて入力できる+  In'' :: Expr Int16    Hex :: Expr Int16 -> Expr Int16 -> Expr String-  Hex' :: Expr Int16 -> Expr String -- 2番目の数は桁数、省略可+  Hex' :: Expr Int16 -> Expr String    Bin :: Expr Int16 -> Expr Int16 -> Expr String-  Bin' :: Expr Int16 -> Expr String -- 2番目の数は桁数、省略可+  Bin' :: Expr Int16 -> Expr String    BitAnd :: Expr Int16 -> Expr Int16 -> Expr Int16   BitOr ::  Expr Int16 -> Expr Int16 -> Expr Int16@@ -270,7 +360,7 @@    Label :: Int16 -> [Stmt] -> Stmt -  -- IFは入れ子にできる+  -- IF could be nested   IfThenElse :: Expr Int16 -> [Stmt] -> [Stmt] -> Stmt   IfThen :: Expr Int16 -> [Stmt] -> Stmt   ForStepNext :: Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16 -> [Stmt] -> Stmt@@ -278,7 +368,7 @@       ---  -- Beginner's+  -- Commands for beginners   --   Let' :: Expr Int16 -> [Expr Int16] -> Stmt   Assign :: Expr Int16 -> Expr Int16 -> Stmt@@ -290,7 +380,7 @@   Run :: Stmt    List :: Expr Int16 -> Expr Int16 -> Stmt-  List' :: Stmt -- 行番号は共に省略可  +  List' :: Stmt       Goto :: Expr Int16 -> Stmt@@ -301,18 +391,18 @@   Cls :: Stmt    Save :: Expr Int16 -> Stmt-  Save' :: Stmt -- 省略で前回使用した数+  Save' :: Stmt      Load :: Expr Int16 -> Stmt-  Load' :: Stmt  -- 省略で前回使用した数+  Load' :: Stmt      Files :: Expr Int16 -> Stmt    Beep :: Expr Int16 -> Expr Int16 -> Stmt-  Beep' :: Stmt -- 周期(1-255)と長さ(1/60秒単位)は省略可+  Beep' :: Stmt    Play :: String -> Stmt-  Play' :: Stmt -- MML省略で停止+  Play' :: Stmt      Tempo :: Expr Int16 -> Stmt @@ -323,7 +413,7 @@     ---  -- Expert's+  -- Commands for experts   --   Clv :: Stmt   Clk :: Stmt@@ -332,7 +422,7 @@   Return :: Stmt    Renum :: Expr Int16 -> Stmt-  Renum' :: Stmt -- 数省略で10+  Renum' :: Stmt      LRun :: Expr Int16 -> Stmt @@ -343,7 +433,7 @@   Help :: Stmt    Out :: Expr Int16 -> Expr Int16 -> Stmt-  Out' :: Expr Int16 -> Stmt -- 数2を省略でまとめて出力できる+  Out' :: Expr Int16 -> Stmt    Bps :: Expr Int16 -> Stmt   @@ -499,23 +589,68 @@  type Code = Writer [Stmt] +{-| Translate huckleberry code to IchigoJam BASIC code.++-} translate :: Code() -> String translate c = (intercalate "\n" $ map toString (execWriter c)) P.++ "\n" +{-| Bracket operator.++the expression++@+pre(y==25)*pre(x==17)+@++evaluated as this expression in IchigoJam BASIC. ++@+(Y=25)*(X=17)+@++-} pre = Pre +{-| Line number statement.++this expression++@+label  40 $ x=:x+u+@++evaluated as this statement in IchigoJam BASIC.++@+40 X=X+U+@++-} label :: Int16 -> Code() -> Code() label l st = tell [Label l (execWriter st)] +{-| IF .. THEN .. ELSE .. statement.++-} ifThenElse :: Expr Int16 -> Code() -> Code() -> Code() ifThenElse c st1 st2 = tell [IfThenElse c (execWriter st1) (execWriter st2)] +{-| IF .. THEN .. statement.++-} ifThen :: Expr Int16 -> Code() -> Code() ifThen c st = tell [IfThen c (execWriter st)] +{-| FOR .. = .. TO .. STEP .. .. NEXT statement.++-} forStepNext :: Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16 -> Code() -> Code() forStepNext v ini inc step st = tell [ForStepNext v ini inc step (execWriter st)] +{-| FOR .. = .. TO .. .. NEXT statement.++-} forNext :: Expr Int16 -> Expr Int16 -> Expr Int16 -> Code() -> Code() forNext v ini inc st = tell [ForNext v ini inc (execWriter st)] @@ -546,24 +681,86 @@ x = X y = Y z = Z++{-| Array valiables expression.++This expression++@+arr 3+@++evaluated as this expression in IchigoJam BASIC.++@+\[3\]+@+-} arr = Array    ----- Beginner's+-- Commands for beginners -- +{-| LET statement.++This expression++@+let' a [3]+@++evaluated as this statement in IchigoJam BASIC. ++@+LET A,3+@++Also, this expression++@+let' (arr 3) [11,12,13]+@++evaluated as this statement in IchigoJam BASIC.++@+LET[3],11,12,13+@+-} let' :: Expr Int16 -> [Expr Int16] -> Code() let' v1 v2  = tell [Let' v1 v2] +{-| Assignment operator.(\=)++This expression++@+x =: x+u+@++evaluated as this statement in IchigoJam BASIC.++@+X=X+U+@++-} (=:) :: Expr Int16 -> Expr Int16 -> Code() (=:) v1 v2  = tell [Assign v1 v2] infix 2 =: +{-| PRINT statement.++-} print :: (Show r) => Expr r -> Code() print x = tell [Print x] +{-| Concatation operator.(;)++-} (++) :: (Show a, Show b, S.IsString c) => Expr a -> Expr b -> Expr c (++) = Concat infixl 2 ++@@ -656,7 +853,9 @@ chr :: Expr Int16 -> Expr String chr v = Chr [v] --- コンマ区切りで連続表記可+{-|++-} chr' :: [Expr Int16] -> Expr String chr' = Chr @@ -699,7 +898,7 @@   ----- Expert's+-- Commands for experts --  clv :: Code()@@ -757,6 +956,9 @@ out' :: Expr Int16 -> Code() out' v = tell [Out' v] +{-| IN expression.++-} in' = In' in'' = In'' @@ -766,21 +968,39 @@ bin = Bin bin' = Bin' +{-| Bitwise AND operator (&)++-} (.&.) = BitAnd infixl 7 .&. +{-| Bitwise OR operator (|)++-} (.|.) = BitOr infixl 6 .|. +{-| Bitwise XOR expression (^)++-} xor = XOr infixl 7 `xor` +{-| Right shift expression (>>)++-} shiftR = ShiftR infixl 7 `shiftR` +{-| Left shift expression (\<\<)++-} shiftL = ShiftL infixl 7 `shiftL` +{-| Complement expression (~)++-} complement = Complement  bps :: Expr Int16 -> Code()
huckleberry.cabal view
@@ -2,9 +2,9 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                huckleberry-version:             0.9.0.0-synopsis:            haskell EDSL Huckleberry-description:         IchigoJam BASIC on haskell+version:             0.9.0.1+synopsis:            IchigoJam BASIC expressed in Haskell.+description:         The EDSL Provides bridge between IchigoJam BASIC and Haskell. license:             BSD3 license-file:        LICENSE author:              Takamasa Mitsuji@@ -22,3 +22,19 @@   build-depends:       base >=4.7 && <4.8, bytestring >=0.10 && <0.11, serialport >=0.4 && <0.5, mtl >=2.1   -- hs-source-dirs:         default-language:    Haskell2010+++source-repository head+  type:     git+  location: https://github.com/mitsuji/huckleberry.git+++test-suite test+  hs-source-dirs: test+  main-is: test_Huckleberry_V10101.hs+  type: exitcode-stdio-1.0+  build-depends:       base,+                       HUnit >= 1.2.0.0,+                       huckleberry+  default-language:    Haskell2010+
+ test/test_Huckleberry_V10101.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE OverloadedStrings #-}+import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..))+import System.Exit (ExitCode(..), exitWith)+import Data.Char (toUpper)++import Prelude hiding (print,(++),(+),(-),(*),(/),(%),(==),(/=),(>=),(>),(<=),(<),(&&),(||),not,abs,return)+import qualified Prelude as P+import Language.Huckleberry.V10101+++exitProperly :: IO Counts -> IO ()+exitProperly m = do+  counts <- m+  exitWith $ if failures counts P./= 0 P.|| errors counts P./= 0 then ExitFailure 1 else ExitSuccess++testCase :: String -> Assertion -> Test+testCase label assertion = TestLabel label (TestCase assertion)++main :: IO ()+main = exitProperly $ runTestTT $ TestList [ TestList huckleberryTests ]++huckleberryTests :: [Test]+huckleberryTests =+  [ testCase "number literal"        $ "?1234\n"                @=? (translate $ print 1234)+  , testCase "number literal"        $ "?102575\n"              @=? (translate $ print 0x190AF)+  , testCase "string literal"        $ "?\"abcd\"\n"            @=? (translate $ print "abcd")+  , testCase "variable"              $ "?A\n"                   @=? (translate $ print a)+  , testCase "variable"              $ "?A+1\n"                 @=? (translate $ print $ a+1)+  , testCase "array"                 $ "?[8]\n"                 @=? (translate $ print $ arr 8)+  , testCase "array"                 $ "?[A]\n"                 @=? (translate $ print $ arr a)+  , testCase "array"                 $ "?[A+1]\n"               @=? (translate $ print $ arr (a+1))+  , testCase "++"                    $ "?\"abc\";\"def\"\n"     @=? (translate $ print $ "abc" ++ "def")+  , testCase "++"                    $ "?1234;5678\n"           @=? (translate $ print $ 1234 ++ 5678)+  , testCase "++"                    $ "?\"abc\";5678\n"        @=? (translate $ print $ "abc" ++ 5678)+  , testCase "++"                    $ "?1234;\"def\"\n"        @=? (translate $ print $ 1234 ++ "def")+  , testCase "let'"                  $ "LETA,1\n"               @=? (translate $ let' a [1])+  , testCase "let'"                  $ "LETA+1,1\n"             @=? (translate $ let' (a+1) [1])+  , testCase "let'"                  $ "LETA,1,2,3\n"           @=? (translate $ let' a [1,2,3])+  , testCase "let'"                  $ "LETA+1,1,2,3\n"         @=? (translate $ let' (a+1) [1,2,3])+  , testCase "let'"                  $ "LET[8],1,2,3\n"         @=? (translate $ let' (arr 8) [1,2,3])+  , testCase "let'"                  $ "LET[A],A+1,2,3\n"       @=? (translate $ let' (arr a) [a+1,2,3])+  , testCase "let'"                  $ "LET[A+1],1,2,3\n"       @=? (translate $ let' (arr (a+1)) [1,2,3])+  , testCase "=:"                    $ "A=1\n"                  @=? (translate $ a=:1)+  , testCase "=:"                    $ "A=B\n"                  @=? (translate $ a=:b)+  , testCase "ifThenElse"            $ "IFA=B?\"S\"ELSE?\"N\"\n"+    @=? (translate $ ifThenElse (a==b) (print "S") (print "N"))+  , testCase "ifThen"                $ "IFA=B?\"S\"\n"+    @=? (translate $ ifThen (a==b) (print "S"))+  , testCase "forStepNext"           $ "FORA=0TO99STEP2:?[A+1]+2:NEXT\n"+    @=? (translate $ forStepNext a 0 99 2 (print $ arr (a+1) +2))+  , testCase "forNext"             $ "FORA=0TO99:?[A+1]+2:NEXT\n"+    @=? (translate $ forNext a 0 99 (print $ arr (a+1) +2))+  , testCase "pre"                   $ "?(A-1)*(B+1)\n"         @=? (translate $ print $ pre(a-1)*pre(b+1))+  , testCase "pre"                   $ "?A-1*B+1\n"             @=? (translate $ print $ (a-1)*(b+1))+  , testCase "led"                   $ "LEDA+1\n"               @=? (translate $ led (a+1))+  , testCase "wait"                  $ "WAITA+1\n"              @=? (translate $ wait(a+1))+  , testCase "run"                   $ "RUN\n"                  @=? (translate $ run)+  , testCase "list"                  $ "LISTA+1,B+2\n"          @=? (translate $ list (a+1) (b+2))+  , testCase "list'"                 $ "LIST\n"                 @=? (translate $ list')+  , testCase "goto"                  $ "GOTOA+1\n"              @=? (translate $ goto (a+1))+  , testCase "end"                   $ "END\n"                  @=? (translate $ end)+  , testCase "btn"                   $ "?BTN(A+1)+2\n"          @=? (translate $ print $ (btn (a+1)) +2)+  , testCase "new"                   $ "NEW\n"                  @=? (translate $ new)+  , testCase "locate"                $ "LCA+1,B+2\n"            @=? (translate $ locate (a+1) (b+2))+  , testCase "cls"                   $ "CLS\n"                  @=? (translate $ cls)+  , testCase "rnd"                   $ "?RND(A+1)+2\n"          @=? (translate $ print $ (rnd (a+1)) +2)+  , testCase "save"                  $ "SAVEA+1\n"              @=? (translate $ save (a+1))+  , testCase "save'"                 $ "SAVE\n"                 @=? (translate $ save')+  , testCase "load"                  $ "LOADA+1\n"              @=? (translate $ load (a+1))+  , testCase "load'"                 $ "LOAD\n"                 @=? (translate $ load')+  , testCase "files"                 $ "FILESA+1\n"             @=? (translate $ files (a+1))+  , testCase "beep"                  $ "BEEPA+1,B+2\n"          @=? (translate $ beep (a+1) (b+2))+  , testCase "beep'"                 $ "BEEP\n"                 @=? (translate $ beep')+  , testCase "play"                  $ "PLAY\"ABCD\"\n"         @=? (translate $ play "ABCD")+  , testCase "play'"                 $ "PLAY\n"                 @=? (translate $ play')+  , testCase "tempo"                 $ "TEMPOA+1\n"             @=? (translate $ tempo (a+1))+  , testCase "+"                     $ "?A+B\n"                 @=? (translate $ print $ a+b)+  , testCase "-"                     $ "?A-B\n"                 @=? (translate $ print $ a-b)+  , testCase "*"                     $ "?A*B\n"                 @=? (translate $ print $ a*b)+  , testCase "/"                     $ "?A/B\n"                 @=? (translate $ print $ a/b)+  , testCase "%"                     $ "?A%B\n"                 @=? (translate $ print $ a%b)+  , testCase "input"                 $ "INPUT\"Q?\",A\n"        @=? (translate $ input "Q?" a)+  , testCase "tick"                  $ "?TICK()+1\n"            @=? (translate $ print $ tick +1)+  , testCase "clt"                   $ "CLT\n"                  @=? (translate $ clt)+  , testCase "inkey"                 $ "?INKEY()+1\n"           @=? (translate $ print $ inkey +1)+  , testCase "chr"                   $ "?CHR$(A+1);\"def\"\n"   @=? (translate $ print $ chr (a+1) ++ "def")+  , testCase "chr'"                  $ "?CHR$(65,66,67)\n"      @=? (translate $ print $ chr'[65,66,67])+  , testCase "asc"                   $ "?ASC(\"abcd\")\n"       @=? (translate $ print $ asc "abcd")+  , testCase "scroll"                $ "SCROLLA+1\n"            @=? (translate $ scroll (a+1))+  , testCase "scr"                   $ "?SCR(A+1,B+2)+2\n"      @=? (translate $ print $ (scr (a+1) (b+2))+2)+  , testCase "scr'"                  $ "?SCR()+1\n"             @=? (translate $ print $ scr'+1)+  , testCase "vpeek"                 $ "?SCR(A+1,B+2)+2\n"      @=? (translate $ print $ (vpeek (a+1) (b+2))+2)+  , testCase "vpeek'"                $ "?SCR()+1\n"             @=? (translate $ print $ vpeek'+1)+  , testCase "=="                    $ "?A=B\n"                 @=? (translate $ print $ a==b)+  , testCase "/="                    $ "?A!=B\n"                @=? (translate $ print $ a/=b)+  , testCase ">="                    $ "?A>=B\n"                @=? (translate $ print $ a>=b)+  , testCase ">"                     $ "?A>B\n"                 @=? (translate $ print $ a>b)+  , testCase "<="                    $ "?A<=B\n"                @=? (translate $ print $ a<=b)+  , testCase "<"                     $ "?A<B\n"                 @=? (translate $ print $ a<b)+  , testCase "&&"                    $ "?AANDB\n"               @=? (translate $ print $ a&&b)+  , testCase "||"                    $ "?AORB\n"                @=? (translate $ print $ a||b)+  , testCase "not"                   $ "?!A\n"                  @=? (translate $ print $ not a)+  , testCase "clv"                   $ "CLV\n"                  @=? (translate $ clv)+  , testCase "clear"                 $ "CLV\n"                  @=? (translate $ clear)+  , testCase "clk"                   $ "CLK\n"                  @=? (translate $ clk)+  , testCase "abs"                   $ "?ABS(A+1)+2\n"          @=? (translate $ print $ (abs (a+1)) +2)+  , testCase "gosub"                 $ "GOSUBA+1\n"             @=? (translate $ gosub (a+1))+  , testCase "return"                $ "RETURN\n"               @=? (translate $ return)+  , testCase "sound"                 $ "?SOUND()+1\n"           @=? (translate $ print $ sound +1)+  , testCase "free"                  $ "?FREE()+1\n"            @=? (translate $ print $ free +1)+  , testCase "ver"                   $ "?VER()+1\n"             @=? (translate $ print $ ver +1)+  , testCase "renum"                 $ "RENUMA+1\n"             @=? (translate $ renum (a+1))+  , testCase "renum'"                $ "RENUM\n"                @=? (translate $ renum')+  , testCase "lrun"                  $ "LRUNA+1\n"              @=? (translate $ lrun (a+1))+  , testCase "file"                  $ "?FILE()+1\n"            @=? (translate $ print $ file +1)+  , testCase "sleep"                 $ "SLEEP\n"                @=? (translate $ sleep)+  , testCase "video"                 $ "VIDEOA+1\n"             @=? (translate $ video (a+1))+  , testCase "peek"                  $ "?PEEK(A+1)+2\n"         @=? (translate $ print $ (peek (a+1)) +2)+  , testCase "poke"                  $ "POKEA+1,B+2\n"          @=? (translate $ poke (a+1) (b+2))+  , testCase "clp"                   $ "CLP\n"                  @=? (translate $ clp)+  , testCase "help"                  $ "HELP\n"                 @=? (translate $ help)+  , testCase "ana"                   $ "?ANA(A+1)+2\n"          @=? (translate $ print $ (ana (a+1)) +2)+  , testCase "out"                   $ "OUTA+1,B+2\n"           @=? (translate $ out (a+1) (b+2))+  , testCase "out'"                  $ "OUTA+1\n"               @=? (translate $ out' (a+1))+  , testCase "in'"                   $ "?IN(A+1)+2\n"           @=? (translate $ print $ (in' (a+1)) +2)+  , testCase "in''"                  $ "?IN()+1\n"              @=? (translate $ print $ in'' +1)+  , testCase "hex"                   $ "?HEX$(A+1,B+2);\"A\"\n" @=? (translate $ print $ hex (a+1) (b+2) ++ "A")+  , testCase "hex'"                  $ "?HEX$(A+1);\"A\"\n"     @=? (translate $ print $ hex' (a+1) ++ "A")+  , testCase "bin"                   $ "?BIN$(A+1,B+2);\"A\"\n" @=? (translate $ print $ bin (a+1) (b+2) ++ "A")+  , testCase "bin'"                  $ "?BIN$(A+1);\"A\"\n"     @=? (translate $ print $ bin' (a+1) ++ "A")+  , testCase ".&."                   $ "?A&B\n"                 @=? (translate $ print $ a.&.b)+  , testCase ".|."                   $ "?A|B\n"                 @=? (translate $ print $ a.|.b)+  , testCase "xor"                   $ "?A^B\n"                 @=? (translate $ print $ a`xor`b)+  , testCase "shiftR"                $ "?A>>B\n"                @=? (translate $ print $ a`shiftR`b)+  , testCase "shiftL"                $ "?A<<B\n"                @=? (translate $ print $ a`shiftL`b)+  , testCase "complement"            $ "?~A\n"                  @=? (translate $ print $ complement a)+  , testCase "bps"                   $ "BPSA+1\n"               @=? (translate $ bps (a+1))+  , testCase "i2cr"                  $ "?I2CR(A+1,B+2,C+3,D+4,E+5)+2\n"+    @=? (translate $ print $ (i2cr (a+1) (b+2) (c+3) (d+4) (e+5)) +2)+  , testCase "i2cw"                  $ "?I2CW(A+1,B+2,C+3,D+4,E+5)+2\n"+    @=? (translate $ print $ (i2cw (a+1) (b+2) (c+3) (d+4) (e+5)) +2)+  , testCase "usr"                   $ "?USR(A+1,B+2)+2\n"      @=? (translate $ print $ (usr (a+1) (b+2)) +2)++  ]+