huckleberry-0.9.0.2: src/Language/Huckleberry/V10101.hs
{-# 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
,label
,ifThenElse
,ifThen
,forStepNext
,forNext
,a
,b
,c
,d
,e
,f
,g
,h
,i
,j
,k
,l
,m
,n
,o
,p
,q
,r
,s
,t
,u
,v
,w
,x
,y
,z
,arr
-- * Commands for beginners
,let'
,(=:)
,print
,(++)
,led
,wait
,run
,list
,list'
,goto
,end
,btn
,new
,locate
,cls
,rnd
,save
,save'
,load
,load'
,files
,beep
,beep'
,play
,play'
,tempo
,(+)
,(-)
,(*)
,(/)
,(%)
,input
,tick
,clt
,inkey
,chr
,chr'
,asc
,scroll
,scr
,scr'
,vpeek
,vpeek'
,(==)
,(/=)
,(>=)
,(>)
,(<=)
,(<)
,(&&)
,(||)
,not
-- * Commands for experts
,clv
,clear
,clk
,abs
,gosub
,return
,sound
,free
,ver
,renum
,renum'
,lrun
,file
,sleep
,video
,peek
,poke
,clp
,help
,ana
,out
,out'
,in'
,in''
,hex
,hex'
,bin
,bin'
,(.&.)
,(.|.)
,xor
,shiftR
,shiftL
,complement
,bps
,i2cr
,i2cw
,usr
) where
import Prelude hiding (print,(++),(+),(-),(*),(/),(%),(==),(/=),(>=),(>),(<=),(<),(&&),(||),not,abs,return)
import Data.Int(Int16)
import Data.List(intercalate)
import qualified Prelude as P
import qualified Data.String as S
import Control.Monad.Writer(Writer,execWriter,tell)
import qualified IchigoJam as IJ
data Expr r where
Number :: (Num r) => r -> Expr r
Str :: (S.IsString r) => r -> Expr r
-- Bracket operator
Pre :: Expr Int16 -> Expr Int16
A :: Expr Int16
B :: Expr Int16
C :: Expr Int16
D :: Expr Int16
E :: Expr Int16
F :: Expr Int16
G :: Expr Int16
H :: Expr Int16
I :: Expr Int16
J :: Expr Int16
K :: Expr Int16
L :: Expr Int16
M :: Expr Int16
N :: Expr Int16
O :: Expr Int16
P :: Expr Int16
Q :: Expr Int16
R :: Expr Int16
S :: Expr Int16
T :: Expr Int16
U :: Expr Int16
V :: Expr Int16
W :: Expr Int16
X :: Expr Int16
Y :: Expr Int16
Z :: Expr Int16
Array :: Expr Int16 -> Expr Int16
Concat :: (Show a, Show b, S.IsString c) => Expr a -> Expr b -> Expr c
--
-- Commands for beginners
--
-- [TODO] [num]:0(button)/UP/DOWN/RIGHT/LEFT/SPACE, defautl 0
Btn :: Expr Int16 -> Expr Int16
Rnd :: Expr Int16 -> Expr Int16
Add :: Expr Int16 -> Expr Int16 -> Expr Int16
Subtract :: Expr Int16 -> Expr Int16 -> Expr Int16
Multiply :: Expr Int16 -> Expr Int16 -> Expr Int16
Divide :: Expr Int16 -> Expr Int16 -> Expr Int16
Remind :: Expr Int16 -> Expr Int16 -> Expr Int16
Tick :: Expr Int16
Inkey :: Expr Int16
Chr :: [Expr Int16] -> Expr String
Asc :: String -> Expr Int16
Scr :: Expr Int16 -> Expr Int16 -> Expr Int16
Scr' :: Expr Int16
Equal :: Expr Int16 -> Expr Int16 -> Expr Int16
NotEqual :: Expr Int16 -> Expr Int16 -> Expr Int16
GreaterThanEqual :: Expr Int16 -> Expr Int16 -> Expr Int16
GreaterThan :: Expr Int16 -> Expr Int16 -> Expr Int16
LessThanEqual :: Expr Int16 -> Expr Int16 -> Expr Int16
LessThan :: Expr Int16 -> Expr Int16 -> Expr Int16
And :: Expr Int16 -> Expr Int16 -> Expr Int16
Or :: Expr Int16 -> Expr Int16 -> Expr Int16
Not :: Expr Int16 -> Expr Int16
--
-- Commands for experts
--
Abs :: Expr Int16 -> Expr Int16
Sound :: Expr Int16
Free :: Expr Int16
Ver :: Expr Int16
File :: Expr Int16
Peek :: Expr Int16 -> Expr Int16
Ana :: Expr Int16 -> Expr Int16
In' :: Expr Int16 -> Expr Int16
In'' :: Expr Int16
Hex :: Expr Int16 -> Expr Int16 -> Expr String
Hex' :: Expr Int16 -> Expr String
Bin :: Expr Int16 -> Expr Int16 -> Expr String
Bin' :: Expr Int16 -> Expr String
BitAnd :: Expr Int16 -> Expr Int16 -> Expr Int16
BitOr :: Expr Int16 -> Expr Int16 -> Expr Int16
XOr :: Expr Int16 -> Expr Int16 -> Expr Int16
ShiftR :: Expr Int16 -> Expr Int16 -> Expr Int16
ShiftL :: Expr Int16 -> Expr Int16 -> Expr Int16
Complement :: Expr Int16 -> Expr Int16
I2CR :: Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16
I2CW :: Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16 -> Expr Int16
USR :: Expr Int16 -> Expr Int16 -> Expr Int16
-- Num Literal
instance (Num a) => Num (Expr a) where
(+) (Number n1) (Number n2) = Number (n1 P.+ n2)
(-) (Number n1) (Number n2) = Number (n1 P.- n2)
(*) (Number n1) (Number n2) = Number (n1 P.* n2)
negate (Number n) = Number (negate n)
abs (Number n) = Number (P.abs n)
signum (Number n) = Number (signum n)
fromInteger n = Number (fromInteger n)
-- OverloadedStrings
instance (S.IsString a) => S.IsString (Expr a) where
fromString s = Str (S.fromString s)
data Stmt where
Label :: Int16 -> [Stmt] -> Stmt
-- 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
ForNext :: Expr Int16 -> Expr Int16 -> Expr Int16 -> [Stmt] -> Stmt
--
-- Commands for beginners
--
Let' :: Expr Int16 -> [Expr Int16] -> Stmt
Assign :: Expr Int16 -> Expr Int16 -> Stmt
Print :: (Show r) => Expr r -> Stmt
Led :: Expr Int16 -> Stmt
Wait :: Expr Int16 -> Stmt
Run :: Stmt
List :: Expr Int16 -> Expr Int16 -> Stmt
List' :: Stmt
Goto :: Expr Int16 -> Stmt
End :: Stmt
New :: Stmt
Locate :: Expr Int16 -> Expr Int16 -> Stmt
Cls :: Stmt
Save :: Expr Int16 -> Stmt
Save' :: Stmt
Load :: Expr Int16 -> Stmt
Load' :: Stmt
Files :: Expr Int16 -> Stmt
Beep :: Expr Int16 -> Expr Int16 -> Stmt
Beep' :: Stmt
Play :: String -> Stmt
Play' :: Stmt
Tempo :: Expr Int16 -> Stmt
Input :: String -> Expr Int16 -> Stmt
Clt :: Stmt
Scroll :: Expr Int16 -> Stmt
--
-- Commands for experts
--
Clv :: Stmt
Clk :: Stmt
Gosub :: Expr Int16 -> Stmt
Return :: Stmt
Renum :: Expr Int16 -> Stmt
Renum' :: Stmt
LRun :: Expr Int16 -> Stmt
Sleep :: Stmt
Video :: Expr Int16 -> Stmt
Poke :: Expr Int16 -> Expr Int16 -> Stmt
Clp :: Stmt
Help :: Stmt
Out :: Expr Int16 -> Expr Int16 -> Stmt
Out' :: Expr Int16 -> Stmt
Bps :: Expr Int16 -> Stmt
reify :: (Show r) => Expr r -> String
reify (Number v) = show v
reify (Str v) = show v
reify (Pre v) = concat ["(", reify v, ")"]
reify (A) = "A"
reify (B) = "B"
reify (C) = "C"
reify (D) = "D"
reify (E) = "E"
reify (F) = "F"
reify (G) = "G"
reify (H) = "H"
reify (I) = "I"
reify (J) = "J"
reify (K) = "K"
reify (L) = "L"
reify (M) = "M"
reify (N) = "N"
reify (O) = "O"
reify (P) = "P"
reify (Q) = "Q"
reify (R) = "R"
reify (S) = "S"
reify (T) = "T"
reify (U) = "U"
reify (V) = "V"
reify (W) = "W"
reify (X) = "X"
reify (Y) = "Y"
reify (Z) = "Z"
reify (Array i) = concat ["[", reify i, "]"]
reify (Concat v1 v2) = concat [reify v1, ";", reify v2]
reify (Btn v) = concat ["BTN(", reify v, ")"]
reify (Rnd v) = concat ["RND(", reify v, ")"]
reify (Add v1 v2) = concat [reify v1, "+", reify v2]
reify (Subtract v1 v2) = concat [reify v1, "-", reify v2]
reify (Multiply v1 v2) = concat [reify v1, "*", reify v2]
reify (Divide v1 v2) = concat [reify v1, "/", reify v2]
reify (Remind v1 v2) = concat [reify v1, "%", reify v2]
reify (Tick) = "TICK()"
reify (Inkey) = "INKEY()"
reify (Chr v) = concat ["CHR$(",(intercalate "," (fmap reify v)), ")"]
reify (Asc v) = concat ["ASC(\"", v, "\")"]
reify (Scr') = concat ["SCR()"]
reify (Scr v1 v2) = concat ["SCR(", reify v1, ",", reify v2, ")"]
reify (Equal v1 v2) = concat [reify v1, "=", reify v2]
reify (NotEqual v1 v2) = concat [reify v1, "!=", reify v2]
reify (GreaterThanEqual v1 v2) = concat [reify v1, ">=", reify v2]
reify (GreaterThan v1 v2) = concat [reify v1, ">", reify v2]
reify (LessThanEqual v1 v2) = concat [reify v1, "<=", reify v2]
reify (LessThan v1 v2) = concat [reify v1, "<", reify v2]
reify (And v1 v2) = concat [reify v1, "AND", reify v2]
reify (Or v1 v2) = concat [reify v1, "OR", reify v2]
reify (Not v) = concat ["!", reify v]
reify (Abs v) = concat ["ABS(", reify v, ")"]
reify (Sound) = "SOUND()"
reify (Free) = "FREE()"
reify (Ver) = "VER()"
reify (File) = "FILE()"
reify (Peek v) = concat ["PEEK(", reify v, ")"]
reify (Ana v) = concat ["ANA(", reify v, ")"]
reify (In' v) = concat ["IN(", reify v, ")"]
reify (In'') = concat ["IN()"]
reify (Hex v1 v2) = concat ["HEX$(", reify v1, ",", reify v2, ")"]
reify (Hex' v) = concat ["HEX$(", reify v, ")"]
reify (Bin v1 v2) = concat ["BIN$(", reify v1, ",", reify v2, ")"]
reify (Bin' v) = concat ["BIN$(", reify v, ")"]
reify (BitAnd v1 v2) = concat [reify v1, "&", reify v2]
reify (BitOr v1 v2) = concat [reify v1, "|", reify v2]
reify (XOr v1 v2) = concat [reify v1, "^", reify v2]
reify (ShiftR v1 v2) = concat [reify v1, ">>", reify v2]
reify (ShiftL v1 v2) = concat [reify v1, "<<", reify v2]
reify (Complement v) = concat ["~", reify v]
reify (I2CR v1 v2 v3 v4 v5) = concat ["I2CR(", reify v1, ",", reify v2, ",", reify v3, ",", reify v4, ",", reify v5, ")"]
reify (I2CW v1 v2 v3 v4 v5) = concat ["I2CW(", reify v1, ",", reify v2, ",", reify v3, ",", reify v4, ",", reify v5, ")"]
reify (USR v1 v2) = concat ["USR(", reify v1, ",", reify v2, ")"]
lToString :: [Stmt] -> String
lToString st = intercalate ":" $ map toString st
toString :: Stmt -> String
toString (Label n st) = concat [(show n), " ", lToString st]
toString (IfThenElse c st1 st2) = concat ["IF", reify c, lToString st1, "ELSE", lToString st2]
toString (IfThen c st) = concat ["IF", reify c, lToString st]
toString (ForStepNext v ini inc step st) = concat ["FOR", reify v, "=", reify ini, "TO", reify inc, "STEP", reify step, ":", lToString st, ":NEXT"]
toString (ForNext v ini inc st) = concat ["FOR", reify v, "=", reify ini, "TO", reify inc, ":", lToString st, ":NEXT"]
toString (Let' v1 v2) = concat ["LET", reify v1, ",", (intercalate "," (fmap reify v2))]
toString (Assign v1 v2) = concat [reify v1, "=", reify v2]
toString (Print v) = concat ["?", reify v]
toString (Led v) = concat ["LED", reify v]
toString (Wait v) = concat ["WAIT", reify v]
toString (Run) = "RUN"
toString (List v1 v2) = concat ["LIST", reify v1, ",", reify v2]
toString (List') = "LIST"
toString (Goto v) = concat ["GOTO", reify v]
toString (End) = "END"
toString (New) = "NEW"
toString (Locate v1 v2) = concat ["LC", reify v1, ",", reify v2]
toString (Cls) = "CLS"
toString (Save v) = concat ["SAVE", reify v]
toString (Save') = "SAVE"
toString (Load v) = concat ["LOAD", reify v]
toString (Load') = "LOAD"
toString (Files v) = concat ["FILES", reify v]
toString (Beep v1 v2) = concat ["BEEP", reify v1, ",", reify v2]
toString (Beep') = "BEEP"
toString (Play v) = concat ["PLAY\"", v, "\""]
toString (Play') = "PLAY"
toString (Tempo v) = concat ["TEMPO", reify v]
toString (Input v1 v2) = concat ["INPUT\"", v1, "\",", reify v2]
toString (Clt) = "CLT"
toString (Scroll v) = concat ["SCROLL", reify v]
toString (Clv) = "CLV"
toString (Clk) = "CLK"
toString (Gosub v) = concat ["GOSUB", reify v]
toString (Return) = "RETURN"
toString (Renum v) = concat ["RENUM", reify v]
toString (Renum') = "RENUM"
toString (LRun v) = concat ["LRUN", reify v]
toString (Sleep) = "SLEEP"
toString (Video v) = concat ["VIDEO", reify v]
toString (Poke v1 v2) = concat ["POKE", reify v1, ",", reify v2]
toString (Clp) = "CLP"
toString (Help) = "HELP"
toString (Out v1 v2) = concat ["OUT", reify v1, ",", reify v2]
toString (Out' v) = concat ["OUT", reify v]
toString (Bps v) = concat ["BPS", reify v]
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)]
a = A
b = B
c = C
d = D
e = E
f = F
g = G
h = H
i = I
j = J
k = K
l = L
m = M
n = N
o = O
p = P
q = Q
r = R
s = S
t = T
u = U
v = V
w = W
x = X
y = Y
z = Z
{-| Array valiables expression.
This expression
@
arr 3
@
evaluated as this expression in IchigoJam BASIC.
@
\[3\]
@
-}
arr = Array
--
-- 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 ++
led :: Expr Int16 -> Code()
led s = tell [Led s]
wait :: Expr Int16 -> Code()
wait t = tell [Wait t]
run :: Code()
run = tell [Run]
list :: Expr Int16 -> Expr Int16 -> Code()
list v1 v2 = tell [List v1 v2]
list' :: Code()
list' = tell [List']
goto :: Expr Int16 -> Code()
goto t = tell [Goto t]
end :: Code()
end = tell [End]
btn = Btn
new :: Code()
new = tell [New]
locate :: Expr Int16 -> Expr Int16 -> Code()
locate v1 v2 = tell [Locate v1 v2]
cls :: Code()
cls = tell [Cls]
rnd = Rnd
save :: Expr Int16 -> Code()
save v = tell [Save v]
save' :: Code()
save' = tell [Save']
load :: Expr Int16 -> Code()
load v = tell [Load v]
load' :: Code()
load' = tell [Load']
files :: Expr Int16 -> Code()
files v = tell [Files v]
beep :: Expr Int16 -> Expr Int16 -> Code()
beep v1 v2 = tell [Beep v1 v2]
beep' :: Code()
beep' = tell [Beep']
play :: String -> Code()
play c = tell [Play c]
play' :: Code()
play' = tell [Play']
tempo :: Expr Int16 -> Code()
tempo t = tell [Tempo t]
(+) = Add
infixl 6 +
(-) = Subtract
infixl 6 -
(*) = Multiply
infixl 7 *
(/) = Divide
infixl 7 /
(%) = Remind
infixl 7 %
input :: String -> Expr Int16 -> Code()
input s v = tell [Input s v]
tick = Tick
clt :: Code()
clt = tell [Clt]
inkey = Inkey
chr :: Expr Int16 -> Expr String
chr v = Chr [v]
{-|
-}
chr' :: [Expr Int16] -> Expr String
chr' = Chr
asc = Asc
scroll :: Expr Int16 -> Code()
scroll v = tell [Scroll v]
scr = Scr
scr' = Scr'
vpeek = scr -- alias
vpeek' = scr' -- alias
(==) = Equal
infix 5 ==
(/=) = NotEqual
infix 5 /=
(>=) = GreaterThanEqual
infix 5 >=
(>) = GreaterThan
infix 5 >
(<=) = LessThanEqual
infix 5 <=
(<) = LessThan
infix 5 <
(&&) = And
infixr 4 &&
(||) = Or
infixr 3 ||
not = Not
--
-- Commands for experts
--
clv :: Code()
clv = tell [Clv]
clear = clv -- alias
clk :: Code()
clk = tell [Clk]
abs = Abs
gosub :: Expr Int16 -> Code()
gosub t = tell [Gosub t]
return :: Code()
return = tell [Return]
sound = Sound
free = Free
ver = Ver
renum :: Expr Int16 -> Code()
renum v = tell [Renum v]
renum' :: Code()
renum' = tell [Renum']
lrun :: Expr Int16 -> Code()
lrun v = tell [LRun v]
file = File
sleep :: Code()
sleep = tell [Sleep]
video :: Expr Int16 -> Code()
video sw = tell [Video sw]
peek = Peek
poke :: Expr Int16 -> Expr Int16 -> Code()
poke v1 v2 = tell [Poke v1 v2]
clp :: Code()
clp = tell [Clp]
help :: Code()
help = tell [Help]
ana = Ana
out :: Expr Int16 -> Expr Int16 -> Code()
out v1 v2 = tell [Out v1 v2]
out' :: Expr Int16 -> Code()
out' v = tell [Out' v]
{-| IN expression.
-}
in' = In'
in'' = In''
hex = Hex
hex' = Hex'
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()
bps s = tell [Bps s]
i2cr = I2CR
i2cw = I2CW
usr = USR