arduino-copilot 0.0.1 → 1.0.0
raw patch · 22 files changed
+867/−460 lines, 22 filesdep +optparse-applicativePVP ok
version bump matches the API change (PVP)
Dependencies added: optparse-applicative
API changes (from Hackage documentation)
- Arduino: (=:) :: Output t -> Stream t -> Sketch
- Arduino: (@:) :: Output t -> Stream Bool -> Output t
- Arduino: Pin :: Int -> Pin
- Arduino: arduino :: Sketch -> IO ()
- Arduino: boolInput :: Pin -> Input Bool
- Arduino: boolInput' :: Pin -> [Bool] -> Input Bool
- Arduino: data Output t
- Arduino: delay :: Output MicroSeconds
- Arduino: firstIteration :: Stream Bool
- Arduino: infixr 1 =:
- Arduino: instance Arduino.ToFramework (Arduino.Input' t)
- Arduino: instance Arduino.ToFramework (Arduino.Output t)
- Arduino: instance GHC.Base.Monoid Arduino.Framework
- Arduino: instance GHC.Base.Semigroup Arduino.Framework
- Arduino: led :: Output Bool
- Arduino: newtype Pin
- Arduino: sketchSpec :: Sketch -> Spec
- Arduino: type Input t = Sketch' (Stream t)
- Arduino: type MicroSeconds = Int16
- Arduino: type Sketch = Sketch' ()
+ Copilot.Arduino: (!!) :: (Typed a, Eq b, Num b, Typed b) => [Stream a] -> Stream b -> Stream a
+ Copilot.Arduino: (#) :: (KnownSymbol s, Typed t, Typed a, Struct a) => Stream a -> (a -> Field s t) -> Stream t
+ Copilot.Arduino: ($!) :: () => (a -> b) -> a -> b
+ Copilot.Arduino: ($) :: () => (a -> b) -> a -> b
+ Copilot.Arduino: (&&) :: Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: (*) :: Num a => a -> a -> a
+ Copilot.Arduino: (**) :: Floating a => a -> a -> a
+ Copilot.Arduino: (*>) :: Applicative f => f a -> f b -> f b
+ Copilot.Arduino: (+) :: Num a => a -> a -> a
+ Copilot.Arduino: (++) :: Typed a => [a] -> Stream a -> Stream a
+ Copilot.Arduino: (-) :: Num a => a -> a -> a
+ Copilot.Arduino: (.!!) :: (KnownNat n, t' ~ InnerType t, Flatten t t', Typed t, Typed t') => Stream (Array n t) -> Stream Word32 -> Stream t
+ Copilot.Arduino: (.&.) :: Bits a => a -> a -> a
+ Copilot.Arduino: (.) :: () => (b -> c) -> (a -> b) -> a -> c
+ Copilot.Arduino: (.<<.) :: (Bits a, Typed a, Typed b, Integral b) => Stream a -> Stream b -> Stream a
+ Copilot.Arduino: (.>>.) :: (Bits a, Typed a, Typed b, Integral b) => Stream a -> Stream b -> Stream a
+ Copilot.Arduino: (.^.) :: Bits a => a -> a -> a
+ Copilot.Arduino: (.|.) :: Bits a => a -> a -> a
+ Copilot.Arduino: (/) :: Fractional a => a -> a -> a
+ Copilot.Arduino: (/=) :: (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
+ Copilot.Arduino: (<$) :: Functor f => a -> f b -> f a
+ Copilot.Arduino: (<$>) :: Functor f => (a -> b) -> f a -> f b
+ Copilot.Arduino: (<) :: (Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
+ Copilot.Arduino: (<*) :: Applicative f => f a -> f b -> f a
+ Copilot.Arduino: (<*>) :: Applicative f => f (a -> b) -> f a -> f b
+ Copilot.Arduino: (<=) :: (Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
+ Copilot.Arduino: (<>) :: Semigroup a => a -> a -> a
+ Copilot.Arduino: (=:) :: Output t -> Stream t -> Sketch ()
+ Copilot.Arduino: (=<<) :: Monad m => (a -> m b) -> m a -> m b
+ Copilot.Arduino: (==) :: (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
+ Copilot.Arduino: (==>) :: Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: (>) :: (Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
+ Copilot.Arduino: (>=) :: (Ord a, Typed a) => Stream a -> Stream a -> Stream Bool
+ Copilot.Arduino: (>>) :: Monad m => m a -> m b -> m b
+ Copilot.Arduino: (>>=) :: Monad m => m a -> (a -> m b) -> m b
+ Copilot.Arduino: (@:) :: Output t -> Stream Bool -> Output t
+ Copilot.Arduino: (^) :: (Typed a, Typed b, Num a, Bits a, Integral b) => Stream a -> Stream b -> Stream a
+ Copilot.Arduino: (^^) :: (Fractional a, Integral b) => a -> b -> a
+ Copilot.Arduino: (||) :: Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: EQ :: Ordering
+ Copilot.Arduino: False :: Bool
+ Copilot.Arduino: Field :: t -> Field t
+ Copilot.Arduino: GT :: Ordering
+ Copilot.Arduino: Just :: a -> Maybe a
+ Copilot.Arduino: LT :: Ordering
+ Copilot.Arduino: Left :: a -> Either a b
+ Copilot.Arduino: Nothing :: Maybe a
+ Copilot.Arduino: Right :: b -> Either a b
+ Copilot.Arduino: True :: Bool
+ Copilot.Arduino: [Array] :: forall a (n :: Nat) t. (KnownNat n, Typed t, Typed (InnerType t), Flatten t (InnerType t)) => Type t -> Type (Array n t)
+ Copilot.Arduino: [Bool] :: forall a. () => Type Bool
+ Copilot.Arduino: [Double] :: forall a. () => Type Double
+ Copilot.Arduino: [Float] :: forall a. () => Type Float
+ Copilot.Arduino: [Int16] :: forall a. () => Type Int16
+ Copilot.Arduino: [Int32] :: forall a. () => Type Int32
+ Copilot.Arduino: [Int64] :: forall a. () => Type Int64
+ Copilot.Arduino: [Int8] :: forall a. () => Type Int8
+ Copilot.Arduino: [SArray] :: forall t. () => Type t -> SimpleType
+ Copilot.Arduino: [SBool] :: () => SimpleType
+ Copilot.Arduino: [SDouble] :: () => SimpleType
+ Copilot.Arduino: [SFloat] :: () => SimpleType
+ Copilot.Arduino: [SInt16] :: () => SimpleType
+ Copilot.Arduino: [SInt32] :: () => SimpleType
+ Copilot.Arduino: [SInt64] :: () => SimpleType
+ Copilot.Arduino: [SInt8] :: () => SimpleType
+ Copilot.Arduino: [SStruct] :: () => SimpleType
+ Copilot.Arduino: [SWord16] :: () => SimpleType
+ Copilot.Arduino: [SWord32] :: () => SimpleType
+ Copilot.Arduino: [SWord64] :: () => SimpleType
+ Copilot.Arduino: [SWord8] :: () => SimpleType
+ Copilot.Arduino: [Struct] :: forall a. (Typed a, Struct a) => a -> Type a
+ Copilot.Arduino: [UType] :: forall a. Typeable a => {uTypeType :: Type a} -> UType
+ Copilot.Arduino: [Value] :: forall a (s :: Symbol) t. (Typeable t, KnownSymbol s, Show t) => Type t -> Field s t -> Value a
+ Copilot.Arduino: [Word16] :: forall a. () => Type Word16
+ Copilot.Arduino: [Word32] :: forall a. () => Type Word32
+ Copilot.Arduino: [Word64] :: forall a. () => Type Word64
+ Copilot.Arduino: [Word8] :: forall a. () => Type Word8
+ Copilot.Arduino: aMajority :: (Eq a, Typed a) => [Stream a] -> Stream a -> Stream Bool
+ Copilot.Arduino: abs :: Num a => a -> a
+ Copilot.Arduino: accessorname :: (Struct a, KnownSymbol s) => (a -> Field s t) -> String
+ Copilot.Arduino: acos :: Floating a => a -> a
+ Copilot.Arduino: acosh :: Floating a => a -> a
+ Copilot.Arduino: all :: Foldable t => (a -> Bool) -> t a -> Bool
+ Copilot.Arduino: always :: Integral a => a -> Stream Bool -> Stream Bool
+ Copilot.Arduino: alwaysBeen :: Stream Bool -> Stream Bool
+ Copilot.Arduino: and :: Foldable t => t Bool -> Bool
+ Copilot.Arduino: any :: Foldable t => (a -> Bool) -> t a -> Bool
+ Copilot.Arduino: appendFile :: FilePath -> String -> IO ()
+ Copilot.Arduino: arduino :: Sketch () -> IO ()
+ Copilot.Arduino: arg :: Typed a => Stream a -> Arg
+ Copilot.Arduino: array :: KnownNat n => [t] -> Array n t
+ Copilot.Arduino: arrayelems :: () => Array n a -> [a]
+ Copilot.Arduino: asTypeOf :: () => a -> a -> a
+ Copilot.Arduino: asin :: Floating a => a -> a
+ Copilot.Arduino: asinh :: Floating a => a -> a
+ Copilot.Arduino: atan :: Floating a => a -> a
+ Copilot.Arduino: atan2 :: RealFloat a => a -> a -> a
+ Copilot.Arduino: atanh :: Floating a => a -> a
+ Copilot.Arduino: badUsage :: () => String -> a
+ Copilot.Arduino: blinking :: Stream Bool
+ Copilot.Arduino: break :: () => (a -> Bool) -> [a] -> ([a], [a])
+ Copilot.Arduino: byteSwap16 :: Word16 -> Word16
+ Copilot.Arduino: byteSwap32 :: Word32 -> Word32
+ Copilot.Arduino: byteSwap64 :: Word64 -> Word64
+ Copilot.Arduino: case' :: Typed a => [Stream Bool] -> [Stream a] -> Stream a
+ Copilot.Arduino: cast :: Cast a b => Stream a -> Stream b
+ Copilot.Arduino: ceiling :: (RealFrac a, Integral b) => a -> b
+ Copilot.Arduino: class Functor f => Applicative (f :: Type -> Type)
+ Copilot.Arduino: class Eq a => Bits a
+ Copilot.Arduino: class Bounded a
+ Copilot.Arduino: class Cast a b
+ Copilot.Arduino: class Enum a
+ Copilot.Arduino: class Eq a
+ Copilot.Arduino: class Flatten a b
+ Copilot.Arduino: class Fractional a => Floating a
+ Copilot.Arduino: class Foldable (t :: Type -> Type)
+ Copilot.Arduino: class Num a => Fractional a
+ Copilot.Arduino: class Functor (f :: Type -> Type)
+ Copilot.Arduino: class (Real a, Enum a) => Integral a
+ Copilot.Arduino: class Applicative m => Monad (m :: Type -> Type)
+ Copilot.Arduino: class Semigroup a => Monoid a
+ Copilot.Arduino: class Num a
+ Copilot.Arduino: class Eq a => Ord a
+ Copilot.Arduino: class Read a
+ Copilot.Arduino: class (Num a, Ord a) => Real a
+ Copilot.Arduino: class (RealFrac a, Floating a) => RealFloat a
+ Copilot.Arduino: class (Real a, Fractional a) => RealFrac a
+ Copilot.Arduino: class Semigroup a
+ Copilot.Arduino: class Show a
+ Copilot.Arduino: class Struct a
+ Copilot.Arduino: class (Functor t, Foldable t) => Traversable (t :: Type -> Type)
+ Copilot.Arduino: class (Show a, Typeable a) => Typed a
+ Copilot.Arduino: class UnsafeCast a b
+ Copilot.Arduino: clk :: Integral a => Period a -> Phase a -> Stream Bool
+ Copilot.Arduino: clk1 :: (Integral a, Typed a) => Period a -> Phase a -> Stream Bool
+ Copilot.Arduino: compare :: Ord a => a -> a -> Ordering
+ Copilot.Arduino: complement :: Bits a => a -> a
+ Copilot.Arduino: concat :: Foldable t => t [a] -> [a]
+ Copilot.Arduino: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
+ Copilot.Arduino: constB :: Bool -> Stream Bool
+ Copilot.Arduino: constD :: Double -> Stream Double
+ Copilot.Arduino: constF :: Float -> Stream Float
+ Copilot.Arduino: constI16 :: Int16 -> Stream Int16
+ Copilot.Arduino: constI32 :: Int32 -> Stream Int32
+ Copilot.Arduino: constI64 :: Int64 -> Stream Int64
+ Copilot.Arduino: constI8 :: Int8 -> Stream Int8
+ Copilot.Arduino: constW16 :: Word16 -> Stream Word16
+ Copilot.Arduino: constW32 :: Word32 -> Stream Word32
+ Copilot.Arduino: constW64 :: Word64 -> Stream Word64
+ Copilot.Arduino: constW8 :: Word8 -> Stream Word8
+ Copilot.Arduino: constant :: Typed a => a -> Stream a
+ Copilot.Arduino: copilotMain :: Interpreter -> Printer -> Compiler -> Spec -> IO ()
+ Copilot.Arduino: copilotRegexp :: (Typed t, SymbolParser t, Eq t) => Stream t -> SourceName -> Stream Bool -> Stream Bool
+ Copilot.Arduino: copilotRegexpB :: SourceName -> [(StreamName, Stream Bool)] -> Stream Bool -> Stream Bool
+ Copilot.Arduino: cos :: Floating a => a -> a
+ Copilot.Arduino: cosh :: Floating a => a -> a
+ Copilot.Arduino: csv :: Integer -> Spec -> IO ()
+ Copilot.Arduino: curry :: () => ((a, b) -> c) -> a -> b -> c
+ Copilot.Arduino: cycle :: Typed a => [a] -> Stream a
+ Copilot.Arduino: data Array (n :: Nat) t
+ Copilot.Arduino: data Bool
+ Copilot.Arduino: data Char
+ Copilot.Arduino: data Double
+ Copilot.Arduino: data Either a b
+ Copilot.Arduino: data Field (s :: Symbol) t
+ Copilot.Arduino: data Float
+ Copilot.Arduino: data GPIO
+ Copilot.Arduino: data IO a
+ Copilot.Arduino: data Int
+ Copilot.Arduino: data Int16
+ Copilot.Arduino: data Int32
+ Copilot.Arduino: data Int64
+ Copilot.Arduino: data Int8
+ Copilot.Arduino: data Integer
+ Copilot.Arduino: data Maybe a
+ Copilot.Arduino: data Ordering
+ Copilot.Arduino: data Output t
+ Copilot.Arduino: data SimpleType
+ Copilot.Arduino: data Sketch t
+ Copilot.Arduino: data Type a
+ Copilot.Arduino: data UType
+ Copilot.Arduino: data Value a
+ Copilot.Arduino: data Word
+ Copilot.Arduino: data Word16
+ Copilot.Arduino: data Word32
+ Copilot.Arduino: data Word64
+ Copilot.Arduino: data Word8
+ Copilot.Arduino: decodeFloat :: RealFloat a => a -> (Integer, Int)
+ Copilot.Arduino: defaultMain :: Compiler -> Spec -> IO ()
+ Copilot.Arduino: delay :: Output MicroSeconds
+ Copilot.Arduino: div :: (Typed a, Integral a) => Stream a -> Stream a -> Stream a
+ Copilot.Arduino: divMod :: Integral a => a -> a -> (a, a)
+ Copilot.Arduino: drop :: Typed a => Int -> Stream a -> Stream a
+ Copilot.Arduino: dropWhile :: () => (a -> Bool) -> [a] -> [a]
+ Copilot.Arduino: either :: () => (a -> c) -> (b -> c) -> Either a b -> c
+ Copilot.Arduino: elem :: (Foldable t, Eq a) => a -> t a -> Bool
+ Copilot.Arduino: encodeFloat :: RealFloat a => Integer -> Int -> a
+ Copilot.Arduino: enumFrom :: Enum a => a -> [a]
+ Copilot.Arduino: enumFromThen :: Enum a => a -> a -> [a]
+ Copilot.Arduino: enumFromThenTo :: Enum a => a -> a -> a -> [a]
+ Copilot.Arduino: enumFromTo :: Enum a => a -> a -> [a]
+ Copilot.Arduino: error :: HasCallStack => [Char] -> a
+ Copilot.Arduino: errorWithoutStackTrace :: () => [Char] -> a
+ Copilot.Arduino: even :: Integral a => a -> Bool
+ Copilot.Arduino: eventually :: Integral a => a -> Stream Bool -> Stream Bool
+ Copilot.Arduino: eventuallyPrev :: Stream Bool -> Stream Bool
+ Copilot.Arduino: exists :: Stream Bool -> Prop Existential
+ Copilot.Arduino: exp :: Floating a => a -> a
+ Copilot.Arduino: exponent :: RealFloat a => a -> Int
+ Copilot.Arduino: extern :: Typed a => String -> Maybe [a] -> Stream a
+ Copilot.Arduino: externB :: String -> Maybe [Bool] -> Stream Bool
+ Copilot.Arduino: externD :: String -> Maybe [Double] -> Stream Double
+ Copilot.Arduino: externI16 :: String -> Maybe [Int16] -> Stream Int16
+ Copilot.Arduino: externI32 :: String -> Maybe [Int32] -> Stream Int32
+ Copilot.Arduino: externI64 :: String -> Maybe [Int64] -> Stream Int64
+ Copilot.Arduino: externI8 :: String -> Maybe [Int8] -> Stream Int8
+ Copilot.Arduino: externW16 :: String -> Maybe [Word16] -> Stream Word16
+ Copilot.Arduino: externW32 :: String -> Maybe [Word32] -> Stream Word32
+ Copilot.Arduino: externW64 :: String -> Maybe [Word64] -> Stream Word64
+ Copilot.Arduino: externW8 :: String -> Maybe [Word8] -> Stream Word8
+ Copilot.Arduino: fail :: Monad m => String -> m a
+ Copilot.Arduino: false :: Stream Bool
+ Copilot.Arduino: fieldname :: KnownSymbol s => Field s t -> String
+ Copilot.Arduino: filter :: () => (a -> Bool) -> [a] -> [a]
+ Copilot.Arduino: firstIteration :: Stream Bool
+ Copilot.Arduino: flatten :: Flatten a b => Array n a -> [b]
+ Copilot.Arduino: flip :: () => (a -> b -> c) -> b -> a -> c
+ Copilot.Arduino: floatDigits :: RealFloat a => a -> Int
+ Copilot.Arduino: floatRadix :: RealFloat a => a -> Integer
+ Copilot.Arduino: floatRange :: RealFloat a => a -> (Int, Int)
+ Copilot.Arduino: floor :: (RealFrac a, Integral b) => a -> b
+ Copilot.Arduino: fmap :: Functor f => (a -> b) -> f a -> f b
+ Copilot.Arduino: foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
+ Copilot.Arduino: foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
+ Copilot.Arduino: foldl1 :: Foldable t => (a -> a -> a) -> t a -> a
+ Copilot.Arduino: foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
+ Copilot.Arduino: foldr1 :: Foldable t => (a -> a -> a) -> t a -> a
+ Copilot.Arduino: forall :: Stream Bool -> Prop Universal
+ Copilot.Arduino: fromEnum :: Enum a => a -> Int
+ Copilot.Arduino: fromInteger :: Num a => Integer -> a
+ Copilot.Arduino: fromIntegral :: (Integral a, Num b) => a -> b
+ Copilot.Arduino: fromRational :: Fractional a => Rational -> a
+ Copilot.Arduino: fst :: () => (a, b) -> a
+ Copilot.Arduino: funArg :: Typed a => Stream a -> Arg
+ Copilot.Arduino: gcd :: Integral a => a -> a -> a
+ Copilot.Arduino: getChar :: IO Char
+ Copilot.Arduino: getContents :: IO String
+ Copilot.Arduino: getLine :: IO String
+ Copilot.Arduino: head :: () => [a] -> a
+ Copilot.Arduino: id :: () => a -> a
+ Copilot.Arduino: ifThenElse :: Typed a => Stream Bool -> Stream a -> Stream a -> Stream a
+ Copilot.Arduino: impossible :: () => String -> String -> a
+ Copilot.Arduino: infix 4 `notElem`
+ Copilot.Arduino: infixl 1 >>
+ Copilot.Arduino: infixl 4 <$>
+ Copilot.Arduino: infixl 5 .|.
+ Copilot.Arduino: infixl 6 -
+ Copilot.Arduino: infixl 7 .&.
+ Copilot.Arduino: infixr 0 $!
+ Copilot.Arduino: infixr 1 ++
+ Copilot.Arduino: infixr 4 ||
+ Copilot.Arduino: infixr 6 <>
+ Copilot.Arduino: infixr 8 ^^
+ Copilot.Arduino: infixr 9 .
+ Copilot.Arduino: init :: () => [a] -> [a]
+ Copilot.Arduino: interact :: (String -> String) -> IO ()
+ Copilot.Arduino: interpret :: Integer -> Spec -> IO ()
+ Copilot.Arduino: ioError :: () => IOError -> IO a
+ Copilot.Arduino: isDenormalized :: RealFloat a => a -> Bool
+ Copilot.Arduino: isIEEE :: RealFloat a => a -> Bool
+ Copilot.Arduino: isInfinite :: RealFloat a => a -> Bool
+ Copilot.Arduino: isNaN :: RealFloat a => a -> Bool
+ Copilot.Arduino: isNegativeZero :: RealFloat a => a -> Bool
+ Copilot.Arduino: iterate :: () => (a -> a) -> a -> [a]
+ Copilot.Arduino: label :: Typed a => String -> Stream a -> Stream a
+ Copilot.Arduino: last :: () => [a] -> a
+ Copilot.Arduino: lcm :: Integral a => a -> a -> a
+ Copilot.Arduino: led :: Output Bool
+ Copilot.Arduino: length :: Foldable t => t a -> Int
+ Copilot.Arduino: lex :: ReadS String
+ Copilot.Arduino: lines :: String -> [String]
+ Copilot.Arduino: local :: (Typed a, Typed b) => Stream a -> (Stream a -> Stream b) -> Stream b
+ Copilot.Arduino: log :: Floating a => a -> a
+ Copilot.Arduino: logBase :: Floating a => a -> a -> a
+ Copilot.Arduino: lookup :: Eq a => a -> [(a, b)] -> Maybe b
+ Copilot.Arduino: majority :: (Eq a, Typed a) => [Stream a] -> Stream a
+ Copilot.Arduino: map :: () => (a -> b) -> [a] -> [b]
+ Copilot.Arduino: mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
+ Copilot.Arduino: mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
+ Copilot.Arduino: mappend :: Monoid a => a -> a -> a
+ Copilot.Arduino: max :: (Typed a, Ord a) => Int -> Stream a -> Stream a
+ Copilot.Arduino: maxBound :: Bounded a => a
+ Copilot.Arduino: maximum :: (Foldable t, Ord a) => t a -> a
+ Copilot.Arduino: maybe :: () => b -> (a -> b) -> Maybe a -> b
+ Copilot.Arduino: mconcat :: Monoid a => [a] -> a
+ Copilot.Arduino: mean :: (Typed a, Eq a, Fractional a) => Int -> Stream a -> Stream a
+ Copilot.Arduino: meanNow :: (Typed a, Integral a) => [Stream a] -> Stream a
+ Copilot.Arduino: mempty :: Monoid a => a
+ Copilot.Arduino: min :: (Typed a, Ord a) => Int -> Stream a -> Stream a
+ Copilot.Arduino: minBound :: Bounded a => a
+ Copilot.Arduino: minimum :: (Foldable t, Ord a) => t a -> a
+ Copilot.Arduino: mod :: (Typed a, Integral a) => Stream a -> Stream a -> Stream a
+ Copilot.Arduino: mux :: Typed a => Stream Bool -> Stream a -> Stream a -> Stream a
+ Copilot.Arduino: negate :: Num a => a -> a
+ Copilot.Arduino: next :: Stream Bool -> Stream Bool
+ Copilot.Arduino: nfoldl :: (Typed a, Typed b) => Int -> (Stream a -> Stream b -> Stream a) -> Stream a -> Stream b -> Stream a
+ Copilot.Arduino: nfoldl1 :: Typed a => Int -> (Stream a -> Stream a -> Stream a) -> Stream a -> Stream a
+ Copilot.Arduino: nfoldr :: (Typed a, Typed b) => Int -> (Stream a -> Stream b -> Stream b) -> Stream b -> Stream a -> Stream b
+ Copilot.Arduino: nfoldr1 :: Typed a => Int -> (Stream a -> Stream a -> Stream a) -> Stream a -> Stream a
+ Copilot.Arduino: not :: Stream Bool -> Stream Bool
+ Copilot.Arduino: notElem :: (Foldable t, Eq a) => a -> t a -> Bool
+ Copilot.Arduino: nscanl :: (Typed a, Typed b) => Int -> (Stream a -> Stream b -> Stream a) -> Stream a -> Stream b -> [Stream a]
+ Copilot.Arduino: nscanl1 :: Typed a => Int -> (Stream a -> Stream a -> Stream a) -> Stream a -> [Stream a]
+ Copilot.Arduino: nscanr :: Typed a => Int -> (Stream a -> Stream b -> Stream b) -> Stream b -> Stream a -> [Stream b]
+ Copilot.Arduino: nscanr1 :: Typed a => Int -> (Stream a -> Stream a -> Stream a) -> Stream a -> [Stream a]
+ Copilot.Arduino: null :: Foldable t => t a -> Bool
+ Copilot.Arduino: observer :: Typed a => String -> Stream a -> Spec
+ Copilot.Arduino: odd :: Integral a => a -> Bool
+ Copilot.Arduino: or :: Foldable t => t Bool -> Bool
+ Copilot.Arduino: otherwise :: Bool
+ Copilot.Arduino: period :: Integral a => a -> Period a
+ Copilot.Arduino: phase :: Integral a => a -> Phase a
+ Copilot.Arduino: pi :: Floating a => a
+ Copilot.Arduino: pred :: Enum a => a -> a
+ Copilot.Arduino: prettyPrint :: Spec -> IO ()
+ Copilot.Arduino: previous :: Stream Bool -> Stream Bool
+ Copilot.Arduino: print :: Show a => a -> IO ()
+ Copilot.Arduino: product :: (Foldable t, Num a) => t a -> a
+ Copilot.Arduino: prop :: () => String -> Prop a -> Writer [SpecItem] (PropRef a)
+ Copilot.Arduino: properFraction :: (RealFrac a, Integral b) => a -> (b, a)
+ Copilot.Arduino: pure :: Applicative f => a -> f a
+ Copilot.Arduino: putChar :: Char -> IO ()
+ Copilot.Arduino: putStr :: String -> IO ()
+ Copilot.Arduino: putStrLn :: String -> IO ()
+ Copilot.Arduino: quot :: Integral a => a -> a -> a
+ Copilot.Arduino: quotRem :: Integral a => a -> a -> (a, a)
+ Copilot.Arduino: read :: Read a => String -> a
+ Copilot.Arduino: readFile :: FilePath -> IO String
+ Copilot.Arduino: readIO :: Read a => String -> IO a
+ Copilot.Arduino: readList :: Read a => ReadS [a]
+ Copilot.Arduino: readLn :: Read a => IO a
+ Copilot.Arduino: readParen :: () => Bool -> ReadS a -> ReadS a
+ Copilot.Arduino: readfrom :: GPIO -> Input Bool
+ Copilot.Arduino: readfrom' :: GPIO -> [Bool] -> Input Bool
+ Copilot.Arduino: reads :: Read a => ReadS a
+ Copilot.Arduino: readsPrec :: Read a => Int -> ReadS a
+ Copilot.Arduino: realToFrac :: (Real a, Fractional b) => a -> b
+ Copilot.Arduino: recip :: Fractional a => a -> a
+ Copilot.Arduino: reify :: () => Spec' a -> IO Spec
+ Copilot.Arduino: release :: Integral a => a -> Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: rem :: Integral a => a -> a -> a
+ Copilot.Arduino: repeat :: () => a -> [a]
+ Copilot.Arduino: replicate :: () => Int -> a -> [a]
+ Copilot.Arduino: return :: Monad m => a -> m a
+ Copilot.Arduino: reverse :: () => [a] -> [a]
+ Copilot.Arduino: round :: (RealFrac a, Integral b) => a -> b
+ Copilot.Arduino: scaleFloat :: RealFloat a => Int -> a -> a
+ Copilot.Arduino: scanl :: () => (b -> a -> b) -> b -> [a] -> [b]
+ Copilot.Arduino: scanl1 :: () => (a -> a -> a) -> [a] -> [a]
+ Copilot.Arduino: scanr :: () => (a -> b -> b) -> b -> [a] -> [b]
+ Copilot.Arduino: scanr1 :: () => (a -> a -> a) -> [a] -> [a]
+ Copilot.Arduino: seq :: () => a -> b -> b
+ Copilot.Arduino: sequence :: (Traversable t, Monad m) => t (m a) -> m (t a)
+ Copilot.Arduino: sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
+ Copilot.Arduino: sequence_ :: (Foldable t, Monad m) => t (m a) -> m ()
+ Copilot.Arduino: show :: Show a => a -> String
+ Copilot.Arduino: showChar :: Char -> ShowS
+ Copilot.Arduino: showList :: Show a => [a] -> ShowS
+ Copilot.Arduino: showParen :: Bool -> ShowS -> ShowS
+ Copilot.Arduino: showString :: String -> ShowS
+ Copilot.Arduino: shows :: Show a => a -> ShowS
+ Copilot.Arduino: showsPrec :: Show a => Int -> a -> ShowS
+ Copilot.Arduino: significand :: RealFloat a => a -> a
+ Copilot.Arduino: signum :: Num a => a -> a
+ Copilot.Arduino: simpleType :: Typed a => Type a -> SimpleType
+ Copilot.Arduino: sin :: Floating a => a -> a
+ Copilot.Arduino: since :: Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: sinh :: Floating a => a -> a
+ Copilot.Arduino: size :: (Flatten a b, b ~ InnerType a) => Array n a -> Int
+ Copilot.Arduino: sketchSpec :: Sketch a -> Spec
+ Copilot.Arduino: snd :: () => (a, b) -> b
+ Copilot.Arduino: span :: () => (a -> Bool) -> [a] -> ([a], [a])
+ Copilot.Arduino: splitAt :: () => Int -> [a] -> ([a], [a])
+ Copilot.Arduino: sqrt :: Floating a => a -> a
+ Copilot.Arduino: stack :: (Integral a, Typed b) => a -> b -> Stream Bool -> Stream Bool -> Stream b -> Stream b
+ Copilot.Arduino: stack' :: (Integral a, Typed b) => a -> b -> Stream Bool -> Stream Bool -> Stream b -> Stream b
+ Copilot.Arduino: subtract :: Num a => a -> a -> a
+ Copilot.Arduino: succ :: Enum a => a -> a
+ Copilot.Arduino: sum :: (Typed a, Num a, Eq a) => Int -> Stream a -> Stream a
+ Copilot.Arduino: tail :: () => [a] -> [a]
+ Copilot.Arduino: tails :: Typed a => Stream a -> [Stream a]
+ Copilot.Arduino: take :: (Integral a, Typed b) => a -> Stream b -> [Stream b]
+ Copilot.Arduino: takeWhile :: () => (a -> Bool) -> [a] -> [a]
+ Copilot.Arduino: tan :: Floating a => a -> a
+ Copilot.Arduino: tanh :: Floating a => a -> a
+ Copilot.Arduino: theorem :: () => String -> Prop a -> Proof a -> Writer [SpecItem] (PropRef a)
+ Copilot.Arduino: toEnum :: Enum a => Int -> a
+ Copilot.Arduino: toInteger :: Integral a => a -> Integer
+ Copilot.Arduino: toRational :: Real a => a -> Rational
+ Copilot.Arduino: toValues :: Struct a => a -> [Value a]
+ Copilot.Arduino: traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)
+ Copilot.Arduino: trigger :: String -> Stream Bool -> [Arg] -> Spec
+ Copilot.Arduino: true :: Stream Bool
+ Copilot.Arduino: truncate :: (RealFrac a, Integral b) => a -> b
+ Copilot.Arduino: tylength :: KnownNat n => Type (Array n t) -> Int
+ Copilot.Arduino: type FilePath = String
+ Copilot.Arduino: type IOError = IOException
+ Copilot.Arduino: type Input t = Sketch (Stream t)
+ Copilot.Arduino: type MicroSeconds = Int16
+ Copilot.Arduino: type Name = String
+ Copilot.Arduino: type Rational = Ratio Integer
+ Copilot.Arduino: type ReadS a = String -> [(a, String)]
+ Copilot.Arduino: type ShowS = String -> String
+ Copilot.Arduino: type Spec = Writer [SpecItem] ()
+ Copilot.Arduino: type Stream t = Stream t
+ Copilot.Arduino: type String = [Char]
+ Copilot.Arduino: type family InnerType x :: Type
+ Copilot.Arduino: typeOf :: Typed a => Type a
+ Copilot.Arduino: typename :: Struct a => a -> String
+ Copilot.Arduino: tysize :: KnownNat n => Type (Array n t) -> Int
+ Copilot.Arduino: uncurry :: () => (a -> b -> c) -> (a, b) -> c
+ Copilot.Arduino: undefined :: HasCallStack => a
+ Copilot.Arduino: unlines :: [String] -> String
+ Copilot.Arduino: unsafeCast :: UnsafeCast a b => Stream a -> Stream b
+ Copilot.Arduino: until :: Integral a => a -> Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: unwords :: [String] -> String
+ Copilot.Arduino: unzip :: () => [(a, b)] -> ([a], [b])
+ Copilot.Arduino: unzip3 :: () => [(a, b, c)] -> ([a], [b], [c])
+ Copilot.Arduino: userError :: String -> IOError
+ Copilot.Arduino: words :: String -> [String]
+ Copilot.Arduino: writeFile :: FilePath -> String -> IO ()
+ Copilot.Arduino: writeto :: GPIO -> Output Bool
+ Copilot.Arduino: xor :: Stream Bool -> Stream Bool -> Stream Bool
+ Copilot.Arduino: zip :: () => [a] -> [b] -> [(a, b)]
+ Copilot.Arduino: zip3 :: () => [a] -> [b] -> [c] -> [(a, b, c)]
+ Copilot.Arduino: zipWith :: () => (a -> b -> c) -> [a] -> [b] -> [c]
+ Copilot.Arduino: zipWith3 :: () => (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
+ Copilot.Arduino.Internals: Framework :: [CFragment] -> [CFragment] -> [CFragment] -> Framework
+ Copilot.Arduino.Internals: GPIO :: Int16 -> GPIO
+ Copilot.Arduino.Internals: InputSource :: [CFragment] -> [CFragment] -> [CFragment] -> Stream t -> InputSource t
+ Copilot.Arduino.Internals: Output :: [CFragment] -> Stream Bool -> (Stream Bool -> Behavior t) -> Output t
+ Copilot.Arduino.Internals: Sketch :: Writer [(Spec, Framework)] t -> Sketch t
+ Copilot.Arduino.Internals: [defineVar] :: InputSource t -> [CFragment]
+ Copilot.Arduino.Internals: [defines] :: Framework -> [CFragment]
+ Copilot.Arduino.Internals: [inputStream] :: InputSource t -> Stream t
+ Copilot.Arduino.Internals: [loops] :: Framework -> [CFragment]
+ Copilot.Arduino.Internals: [outputBehavior] :: Output t -> Stream Bool -> Behavior t
+ Copilot.Arduino.Internals: [outputCond] :: Output t -> Stream Bool
+ Copilot.Arduino.Internals: [readInput] :: InputSource t -> [CFragment]
+ Copilot.Arduino.Internals: [setupInput] :: InputSource t -> [CFragment]
+ Copilot.Arduino.Internals: [setupOutput] :: Output t -> [CFragment]
+ Copilot.Arduino.Internals: [setups] :: Framework -> [CFragment]
+ Copilot.Arduino.Internals: class ToFramework t
+ Copilot.Arduino.Internals: data Framework
+ Copilot.Arduino.Internals: data InputSource t
+ Copilot.Arduino.Internals: data Output t
+ Copilot.Arduino.Internals: instance Control.Monad.Writer.Class.MonadWriter [(Copilot.Language.Spec.Spec, Copilot.Arduino.Internals.Framework)] Copilot.Arduino.Internals.Sketch
+ Copilot.Arduino.Internals: instance Copilot.Arduino.Internals.ToFramework (Copilot.Arduino.Internals.InputSource t)
+ Copilot.Arduino.Internals: instance Copilot.Arduino.Internals.ToFramework (Copilot.Arduino.Internals.Output t)
+ Copilot.Arduino.Internals: instance GHC.Base.Applicative Copilot.Arduino.Internals.Sketch
+ Copilot.Arduino.Internals: instance GHC.Base.Functor Copilot.Arduino.Internals.Sketch
+ Copilot.Arduino.Internals: instance GHC.Base.Monad Copilot.Arduino.Internals.Sketch
+ Copilot.Arduino.Internals: instance GHC.Base.Monoid (Copilot.Arduino.Internals.Sketch ())
+ Copilot.Arduino.Internals: instance GHC.Base.Monoid Copilot.Arduino.Internals.Framework
+ Copilot.Arduino.Internals: instance GHC.Base.Semigroup (Copilot.Arduino.Internals.Sketch t)
+ Copilot.Arduino.Internals: instance GHC.Base.Semigroup Copilot.Arduino.Internals.Framework
+ Copilot.Arduino.Internals: mkInput :: InputSource t -> Input t
+ Copilot.Arduino.Internals: newtype GPIO
+ Copilot.Arduino.Internals: newtype Sketch t
+ Copilot.Arduino.Internals: sketchFramework :: Framework -> [String] -> [CFragment]
+ Copilot.Arduino.Internals: toFramework :: ToFramework t => t -> Framework
+ Copilot.Arduino.Internals: type Behavior t = Stream t -> Spec
+ Copilot.Arduino.Internals: type CFragment = String
+ Copilot.Arduino.Internals: type Input t = Sketch (Stream t)
+ Copilot.Arduino.Internals: type MicroSeconds = Int16
+ Copilot.Arduino.Nano: pin10 :: GPIO
+ Copilot.Arduino.Nano: pin11 :: GPIO
+ Copilot.Arduino.Nano: pin12 :: GPIO
+ Copilot.Arduino.Nano: pin13 :: GPIO
+ Copilot.Arduino.Nano: pin2 :: GPIO
+ Copilot.Arduino.Nano: pin3 :: GPIO
+ Copilot.Arduino.Nano: pin4 :: GPIO
+ Copilot.Arduino.Nano: pin5 :: GPIO
+ Copilot.Arduino.Nano: pin6 :: GPIO
+ Copilot.Arduino.Nano: pin7 :: GPIO
+ Copilot.Arduino.Nano: pin8 :: GPIO
+ Copilot.Arduino.Nano: pin9 :: GPIO
+ Copilot.Arduino.Uno: pin10 :: GPIO
+ Copilot.Arduino.Uno: pin11 :: GPIO
+ Copilot.Arduino.Uno: pin12 :: GPIO
+ Copilot.Arduino.Uno: pin13 :: GPIO
+ Copilot.Arduino.Uno: pin2 :: GPIO
+ Copilot.Arduino.Uno: pin3 :: GPIO
+ Copilot.Arduino.Uno: pin4 :: GPIO
+ Copilot.Arduino.Uno: pin5 :: GPIO
+ Copilot.Arduino.Uno: pin6 :: GPIO
+ Copilot.Arduino.Uno: pin7 :: GPIO
+ Copilot.Arduino.Uno: pin8 :: GPIO
+ Copilot.Arduino.Uno: pin9 :: GPIO
Files
- CHANGELOG +1/−1
- README +7/−0
- TODO +2/−0
- arduino-copilot.cabal +25/−15
- demo/Makefile +0/−127
- demo/README +0/−28
- demo/demo.hs +0/−25
- demo/pre-build-hook.sh +0/−2
- examples/blink/Makefile +127/−0
- examples/blink/README +28/−0
- examples/blink/demo.hs +8/−0
- examples/blink/pre-build-hook.sh +2/−0
- examples/button/Makefile +127/−0
- examples/button/README +24/−0
- examples/button/demo.hs +22/−0
- examples/button/pre-build-hook.sh +2/−0
- src/Arduino.hs +0/−262
- src/Copilot/Arduino.hs +163/−0
- src/Copilot/Arduino/Internals.hs +145/−0
- src/Copilot/Arduino/Main.hs +84/−0
- src/Copilot/Arduino/Nano.hs +51/−0
- src/Copilot/Arduino/Uno.hs +49/−0
CHANGELOG view
@@ -1,4 +1,4 @@-arduino-copilot (0.0.1) unstable; urgency=medium+arduino-copilot (1.0.0) unstable; urgency=medium * First release.
+ README view
@@ -0,0 +1,7 @@+Arduino programming in haskell using the Copilot stream DSL++See Copilot.Arduino for details on how to use write a program using this+library.++Several examples are included in the examples/ directory, and each have+their own README explaining how to use them.
TODO view
@@ -0,0 +1,2 @@+* analog pins+* serial console support (involves arrays of bytes)
arduino-copilot.cabal view
@@ -1,5 +1,5 @@ Name: arduino-copilot-Version: 0.0.1+Version: 1.0.0 Cabal-Version: >= 1.8 License: BSD3 Maintainer: Joey Hess <id@joeyh.name>@@ -9,13 +9,13 @@ License-File: LICENSE Build-Type: Simple Category: Embedded, Language-Synopsis: Arduino programming in haskell using the stream DSL+Synopsis: Arduino programming in haskell using the Copilot stream DSL Description: arduino-copilot contains the basic building blocks to program your Arduino Nano, Arduino Uno or compatible hardware using Haskell and Functional Reactive Programming (FRP). .- arduino-copilot uses the Copilot stream domain-specific language (DSL)+ arduino-copilot uses the Copilot stream DSL (domain-specific language) to generate an Arduino sketch, which can be loaded in the Arduino IDE and uploaded to the board. Other methods of deploying sketches to the Arduino, such as the Arduino-Makefile, can also be used with a sketch@@ -25,30 +25,39 @@ desired behavior of the Arduino. This is all the code needed to make it blink its LED: .- -- > import Arduino+ -- > import Copilot.Arduino -- > main = arduino $ do- -- > led =: clk (period 2) (phase 1)- -- > delay =: const16 100+ -- > led =: blinking+ -- > delay =: constant 100 . Copilot is a stream (i.e., infinite lists) domain-specific language- (DSL) in Haskell that compiles into embedded C. Copilot contains an+ (DSL) in Haskell that compiles into embedded C. Copilot contains an interpreter, multiple back-end compilers, and other verification tools.- A tutorial, bug reports, and todos are available at- <https://github.com/Copilot-Language/copilot-discussion>.+ <https://copilot-language.github.io/> Extra-Source-Files:+ README CHANGELOG TODO stack.yaml- demo/Makefile- demo/README- demo/demo.hs- demo/pre-build-hook.sh+ examples/blink/Makefile+ examples/blink/README+ examples/blink/demo.hs+ examples/blink/pre-build-hook.sh+ examples/button/Makefile+ examples/button/README+ examples/button/demo.hs+ examples/button/pre-build-hook.sh Library GHC-Options: -Wall -fno-warn-tabs Hs-Source-Dirs: src Exposed-Modules:- Arduino+ Copilot.Arduino+ Copilot.Arduino.Nano+ Copilot.Arduino.Uno+ Copilot.Arduino.Internals+ Other-Modules:+ Copilot.Arduino.Main Build-Depends: base (>= 4.5 && < 5), copilot (== 3.1.*),@@ -56,7 +65,8 @@ filepath, directory, mtl,- unix+ unix,+ optparse-applicative (>= 0.14.1) source-repository head type: git
− demo/Makefile
@@ -1,127 +0,0 @@-# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile-BOARD_TAG = uno-include /usr/share/arduino/Arduino.mk--# --- leonardo (or pro micro w/leo bootloader)-#BOARD_TAG = leonardo-#MONITOR_PORT = /dev/ttyACM0-#include /usr/share/arduino/Arduino.mk--# --- mega2560 ide 1.0-#BOARD_TAG = mega2560-#ARDUINO_PORT = /dev/ttyACM0-#include /usr/share/arduino/Arduino.mk--# --- mega2560 ide 1.6-#BOARD_TAG = mega-#BOARD_SUB = atmega2560-#MONITOR_PORT = /dev/ttyACM0-#ARDUINO_DIR = /where/you/installed/arduino-1.6.5-#include /usr/share/arduino/Arduino.mk--# --- nano ide 1.0-#BOARD_TAG = nano328-#MONITOR_PORT = /dev/ttyUSB0-#include /usr/share/arduino/Arduino.mk--# --- nano ide 1.6-#BOARD_TAG = nano-#BOARD_SUB = atmega328-#ARDUINO_DIR = /where/you/installed/arduino-1.6.5-#include /usr/share/arduino/Arduino.mk--# --- pro mini-#BOARD_TAG = pro5v328-#MONITOR_PORT = /dev/ttyUSB0-#include /usr/share/arduino/Arduino.mk--# --- sparkfun pro micro-#BOARD_TAG = promicro16-#ALTERNATE_CORE = promicro-#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt-#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders-#BOOTLOADER_PATH = caterina-#BOOTLOADER_FILE = Caterina-promicro16.hex-#ISP_PROG = usbasp-#AVRDUDE_OPTS = -v-#include /usr/share/arduino/Arduino.mk--# --- chipkit-#BOARD_TAG = mega_pic32-#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test-#include /usr/share/arduino/chipKIT.mk--# --- pinoccio-#BOARD_TAG = pinoccio256-#ALTERNATE_CORE = pinoccio-#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders-#BOOTLOADER_PATH = STK500RFR2/release_0.51-#BOOTLOADER_FILE = boot_pinoccio.hex-#CFLAGS_STD = -std=gnu99-#CXXFLAGS_STD = -std=gnu++11-#include /usr/share/arduino/Arduino.mk--# --- fio-#BOARD_TAG = fio-#include /usr/share/arduino/Arduino.mk--# --- atmega-ng ide 1.6-#BOARD_TAG = atmegang-#BOARD_SUB = atmega168-#MONITOR_PORT = /dev/ttyACM0-#ARDUINO_DIR = /where/you/installed/arduino-1.6.5-#include /usr/share/arduino/Arduino.mk--# --- arduino-tiny ide 1.0-#ISP_PROG = usbasp-#BOARD_TAG = attiny85at8-#ALTERNATE_CORE = tiny-#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny-#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny-#AVRDUDE_OPTS = -v-#include /usr/share/arduino/Arduino.mk--# --- arduino-tiny ide 1.6-#ISP_PROG = usbasp-#BOARD_TAG = attiny85at8-#ALTERNATE_CORE = tiny-#ARDUINO_DIR = /where/you/installed/arduino-1.6.5-#include /usr/share/arduino/Arduino.mk--# --- damellis attiny ide 1.0-#ISP_PROG = usbasp-#BOARD_TAG = attiny85-#ALTERNATE_CORE = attiny-master-#AVRDUDE_OPTS = -v-#include /usr/share/arduino/Arduino.mk--# --- damellis attiny ide 1.6-#ISP_PROG = usbasp-#BOARD_TAG = attiny-#BOARD_SUB = attiny85-#ALTERNATE_CORE = attiny-#F_CPU = 16000000L-#ARDUINO_DIR = /where/you/installed/arduino-1.6.5-#include /usr/share/arduino/Arduino.mk--# --- teensy3-#BOARD_TAG = teensy31-#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6-#include /usr/share/arduino/Teensy.mk--# --- mighty 1284p-#BOARD_TAG = mighty_opt-#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt-#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders-#BOOTLOADER_PATH = optiboot-#BOOTLOADER_FILE = optiboot_atmega1284p.hex-#ISP_PROG = usbasp-#AVRDUDE_OPTS = -v-#include /usr/share/arduino/Arduino.mk--# --- atmega328p on breadboard-#BOARD_TAG = atmega328bb-#ISP_PROG = usbasp-#AVRDUDE_OPTS = -v-#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt-#include /usr/share/arduino/Arduino.mk
− demo/README
@@ -1,28 +0,0 @@-This is a demo program using arduino-copilot. --To build the C code:-- stack run demo--The resulting `.ino` sketch can be loaded into the Arduino IDE and flashed-to an Arduino board using the IDE.--It simply flashes the Arduino's on board LED, so should work on most or all-Arduino boards.--## Arduino-Makefile integration--The `Makefile` and `pre-build-hook.sh` show how to integrate arduino-copilot-with <https://github.com/sudar/Arduino-Makefile>. This automates generating-the C code, compiling that, and flashing it onto an Arduino Uno board,-with a single command-- make flash--Note that you will need to manually build the C code once, as shown above-, since the Arduino-Makefile expects to find a `.ino` file.--The path in the `Makefile` to `Arduino.mk` may need to be adjusted (the-default is the location where on a Debian system, `apt-get install-arduino-mk` will install it). You may also adjust the `Makefile` to target-a different board than the Arduino Uno.
− demo/demo.hs
@@ -1,25 +0,0 @@-{-# LANGUAGE RebindableSyntax #-}--import Arduino--flashing :: Stream Bool-flashing = clk (period (2 :: Int16)) (phase 1)--longer_and_longer :: Stream Int16-longer_and_longer = counter true $ counter true false `mod` 64 == 0--counter :: Stream Bool -> Stream Bool -> Stream Int16-counter inc reset = cnt- where- cnt = if reset- then 0- else if inc- then z + 1- else z- z = [0] ++ cnt--main :: IO ()-main = arduino $ do- buttonpressed <- boolInput (Pin 14)- led =: buttonpressed || flashing- delay =: longer_and_longer
− demo/pre-build-hook.sh
@@ -1,2 +0,0 @@-#!/bin/sh-exec stack run demo -Wall -fno-warn-tabs
+ examples/blink/Makefile view
@@ -0,0 +1,127 @@+# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile+BOARD_TAG = uno+include /usr/share/arduino/Arduino.mk++# --- leonardo (or pro micro w/leo bootloader)+#BOARD_TAG = leonardo+#MONITOR_PORT = /dev/ttyACM0+#include /usr/share/arduino/Arduino.mk++# --- mega2560 ide 1.0+#BOARD_TAG = mega2560+#ARDUINO_PORT = /dev/ttyACM0+#include /usr/share/arduino/Arduino.mk++# --- mega2560 ide 1.6+#BOARD_TAG = mega+#BOARD_SUB = atmega2560+#MONITOR_PORT = /dev/ttyACM0+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- nano ide 1.0+#BOARD_TAG = nano328+#MONITOR_PORT = /dev/ttyUSB0+#include /usr/share/arduino/Arduino.mk++# --- nano ide 1.6+#BOARD_TAG = nano+#BOARD_SUB = atmega328+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- pro mini+#BOARD_TAG = pro5v328+#MONITOR_PORT = /dev/ttyUSB0+#include /usr/share/arduino/Arduino.mk++# --- sparkfun pro micro+#BOARD_TAG = promicro16+#ALTERNATE_CORE = promicro+#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders+#BOOTLOADER_PATH = caterina+#BOOTLOADER_FILE = Caterina-promicro16.hex+#ISP_PROG = usbasp+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- chipkit+#BOARD_TAG = mega_pic32+#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test+#include /usr/share/arduino/chipKIT.mk++# --- pinoccio+#BOARD_TAG = pinoccio256+#ALTERNATE_CORE = pinoccio+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders+#BOOTLOADER_PATH = STK500RFR2/release_0.51+#BOOTLOADER_FILE = boot_pinoccio.hex+#CFLAGS_STD = -std=gnu99+#CXXFLAGS_STD = -std=gnu++11+#include /usr/share/arduino/Arduino.mk++# --- fio+#BOARD_TAG = fio+#include /usr/share/arduino/Arduino.mk++# --- atmega-ng ide 1.6+#BOARD_TAG = atmegang+#BOARD_SUB = atmega168+#MONITOR_PORT = /dev/ttyACM0+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- arduino-tiny ide 1.0+#ISP_PROG = usbasp+#BOARD_TAG = attiny85at8+#ALTERNATE_CORE = tiny+#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny+#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- arduino-tiny ide 1.6+#ISP_PROG = usbasp+#BOARD_TAG = attiny85at8+#ALTERNATE_CORE = tiny+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- damellis attiny ide 1.0+#ISP_PROG = usbasp+#BOARD_TAG = attiny85+#ALTERNATE_CORE = attiny-master+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- damellis attiny ide 1.6+#ISP_PROG = usbasp+#BOARD_TAG = attiny+#BOARD_SUB = attiny85+#ALTERNATE_CORE = attiny+#F_CPU = 16000000L+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- teensy3+#BOARD_TAG = teensy31+#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6+#include /usr/share/arduino/Teensy.mk++# --- mighty 1284p+#BOARD_TAG = mighty_opt+#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders+#BOOTLOADER_PATH = optiboot+#BOOTLOADER_FILE = optiboot_atmega1284p.hex+#ISP_PROG = usbasp+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- atmega328p on breadboard+#BOARD_TAG = atmega328bb+#ISP_PROG = usbasp+#AVRDUDE_OPTS = -v+#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt+#include /usr/share/arduino/Arduino.mk
+ examples/blink/README view
@@ -0,0 +1,28 @@+This is a demo program using arduino-copilot. ++To build the C code:++ runghc demo.hs++The resulting `.ino` sketch can be loaded into the Arduino IDE and flashed+to an Arduino board using the IDE.++It simply flashes the Arduino's on board LED, so should work on most or all+Arduino boards.++## Arduino-Makefile integration++The `Makefile` and `pre-build-hook.sh` show how to integrate arduino-copilot+with <https://github.com/sudar/Arduino-Makefile>. This automates generating+the C code, compiling that, and flashing it onto an Arduino Uno board,+with a single command++ make upload++Note that you will need to manually build the C code once, as shown above+, since the Arduino-Makefile expects to find a `.ino` file.++The path in the `Makefile` to `Arduino.mk` may need to be adjusted (the+default is the location where on a Debian system, `apt-get install+arduino-mk` will install it). You may also adjust the `Makefile` to target+a different board than the Arduino Uno.
+ examples/blink/demo.hs view
@@ -0,0 +1,8 @@+{-# LANGUAGE RebindableSyntax #-}++import Copilot.Arduino++main :: IO ()+main = arduino $ do+ led =: blinking+ delay =: constant 100
+ examples/blink/pre-build-hook.sh view
@@ -0,0 +1,2 @@+#!/bin/sh+exec runghc demo.hs
+ examples/button/Makefile view
@@ -0,0 +1,127 @@+# Arduino Make file. Refer to https://github.com/sudar/Arduino-Makefile+BOARD_TAG = uno+include /usr/share/arduino/Arduino.mk++# --- leonardo (or pro micro w/leo bootloader)+#BOARD_TAG = leonardo+#MONITOR_PORT = /dev/ttyACM0+#include /usr/share/arduino/Arduino.mk++# --- mega2560 ide 1.0+#BOARD_TAG = mega2560+#ARDUINO_PORT = /dev/ttyACM0+#include /usr/share/arduino/Arduino.mk++# --- mega2560 ide 1.6+#BOARD_TAG = mega+#BOARD_SUB = atmega2560+#MONITOR_PORT = /dev/ttyACM0+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- nano ide 1.0+#BOARD_TAG = nano328+#MONITOR_PORT = /dev/ttyUSB0+#include /usr/share/arduino/Arduino.mk++# --- nano ide 1.6+#BOARD_TAG = nano+#BOARD_SUB = atmega328+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- pro mini+#BOARD_TAG = pro5v328+#MONITOR_PORT = /dev/ttyUSB0+#include /usr/share/arduino/Arduino.mk++# --- sparkfun pro micro+#BOARD_TAG = promicro16+#ALTERNATE_CORE = promicro+#BOARDS_TXT = $(HOME)/arduino/hardware/promicro/boards.txt+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/promicro/bootloaders+#BOOTLOADER_PATH = caterina+#BOOTLOADER_FILE = Caterina-promicro16.hex+#ISP_PROG = usbasp+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- chipkit+#BOARD_TAG = mega_pic32+#MPIDE_DIR = /where/you/installed/mpide-0023-linux64-20130817-test+#include /usr/share/arduino/chipKIT.mk++# --- pinoccio+#BOARD_TAG = pinoccio256+#ALTERNATE_CORE = pinoccio+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/pinoccio/bootloaders+#BOOTLOADER_PATH = STK500RFR2/release_0.51+#BOOTLOADER_FILE = boot_pinoccio.hex+#CFLAGS_STD = -std=gnu99+#CXXFLAGS_STD = -std=gnu++11+#include /usr/share/arduino/Arduino.mk++# --- fio+#BOARD_TAG = fio+#include /usr/share/arduino/Arduino.mk++# --- atmega-ng ide 1.6+#BOARD_TAG = atmegang+#BOARD_SUB = atmega168+#MONITOR_PORT = /dev/ttyACM0+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- arduino-tiny ide 1.0+#ISP_PROG = usbasp+#BOARD_TAG = attiny85at8+#ALTERNATE_CORE = tiny+#ARDUINO_VAR_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny+#ARDUINO_CORE_PATH = $(HOME)/arduino/hardware/tiny/cores/tiny+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- arduino-tiny ide 1.6+#ISP_PROG = usbasp+#BOARD_TAG = attiny85at8+#ALTERNATE_CORE = tiny+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- damellis attiny ide 1.0+#ISP_PROG = usbasp+#BOARD_TAG = attiny85+#ALTERNATE_CORE = attiny-master+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- damellis attiny ide 1.6+#ISP_PROG = usbasp+#BOARD_TAG = attiny+#BOARD_SUB = attiny85+#ALTERNATE_CORE = attiny+#F_CPU = 16000000L+#ARDUINO_DIR = /where/you/installed/arduino-1.6.5+#include /usr/share/arduino/Arduino.mk++# --- teensy3+#BOARD_TAG = teensy31+#ARDUINO_DIR = /where/you/installed/the/patched/teensy/arduino-1.0.6+#include /usr/share/arduino/Teensy.mk++# --- mighty 1284p+#BOARD_TAG = mighty_opt+#BOARDS_TXT = $(HOME)/arduino/hardware/mighty-1284p/boards.txt+#BOOTLOADER_PARENT = $(HOME)/arduino/hardware/mighty-1284p/bootloaders+#BOOTLOADER_PATH = optiboot+#BOOTLOADER_FILE = optiboot_atmega1284p.hex+#ISP_PROG = usbasp+#AVRDUDE_OPTS = -v+#include /usr/share/arduino/Arduino.mk++# --- atmega328p on breadboard+#BOARD_TAG = atmega328bb+#ISP_PROG = usbasp+#AVRDUDE_OPTS = -v+#BOARDS_TXT = $(HOME)/arduino/hardware/breadboard/boards.txt+#include /usr/share/arduino/Arduino.mk
+ examples/button/README view
@@ -0,0 +1,24 @@+This is a demo program using arduino-copilot. ++To build the C code:++ runghc demo.hs++The resulting `.ino` sketch can be loaded into the Arduino IDE and flashed+to an Arduino Uno board using the IDE.++## Arduino-Makefile integration++The `Makefile` and `pre-build-hook.sh` show how to integrate arduino-copilot+with <https://github.com/sudar/Arduino-Makefile>. This automates generating+the C code, compiling that, and flashing it onto an Arduino Uno board,+with a single command++ make upload++Note that you will need to manually build the C code once, as shown above+, since the Arduino-Makefile expects to find a `.ino` file.++The path in the `Makefile` to `Arduino.mk` may need to be adjusted (the+default is the location where on a Debian system, `apt-get install+arduino-mk` will install it).
+ examples/button/demo.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE RebindableSyntax #-}++import Copilot.Arduino.Uno++longer_and_longer :: Stream Int16+longer_and_longer = counter true $ counter true false `mod` 64 == 0++counter :: Stream Bool -> Stream Bool -> Stream Int16+counter inc reset = cnt+ where+ cnt = if reset+ then 0+ else if inc+ then z + 1+ else z+ z = [0] ++ cnt++main :: IO ()+main = arduino $ do+ buttonpressed <- readfrom' pin12 [False, False, False, True, True]+ led =: buttonpressed || blinking+ delay =: longer_and_longer * 2
+ examples/button/pre-build-hook.sh view
@@ -0,0 +1,2 @@+#!/bin/sh+exec runghc demo.hs
− src/Arduino.hs
@@ -1,262 +0,0 @@-{-# LANGUAGE RebindableSyntax #-}--module Arduino (- module X,- -- * Arduino sketch generation- Sketch,- Input,- Output,- arduino,- -- * Combinators- (=:),- (@:),- -- * Inputs- boolInput,- boolInput',- -- TODO enumerate all avail pins, don't export constructor- Pin(..),- -- * Outputs- led,- MicroSeconds,- delay,- -- * Utilities- firstIteration,- sketchSpec,-) where--import Language.Copilot as X-import Copilot.Compile.C99-import System.Environment-import System.Directory-import System.Posix.Temp (mkdtemp)-import System.FilePath-import Text.Read-import Control.Monad.Writer-import Data.List (isInfixOf)-import qualified Prelude---- | An Arduino sketch, implemented using copilot.------ On each iteration of a Sketch, all inputs used by it are first--- collected, before any outputs are performed.------ Like a copilot `Spec`, a Sketch's outputs are not run in any--- particular order.-type Sketch = Sketch' ()--type Sketch' t = Writer [(Spec, Framework)] t--data Framework = Framework- { defines :: [CFragment]- , setups :: [CFragment]- , loops :: [CFragment]- }--type CFragment = String--instance Semigroup Framework where- a <> b = Framework- { defines = defines a <> defines b- , setups = setups a <> setups b- , loops = loops a <> loops b- }--instance Monoid Framework where- mempty = Framework mempty mempty mempty--class ToFramework t where- toFramework :: t -> Framework--type Behavior t = Stream t -> Spec---- | Somewhere that a Stream can be directed to, in order to control the--- Arduino.-data Output t = Output- { setupOutput :: [CFragment]- , outputCond :: Stream Bool- , outputBehavior :: Stream Bool -> Behavior t- }--instance ToFramework (Output t) where- toFramework o = Framework- { defines = mempty- , setups = setupOutput o- , loops = mempty- }---- | A source of a `Stream` of values input from the Arduino.-type Input t = Sketch' (Stream t)--data Input' t = Input'- { defineVar :: [CFragment]- , setupInput :: [CFragment]- , readInput :: [CFragment]- , inputStream :: Stream t- }--instance ToFramework (Input' t) where- toFramework i = Framework- { defines = defineVar i- , setups = setupInput i- , loops = readInput i- }---- | A GPIO pin-newtype Pin = Pin Int--mkInput :: Input' t -> Input t-mkInput i = do- tell [(return (), toFramework i)]- return (inputStream i)---- | Connect a `Stream` to an `Output`.-(=:) :: Output t -> Stream t -> Sketch-o =: s = tell [(go, toFramework o)]- where- go = (outputBehavior o) (outputCond o) s---- Same fixity as =<<-infixr 1 =:---- | By default, an `Output` is written to on each iteration of the Sketch.------ For example, this constantly turns on the LED, even though it will--- already be on after the first iteration.------ > led =: true------ To avoid unnecessary work being done, this combinator can make an--- `Output` only be written to when the current value of the provided--- `Stream` is True.------ So to make the LED only be turned on in the first iteration,--- and allow it to remain on thereafter without doing extra work:------ > led @: firstIteration =: true-(@:) :: Output t -> Stream Bool -> Output t-(@:) o c = o { outputCond = c }---- | True on the first iteration of the Sketch, and False thereafter.-firstIteration :: Stream Bool-firstIteration = [True]++false---- FIXME should be a newtype, but how to make a stream of a newtype?-type MicroSeconds = Int16---- | The on-board LED.-led :: Output Bool-led = Output- { setupOutput = ["pinMode(13, OUTPUT)"]- , outputBehavior = - \c v -> trigger "digitalWrite" c [arg (constI16 13), arg v]- , outputCond = true- }---- | Use this to add a delay between each iteration of the Sketch.-delay :: Output MicroSeconds-delay = Output- { setupOutput = []- , outputBehavior = \c n -> trigger "delay" c [arg n]- , outputCond = true- }---- | Reading from a GPIO pin.-boolInput :: Pin -> Input Bool-boolInput n = boolInput' n []---- | The optional list is used as simulated input--- when interpreting the program.-boolInput' :: Pin -> [Bool] -> Input Bool-boolInput' (Pin n) interpretvalues = mkInput $ Input'- { defineVar = ["bool " <> varname]- , setupInput = ["pinMode(" <> show n <> ", INPUT)"]- , readInput = [varname <> " = digitalRead(" <> show n <> ")"]- , inputStream = extern varname interpretvalues'- }- where- varname = "arduino_boolinput" <> show n- interpretvalues'- | null interpretvalues = Nothing- | otherwise = Just interpretvalues---- | Typically your Arduino program's main will use this. For example:------ > main = arduino $ do--- > led =: clk (period 2) (phase 1)--- > delay =: const16 100------ The `Sketch` is compiled into C code using copilot, and written--- to a .ino file. That can be built and uploaded to your Arduino--- using the Arduino IDE, or any other toolchain for Arduino sketches.-arduino :: Sketch -> IO ()-arduino s = do- let (is, fs) = unzip (execWriter s)- let spec = sequence_ is- -- TODO optparse-applicative- ps <- getArgs- case ps of- [] -> writeIno spec (mconcat fs)- ["-i", n] -> case readMaybe n of- Just n' -> interpret n' spec- Nothing -> error "expected a number after -i"- _ -> error "bad parameters"---- | Extracts a copilot `Spec` from a `Sketch`.------ This can be useful to intergrate with other libraries --- such as copilot-theorem.-sketchSpec :: Sketch -> Spec-sketchSpec s = sequence_ is- where- (is, _fs) = unzip (execWriter s)--writeIno :: Spec -> Framework -> IO ()-writeIno spec framework = do- -- This could be a lot prettier, unfortunately copilot only exports- -- an interface that writes the generated code to a file.- -- And, the .c file includes a .h file that will make it fail to- -- build when used in the .ino file, so that include has to be- -- filtered out.- toptmpdir <- getTemporaryDirectory- mytmpdir <- mkdtemp (toptmpdir </> "copilot")- reify spec >>= compile (mytmpdir </> "copilot")- c <- lines <$> readFile (mytmpdir </> "copilot.c")- let c' = filter (Prelude.not . isInfixOf "#include \"") c- -- Use a name for the ino file that will let the Arduino IDE find it.- d <- getCurrentDirectory- let dirbase = takeFileName d- writeFile (addExtension dirbase "ino") $ - sketchFramework framework c'- removeDirectoryRecursive mytmpdir- --sketchFramework :: Framework -> [String] -> String-sketchFramework f ccode = unlines $ concat- [- [ "/* automatically generated, do not edit */"- , blank- , "#include <stdbool.h>"- , "#include <stdint.h>"- , blank- ]- , map statement (defines f)- , [blank]- , ccode- , [blank]- ,- [ "void setup()"- ]- , codeblock $ map statement (setups f)- , [blank]- ,- [ "void loop()"- ]- , codeblock $ map statement $ (loops f) <>- [ "step()"- ]- ]- where- blank = ""- indent l = " " <> l- statement d = d <> ";"- codeblock l = ["{"] <> map indent l <> ["}"]
+ src/Copilot/Arduino.hs view
@@ -0,0 +1,163 @@+-- | Programming the Arduino with Copilot.+--+-- This module should work on any model of Arduino.+-- See Arduino.Uno and Arduino.Nano for model-specific code.++{-# LANGUAGE RebindableSyntax #-}++module Copilot.Arduino (+ -- * Arduino sketch generation+ arduino,+ Sketch,+ Input,+ Output,+ Stream,+ GPIO,+ -- * Combinators+ (=:),+ (@:),+ -- * Inputs+ readfrom,+ readfrom',+ -- * Outputs+ --+ -- | Only outputs that work on all Arduino boards are included+ -- here. Load a module such as Arduino.Uno for model-specific+ -- outputs.+ led,+ writeto,+ MicroSeconds,+ delay,+ -- * Utilities+ blinking,+ firstIteration,+ sketchSpec,+ -- * Copilot DSL+ --+ -- | The Copilot.Language module is re-exported here, including+ -- a version of the Prelude modified for it. You should enable+ -- the RebindableSyntax language extension in your program+ -- to use the Copilot DSL.+ --+ -- > {-# LANGUAGE RebindableSyntax #-}+ --+ -- For documentation on using the Copilot DSL, see+ -- <https://copilot-language.github.io/>+ module Language.Copilot,+) where++import qualified Language.Copilot+import Language.Copilot hiding (Stream)+import Copilot.Arduino.Internals+import Copilot.Arduino.Main+import Control.Monad.Writer++-- | A value that varies over time.+--+-- The Copilot DSL provides many operations on streams, for example+-- `Language.Copilot.&&` to combine two streams of Bools.+-- +-- For documentation on using the Copilot DSL, see+-- <https://copilot-language.github.io/>+type Stream t = Language.Copilot.Stream t++-- | Connect a `Stream` to an `Output`.+--+-- > led := blinking+(=:) :: Output t -> Stream t -> Sketch ()+o =: s = tell [(go, toFramework o)]+ where+ go = (outputBehavior o) (outputCond o) s++-- | Use this to make a LED blink on and off.+--+-- On each iteration of the `Sketch`, this changes to the opposite of its+-- previous value.+--+-- This is implemented using Copilot's `clk`, so to get other blinking+-- behaviors, just pick different numbers, or use Copilot `Stream`+-- combinators.+-- +-- > blinking = clk (period 2) (phase 1)+blinking :: Stream Bool+blinking = clk (period (2 :: Integer)) (phase (1 :: Integer))++-- Same fixity as =<<+infixr 1 =:++-- | By default, an `Output` is written to on each iteration of the `Sketch`.+--+-- For example, this constantly turns on the LED, even though it will+-- already be on after the first iteration.+--+-- > led =: true+--+-- To avoid unnecessary work being done, this combinator can make an+-- `Output` only be written to when the current value of the provided+-- `Stream` is True.+--+-- So to make the LED only be turned on in the first iteration,+-- and allow it to remain on thereafter without doing extra work:+--+-- > led @: firstIteration =: true+(@:) :: Output t -> Stream Bool -> Output t+(@:) o c = o { outputCond = c }++-- | True on the first iteration of the `Sketch`, and False thereafter.+firstIteration :: Stream Bool+firstIteration = [True]++false++-- | Use this to add a delay between each iteration of the `Sketch`.+-- A `Sketch` with no delay will run as fast as the hardware can run it.+delay :: Output MicroSeconds+delay = Output+ { setupOutput = []+ , outputBehavior = \c n -> trigger "delay" c [arg n]+ , outputCond = true+ }++-- | Reading from a GPIO pin.+--+-- > do+-- > buttonpressed <- readfrom pin12+-- > led := buttonpressed+readfrom :: GPIO -> Input Bool+readfrom n = readfrom' n []++-- | The list is used as simulated input when interpreting the program.+readfrom' :: GPIO -> [Bool] -> Input Bool+readfrom' (GPIO n) interpretvalues = mkInput $ InputSource+ { defineVar = ["bool " <> varname]+ , setupInput = ["pinMode(" <> show n <> ", INPUT)"]+ , readInput = [varname <> " = digitalRead(" <> show n <> ")"]+ , inputStream = extern varname interpretvalues'+ }+ where+ varname = "arduino_gpio_input" <> show n+ interpretvalues'+ | null interpretvalues = Nothing+ | otherwise = Just interpretvalues++-- | Writing to a GPIO pin.+writeto :: GPIO -> Output Bool+writeto (GPIO n) = Output+ { setupOutput = ["pinMode(" <> sn <> ", OUTPUT)"]+ , outputBehavior = + \c v -> trigger "digitalWrite" c [arg (constant n), arg v]+ , outputCond = true+ }+ where+ sn = show n++-- | The on-board LED.+led :: Output Bool+led = writeto (GPIO 13)++-- | Extracts a copilot `Spec` from a `Sketch`.+--+-- This can be useful to intergrate with other libraries +-- such as copilot-theorem.+sketchSpec :: Sketch a -> Spec+sketchSpec (Sketch s) = sequence_ is+ where+ (is, _fs) = unzip (execWriter s)
+ src/Copilot/Arduino/Internals.hs view
@@ -0,0 +1,145 @@+-- | You should not need to import this module unless you're adding support+-- for a new model of Arduino, or an Arduino library.++{-# LANGUAGE RebindableSyntax #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleInstances #-}++module Copilot.Arduino.Internals where++import Language.Copilot+import Control.Monad.Writer++-- | An Arduino sketch, implemented using Copilot.+--+-- It's best to think of the `Sketch` as a description of the state of the+-- Arduino at any point in time.+--+-- Under the hood, the `Sketch` is run in a loop. On each iteration, it first+-- reads all inputs and then updates outputs as needed. While it is a monad,+-- a Sketch's outputs are not updated in any particular order, because+-- Copilot does not guarantee any order.+newtype Sketch t = Sketch (Writer [(Spec, Framework)] t)+ deriving (Monad, Applicative, Functor, MonadWriter [(Spec, Framework)])++instance Monoid (Sketch ()) where+ mempty = Sketch (return ())++instance Semigroup (Sketch t) where+ (Sketch a) <> (Sketch b) = Sketch (a >> b)++-- | The framework of an Arduino sketch.+data Framework = Framework+ { defines :: [CFragment]+ -- ^ Things that come before the C code generated by Copilot.+ , setups :: [CFragment]+ -- ^ Things to run in `setup`.+ , loops :: [CFragment]+ -- ^ Things to run in `loop`.+ }++-- | A fragment of C code.+type CFragment = String++instance Semigroup Framework where+ a <> b = Framework+ { defines = defines a <> defines b+ , setups = setups a <> setups b+ , loops = loops a <> loops b+ }++instance Monoid Framework where+ mempty = Framework mempty mempty mempty++class ToFramework t where+ toFramework :: t -> Framework++type Behavior t = Stream t -> Spec++-- | Somewhere that a Stream can be directed to, in order to control the+-- Arduino.+data Output t = Output+ { setupOutput :: [CFragment]+ -- ^ How to set up the output.+ , outputCond :: Stream Bool+ , outputBehavior :: Stream Bool -> Behavior t+ }++instance ToFramework (Output t) where+ toFramework o = Framework+ { defines = mempty+ , setups = setupOutput o+ , loops = mempty+ }++-- | A source of a `Stream` of values input from the Arduino.+--+-- Runs in the `Sketch` monad.+type Input t = Sketch (Stream t)++data InputSource t = InputSource+ { defineVar :: [CFragment]+ -- ^ Added to the `Framework`'s `defines`, this typically+ -- defines a C variable.+ , setupInput :: [CFragment]+ -- ^ How to set up the input.+ , readInput :: [CFragment]+ -- ^ How to read a value from the input, this typically+ -- reads a value into a C variable.+ , inputStream :: Stream t+ }++instance ToFramework (InputSource t) where+ toFramework i = Framework+ { defines = defineVar i+ , setups = setupInput i+ , loops = readInput i+ }++mkInput :: InputSource t -> Input t+mkInput i = do+ tell [(return (), toFramework i)]+ return (inputStream i)++-- | A GPIO pin+--+-- For definitions of GPIO pins like `Copilot.Arduino.Uno.pin12`, +-- load a module such as Copilot.Arduino.Uno, which provides the pins of a+-- particular board.+newtype GPIO = GPIO Int16++-- FIXME should be a newtype, but how to make a stream of a newtype?+type MicroSeconds = Int16++-- | Makes an arduino sketch, using a Framework, and a list of lines of C+-- code generated by Copilot.+sketchFramework :: Framework -> [String] -> [CFragment]+sketchFramework f ccode = concat+ [+ [ "/* automatically generated, do not edit */"+ , blank+ , "#include <stdbool.h>"+ , "#include <stdint.h>"+ , blank+ ]+ , map statement (defines f)+ , [blank]+ , ccode+ , [blank]+ ,+ [ "void setup()"+ ]+ , codeblock $ map statement (setups f)+ , [blank]+ ,+ [ "void loop()"+ ]+ , codeblock $ map statement $ (loops f) <>+ [ "step()"+ ]+ ]+ where+ blank = ""+ indent l = " " <> l+ statement d = d <> ";"+ codeblock l = ["{"] <> map indent l <> ["}"]
+ src/Copilot/Arduino/Main.hs view
@@ -0,0 +1,84 @@+module Copilot.Arduino.Main (arduino) where++import Language.Copilot (Spec, interpret, reify)+import Copilot.Compile.C99 (compile)+import Copilot.Arduino.Internals+import System.Directory+import System.Posix.Temp (mkdtemp)+import System.FilePath+import Control.Monad.Writer+import Data.List (isInfixOf)+import Options.Applicative++-- | Typically your Arduino program's main will be implemented using this.+-- For example:+--+-- > {-# LANGUAGE RebindableSyntax #-}+-- > +-- > import Copilot.Arduino+-- > +-- > main = arduino $ do+-- > led =: flashing+-- > delay =: constant 100+--+-- Running this program compiles the `Sketch` into C code using copilot, and+-- writes it to a .ino file. That can be built and uploaded to your Arduino+-- using the Arduino IDE, or any other toolchain for Arduino sketches.+--+-- This also supports interpreting a `Sketch`, without loading it onto an+-- Arduino. Run the program with parameters "-i 4" to display what it+-- would do on the first 4 iterations. The output will look something like+-- this:+--+-- > delay: digitalWrite: +-- > (100) (13,false) +-- > (100) (13,true) +-- > (100) (13,false) +-- > (100) (13,true) +arduino :: Sketch () -> IO ()+arduino (Sketch s) = go =<< execParser opts+ where+ opts = info (parseCmdLine <**> helper)+ ( fullDesc+ <> progDesc "Run this program with no options to generate an Arduino sketch."+ )++ go o = case interpretSteps o of+ Just n -> interpret n spec+ Nothing -> writeIno spec (mconcat fs)+ + (is, fs) = unzip (execWriter s)+ spec = sequence_ is++data CmdLine = CmdLine+ { interpretSteps :: Maybe Integer+ }+++parseCmdLine :: Parser CmdLine+parseCmdLine = CmdLine+ <$> optional (option auto+ ( long "interpret"+ <> short 'i'+ <> help "use copilot to interpret the program, displaying what it would do"+ <> metavar "NUM"+ ))++writeIno :: Spec -> Framework -> IO ()+writeIno spec framework = do+ -- This could be a lot prettier, unfortunately copilot only exports+ -- an interface that writes the generated code to a file.+ -- And, the .c file includes a .h file that will make it fail to+ -- build when used in the .ino file, so that include has to be+ -- filtered out.+ toptmpdir <- getTemporaryDirectory+ mytmpdir <- mkdtemp (toptmpdir </> "copilot")+ reify spec >>= compile (mytmpdir </> "copilot")+ c <- lines <$> readFile (mytmpdir </> "copilot.c")+ let c' = filter (Prelude.not . isInfixOf "#include \"") c+ -- Use a name for the ino file that will let the Arduino IDE find it.+ d <- getCurrentDirectory+ let dirbase = takeFileName d+ writeFile (addExtension dirbase "ino") $ + unlines $ sketchFramework framework c'+ removeDirectoryRecursive mytmpdir
+ src/Copilot/Arduino/Nano.hs view
@@ -0,0 +1,51 @@+-- | Programming the Arduino Nano with Copilot.++module Copilot.Arduino.Nano (+ -- * General Arduino programming infrastructure+ module Copilot.Arduino+ -- * GPIO+ , pin2+ , pin3+ , pin4+ , pin5+ , pin6+ , pin7+ , pin8+ , pin9+ , pin10+ , pin11+ , pin12+ , pin13+ -- * Analog input+ -- TODO!+ --, a0+ --, a1+ --, a2+ --, a3+ --, a4+ --, a5+ --, a6+ --, a7+ -- * UART+ -- Not currently supported!+ --, uart+) where++import Copilot.Arduino+import Copilot.Arduino.Internals++pin2, pin3, pin4, pin5, pin6, pin7, pin8, pin9, pin10, pin11, pin12, pin13 :: GPIO+pin2 = GPIO 2+pin3 = GPIO 3+pin4 = GPIO 4+pin5 = GPIO 5+pin6 = GPIO 6+pin7 = GPIO 7+pin8 = GPIO 8+pin9 = GPIO 9+pin10 = GPIO 10+pin11 = GPIO 11+pin12 = GPIO 12+-- | This pin is connected to the `led`+pin13 = GPIO 13+
+ src/Copilot/Arduino/Uno.hs view
@@ -0,0 +1,49 @@+-- | Programming the Arduino Uno with Copilot.++module Copilot.Arduino.Uno (+ -- * General Arduino programming infrastructure+ module Copilot.Arduino+ -- * GPIO+ , pin2+ , pin3+ , pin4+ , pin5+ , pin6+ , pin7+ , pin8+ , pin9+ , pin10+ , pin11+ , pin12+ , pin13+ -- * Analog input+ -- TODO!+ --, a0+ --, a1+ --, a2+ --, a3+ --, a4+ --, a5+ -- * UART+ -- Not currently supported!+ --, uart+) where++import Copilot.Arduino+import Copilot.Arduino.Internals++pin2, pin3, pin4, pin5, pin6, pin7, pin8, pin9, pin10, pin11, pin12, pin13 :: GPIO+pin2 = GPIO 2+pin3 = GPIO 3+pin4 = GPIO 4+pin5 = GPIO 5+pin6 = GPIO 6+pin7 = GPIO 7+pin8 = GPIO 8+pin9 = GPIO 9+pin10 = GPIO 10+pin11 = GPIO 11+pin12 = GPIO 12+-- | This pin drives the `led`+pin13 = GPIO 13+