summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assignment-13/Arduino.dcl10
-rw-r--r--assignment-13/Arduino.icl16
-rw-r--r--assignment-13/Bootstrap.dcl33
-rw-r--r--assignment-13/Bootstrap.icl118
-rw-r--r--assignment-13/C.dcl71
-rw-r--r--assignment-13/C.icl93
-rw-r--r--assignment-13/Util.dcl19
-rw-r--r--assignment-13/Util.icl37
-rw-r--r--assignment-13/ufpl.dcl94
-rw-r--r--assignment-13/ufpl.icl217
10 files changed, 708 insertions, 0 deletions
diff --git a/assignment-13/Arduino.dcl b/assignment-13/Arduino.dcl
new file mode 100644
index 0000000..abb4888
--- /dev/null
+++ b/assignment-13/Arduino.dcl
@@ -0,0 +1,10 @@
+definition module Arduino
+
+from StdOverloaded import class toString
+
+from Util import class print
+
+:: Button = B0 | B1 | B2 | B3 | B4 | B5
+
+instance toString Button
+instance print Button
diff --git a/assignment-13/Arduino.icl b/assignment-13/Arduino.icl
new file mode 100644
index 0000000..fe108f4
--- /dev/null
+++ b/assignment-13/Arduino.icl
@@ -0,0 +1,16 @@
+implementation module Arduino
+
+import StdOverloaded
+
+import Util
+
+instance toString Button
+where
+ toString B0 = "B0"
+ toString B1 = "B1"
+ toString B2 = "B2"
+ toString B3 = "B3"
+ toString B4 = "B4"
+ toString B5 = "B5"
+
+instance print Button where print b = print (toString b)
diff --git a/assignment-13/Bootstrap.dcl b/assignment-13/Bootstrap.dcl
new file mode 100644
index 0000000..682714c
--- /dev/null
+++ b/assignment-13/Bootstrap.dcl
@@ -0,0 +1,33 @@
+definition module Bootstrap
+
+import ufpl
+
+rwBool :: String Bool -> Expr Bool RW
+roBool :: String Bool -> Expr Bool RO
+
+rwInt :: String Int -> Expr Int RW
+roInt :: String Int -> Expr Int RO
+rwUInt :: String Int -> Expr Int RW
+roUInt :: String Int -> Expr Int RO
+
+rwLong :: String Int -> Expr Int RW
+roLong :: String Int -> Expr Int RO
+rwULong :: String Int -> Expr Int RW
+roULong :: String Int -> Expr Int RO
+
+boolmap :: Bimap Bool CExpr
+intmap :: Bimap Int CExpr
+longmap :: Bimap Int CExpr
+
+b0 :: Expr Bool RO
+b1 :: Expr Bool RO
+b2 :: Expr Bool RO
+b3 :: Expr Bool RO
+b4 :: Expr Bool RO
+
+millis :: Expr Int RO
+
+false :: Expr Bool RO
+true :: Expr Bool RO
+
+rts :: String
diff --git a/assignment-13/Bootstrap.icl b/assignment-13/Bootstrap.icl
new file mode 100644
index 0000000..3982566
--- /dev/null
+++ b/assignment-13/Bootstrap.icl
@@ -0,0 +1,118 @@
+implementation module Bootstrap
+
+from StdFunc import const
+import StdGeneric
+from StdMisc import undef
+import StdString
+
+import Arduino
+import C
+import ufpl
+
+rwBool :: String Bool -> Expr Bool RW
+rwBool n d = EShared {sname=n, stype=CTBool, sinit=d, srepr=boolmap}
+
+roBool :: String Bool -> Expr Bool RO
+roBool n d = EShared {sname=n, stype=CTBool, sinit=d, srepr=boolmap}
+
+rwInt :: String Int -> Expr Int RW
+rwInt n d = EShared {sname=n, stype=CTInt Sig, sinit=d, srepr=intmap}
+
+roInt :: String Int -> Expr Int RO
+roInt n d = EShared {sname=n, stype=CTInt Sig, sinit=d, srepr=intmap}
+
+rwUInt :: String Int -> Expr Int RW
+rwUInt n d = EShared {sname=n, stype=CTInt Unsig, sinit=d, srepr=intmap}
+
+roUInt :: String Int -> Expr Int RO
+roUInt n d = EShared {sname=n, stype=CTInt Unsig, sinit=d, srepr=intmap}
+
+rwLong :: String Int -> Expr Int RW
+rwLong n d = EShared {sname=n, stype=CTLong Sig, sinit=d, srepr=longmap}
+
+roLong :: String Int -> Expr Int RO
+roLong n d = EShared {sname=n, stype=CTLong Sig, sinit=d, srepr=longmap}
+
+rwULong :: String Int -> Expr Int RW
+rwULong n d = EShared {sname=n, stype=CTLong Unsig, sinit=d, srepr=longmap}
+
+roULong :: String Int -> Expr Int RO
+roULong n d = EShared {sname=n, stype=CTLong Unsig, sinit=d, srepr=longmap}
+
+boolmap :: Bimap Bool CExpr
+boolmap = {map_to=CEBool, map_from= \(CEBool b) -> b}
+
+intmap :: Bimap Int CExpr
+intmap = {map_to=CEInt, map_from= \(CEInt i) -> i}
+
+longmap :: Bimap Int CExpr
+longmap = {map_to=CEInt, map_from= \(CEInt i) -> i}
+
+b0 :: Expr Bool RO
+b0 = roBool "b0" False
+
+b1 :: Expr Bool RO
+b1 = roBool "b1" False
+
+b2 :: Expr Bool RO
+b2 = roBool "b2" False
+
+b3 :: Expr Bool RO
+b3 = roBool "b3" False
+
+b4 :: Expr Bool RO
+b4 = roBool "b4" False
+
+millis :: Expr Int RO
+millis = roLong "millis" 0
+
+false :: Expr Bool RO
+false = lit False
+
+true :: Expr Bool RO
+true = lit True
+
+rts :: String
+rts =
+ "#include <LiquidCrystal.h>" +:
+ "LiquidCrystal lcd = LiquidCrystal(8, 9, 4, 5, 6, 7);" +:
+
+ sharetype "b" "bool" +:
+ sharetype "c" "signed char" +:
+ sharetype "uc" "unsigned char" +:
+ sharetype "i" "signed int" +:
+ sharetype "ui" "unsigned int" +:
+ sharetype "l" "signed long" +:
+ sharetype "ul" "unsigned long"
+where
+ (+:) infixl 6 :: String String -> String
+ (+:) a b = a +++ "\n" +++ b
+
+ sharetype :: String String -> String
+ sharetype short long =
+ "struct " +++ short +++ "share {" +:
+ " " +++ long +++ " val;" +:
+ " unsigned char dirty;" +:
+ " unsigned char subscriptions;" +:
+ "};" +:
+
+ "void " +++ short +++ "subscribe(struct " +++ short +++ "share *share) {" +:
+ " share->subscriptions++;" +:
+ "}" +:
+
+ "void " +++ short +++ "release(struct " +++ short +++ "share *share) {" +:
+ " share->subscriptions--;" +:
+ "}" +:
+
+ "void " +++ short +++ "set(struct " +++ short +++ "share *share, " +++ long +++ " val) {" +:
+ " share->val = val;" +:
+ " share->dirty = share->subscriptions;" +:
+ "}" +:
+
+ "bool " +++ short +++ "dirty(struct " +++ short +++ "share *share) {" +:
+ " if (share->dirty) {" +:
+ " share->dirty--;" +:
+ " return 1;" +:
+ " }" +:
+ " return 0;" +:
+ "}"
diff --git a/assignment-13/C.dcl b/assignment-13/C.dcl
new file mode 100644
index 0000000..88b048f
--- /dev/null
+++ b/assignment-13/C.dcl
@@ -0,0 +1,71 @@
+definition module C
+
+from Data.Maybe import :: Maybe
+
+from Arduino import :: Button
+from Util import class print
+
+:: Signedness = Sig | Unsig
+
+:: CType
+ = CTChar Signedness
+ | CTBool
+ | CTInt Signedness
+ | CTLong Signedness
+ | CTVoid
+ | CTArray CType
+ | CTStruct String
+
+:: CExpr
+ = CEButton Button
+ | CEGlobal String
+ | CEInfix String CExpr CExpr
+ | CEApp String [CExpr]
+ | CEBool Bool
+ | CEInt Int
+ | CEChar Char
+ | CEBArray Int [Bool]
+ | CEIArray Int [Int]
+ | CEIf CExpr CExpr CExpr
+ | CERef CExpr
+ | CEDeref CExpr
+
+:: CBody
+ = CBReturn (Maybe CExpr)
+ | CBIf CExpr CBody CBody
+ | CBWhile CExpr CBody
+ | CBAssign String CExpr
+ | CBSeq CBody CBody
+ | CBEmpty
+ | CBExpr CExpr
+
+(`seq`) infix 0 :: CBody CBody -> CBody
+
+:: CVar =
+ { name :: String
+ , type :: CType
+ , value :: CExpr
+ }
+
+:: CFun =
+ { params :: [(Int, CType)]
+ , body :: CBody
+ , fresh :: Int
+ , type :: CType
+ , name :: String
+ }
+
+:: CG t p = CG (CFun -> (t, CFun))
+
+unCG :: (CG t p) -> CFun -> (t, CFun)
+cg :: (CG t p) -> CFun
+
+(>>-) infixl 1 :: (CG a p) (a -> CG b q) -> CG b q
+return :: (a -> CG a p)
+
+instance print Signedness
+instance print CType
+instance print CExpr
+instance print CBody
+instance print CVar
+instance print CFun
diff --git a/assignment-13/C.icl b/assignment-13/C.icl
new file mode 100644
index 0000000..328802f
--- /dev/null
+++ b/assignment-13/C.icl
@@ -0,0 +1,93 @@
+implementation module C
+
+from StdFunc import id, o
+import StdString
+import StdTuple
+
+import Data.Generics.GenDefault
+import Data.Maybe
+import Data.Tuple
+
+import Arduino
+import Util
+
+(`seq`) infix 0 :: CBody CBody -> CBody
+(`seq`) CBEmpty cb = cb
+(`seq`) cb CBEmpty = cb
+(`seq`) a b = CBSeq a b
+
+gDefault{|UNIT|} = UNIT
+gDefault{|RECORD|} f = RECORD f
+gDefault{|Bool|} = False
+gDefault{|Char|} = '\x00'
+gDefault{|Maybe|} _ = Nothing
+
+derive gDefault Button, Signedness, CType, CExpr, CBody, CFun
+
+unCG :: (CG t p) -> CFun -> (t, CFun)
+unCG (CG f) = f
+
+cg :: (CG t p) -> CFun
+cg (CG f) = snd (f gDefault{|*|})
+
+(>>-) infixl 1 :: (CG a p) (a -> CG b q) -> CG b q
+(>>-) (CG f) g = CG \st -> case f st of (x, st) -> unCG (g x) st
+
+return :: (a -> CG a p)
+return = CG o tuple
+
+instance print Signedness
+where
+ print Sig = print "signed"
+ print Unsig = print "unsigned"
+
+instance print CType
+where
+ print (CTChar s) = print s o print " char"
+ print CTBool = print "bool"
+ print (CTInt s) = print s o print " int"
+ print (CTLong s) = print s o print " long"
+ print CTVoid = print "void"
+ print (CTArray t) = print "*" o print t
+ print (CTStruct s) = print "struct " o print s
+
+instance print (Int,CType) // Variable
+where
+ print (i,t) = print t o print " v" o print i
+
+instance print CExpr
+where
+ print (CEButton b) = print b
+ print (CEGlobal g) = print g
+ print (CEInfix op a b) = print "(" o print a o print ") " o print op o print " (" o print b o print ")"
+ print (CEApp f ps) = print f o print "(" o prsperse ", " ps o print ")"
+ print (CEBool b) = print (if b "true" "false")
+ print (CEInt i) = print i
+ print (CEChar c) = print "'" o print (toString c) o print "'"
+ print (CEIf b t e) = print "(" o print b o print " ? " o print t o print " : " o print e o print ")"
+ print (CERef e) = print "&(" o print e o print ")"
+ print (CEDeref e) = print "*(" o print e o print ")"
+
+instance print CBody
+where
+ print (CBReturn Nothing) = print "return;"
+ print (CBReturn (Just e)) = print "return " o print e o print ";"
+ print (CBIf c t e) = print "if (" o print c o print ") {" o indent o nl
+ o print t o unindent o nl
+ o print "} else {" o indent o nl
+ o print e o unindent o nl o print "}"
+ print (CBWhile e b) = print "while (" o print e o print ") {" o nl o print b o nl o print "}"
+ print (CBAssign v e) = print v o print " = " o print e o print ";"
+ print (CBSeq a b) = print a o nl o print b
+ print CBEmpty = id
+ print (CBExpr e) = print e o print ";"
+
+instance print CVar
+where
+ print v = print v.CVar.type o print " " o print v.CVar.name o print " = " o print v.value o print ";"
+
+instance print CFun
+where
+ print cf = print cf.CFun.type o print " " o print cf.CFun.name
+ o print "(" o prsperse ", " cf.params o print ") {" o indent o nl
+ o print cf.body o unindent o nl o print "}"
diff --git a/assignment-13/Util.dcl b/assignment-13/Util.dcl
new file mode 100644
index 0000000..11ad93e
--- /dev/null
+++ b/assignment-13/Util.dcl
@@ -0,0 +1,19 @@
+definition module Util
+
+:: PrState =
+ { indent :: Int
+ , output :: [String]
+ }
+
+class print a :: a -> PrState -> PrState
+
+printToString :: a -> String | print a
+
+instance print String
+instance print Int
+
+nl :: PrState -> PrState
+indent :: PrState -> PrState
+unindent :: PrState -> PrState
+
+prsperse :: a [b] -> PrState -> PrState | print a & print b
diff --git a/assignment-13/Util.icl b/assignment-13/Util.icl
new file mode 100644
index 0000000..7775601
--- /dev/null
+++ b/assignment-13/Util.icl
@@ -0,0 +1,37 @@
+implementation module Util
+
+import StdClass
+from StdFunc import id, o
+import StdInt
+import StdList
+import StdOverloaded
+import StdString
+
+from Text import class Text(concat), instance Text String
+
+instance zero PrState
+where
+ zero =
+ { indent = 0
+ , output = []
+ }
+
+printToString :: a -> String | print a
+printToString x = concat (print x zero).output
+
+instance print String where print s = \st -> {st & output=[s:st.output]}
+instance print Int where print i = \st -> {st & output=[toString i:st.output]}
+
+nl :: PrState -> PrState
+nl st = {st & output=["\n":repeatn st.indent "\t"] ++ st.output}
+
+indent :: PrState -> PrState
+indent st = {st & indent=max 0 (st.indent - 1)}
+
+unindent :: PrState -> PrState
+unindent st = {st & indent=st.indent + 1}
+
+prsperse :: a [b] -> PrState -> PrState | print a & print b
+prsperse _ [] = id
+prsperse _ [x] = print x
+prsperse g [x:xs] = print x o print g o prsperse g xs
diff --git a/assignment-13/ufpl.dcl b/assignment-13/ufpl.dcl
new file mode 100644
index 0000000..bf3e010
--- /dev/null
+++ b/assignment-13/ufpl.dcl
@@ -0,0 +1,94 @@
+definition module ufpl
+
+from StdGeneric import :: Bimap
+from StdOverloaded import class +, class -, class *, class /, class ==, class <
+
+from C import :: CType, :: CExpr, :: CBody, :: CVar, :: CFun
+
+:: RO = RO
+:: RW = RW
+
+:: Shared t w =
+ { sname :: String
+ , stype :: CType
+ , sinit :: t
+ , srepr :: Bimap t CExpr
+ }
+
+:: Shares
+ = NoShares
+ | E.t rw: Shares (Shared t rw) Shares
+
+removeDupShares :: Shares -> Shares
+
+class allShares t
+where
+ allShares` :: t -> Shares
+
+ allShares :: t -> Shares
+ allShares x :== removeDupShares (allShares` x)
+
+instance allShares [t] | allShares t
+instance allShares (Expr t rw)
+instance allShares Trigger
+instance allShares Rule
+instance allShares NamedRule
+
+class Expr t where litExpr :: t -> CExpr
+instance Expr Int
+instance Expr Bool
+instance Expr Char
+
+:: Expr t rw
+ = ELit t
+ | EShared (Shared t rw)
+ | E.rwa rwb: (+.) infixl 6 (Expr t rwa) (Expr t rwb) & + t
+ | E.rwa rwb: (-.) infixl 6 (Expr t rwa) (Expr t rwb) & - t
+ | E.rwa rwb: (*.) infixl 7 (Expr t rwa) (Expr t rwb) & * t
+ | E.rwa rwb: (/.) infixl 7 (Expr t rwa) (Expr t rwb) & / t
+ | E.rwa rwb u: EEq (Bimap t Bool) (Expr u rwa) (Expr u rwb) & Expr, == u
+ | E.rwa rwb u: ELt (Bimap t Bool) (Expr u rwa) (Expr u rwb) & Expr, < u
+ | E.rwa rwb: EAnd (Bimap t Bool) (Expr Bool rwa) (Expr Bool rwb)
+ | E.rwa rwb: EOr (Bimap t Bool) (Expr Bool rwa) (Expr Bool rwb)
+ | E.rwa rwb rwc: EIf (Expr Bool rwa) (Expr t rwb) (Expr t rwc)
+
+lit :: (t -> Expr t RO)
+(?) infix 4 :: (Expr Bool rwa) (Expr t rwb, Expr t rwc) -> Expr t RO
+
+(==.) infix 4 :: (Expr t rwa) (Expr t rwb) -> Expr Bool RO | Expr, == t
+(<.) infix 4 :: (Expr t rwa) (Expr t rwb) -> Expr Bool RO | Expr, < t
+(>.) infix 4 :: (Expr t rwa) (Expr t rwb) -> Expr Bool RO | Expr, < t
+
+(&&.) infixr 3 :: (Expr Bool rwa) (Expr Bool rwb) -> Expr Bool RO
+(||.) infixr 4 :: (Expr Bool rwa) (Expr Bool rwb) -> Expr Bool RO
+
+:: Trigger
+ = E.t rw: Change (Expr t rw) & Expr t
+ | E.t rwa rwb: (?=) (Expr t rwa) (Expr t rwb) & Expr, == t
+ | (?&) infixr 3 Trigger Trigger
+ | (?|) infixr 4 Trigger Trigger
+
+:: Rule
+ = E.t rw: (<#) infix 3 (Expr t RW) (Expr t rw) & Expr t
+ | E.rw: When (Expr Bool rw) [Rule]
+ | (>>>) infixr 2 Trigger [Rule]
+ | E.rwa rwb: SetCursor (Expr Int rwa, Expr Int rwb)
+ | E.t rw: Print (Expr t rw) & Expr t
+
+:: NamedRule = E.r: (:=:) infix 1 String r & gen r CBody & allShares r
+
+class gen f t :: f -> t
+
+class (:.) infixr 2 r :: Rule r -> [Rule]
+instance :. Rule
+instance :. [Rule]
+
+class (|||) infixr 0 r :: NamedRule r -> [NamedRule]
+instance ||| NamedRule
+instance ||| [NamedRule]
+
+instance gen (Expr t rw) CExpr | Expr t
+instance gen Rule CBody
+instance gen [r] CBody | gen r CBody
+instance gen NamedRule CFun
+instance gen (Shared t rw) CVar
diff --git a/assignment-13/ufpl.icl b/assignment-13/ufpl.icl
new file mode 100644
index 0000000..73d1ff0
--- /dev/null
+++ b/assignment-13/ufpl.icl
@@ -0,0 +1,217 @@
+implementation module ufpl
+
+import StdArray
+import StdBool
+import StdClass
+from StdFunc import const, flip, id, o
+from StdGeneric import :: Bimap{..}, bimapId; bm :== bimapId
+import StdInt
+import StdList
+import StdMisc
+import StdOverloaded
+import StdString
+import StdTuple
+
+from Data.Func import $
+import Data.List
+
+import Arduino
+import Bootstrap
+import C
+import Util
+
+typedfun :: CType String -> String
+typedfun t f = flip (+++) f case t of
+ CTBool -> "b"
+ CTInt s -> sig s +++ "i"
+ CTChar s -> sig s +++ "c"
+ CTLong s -> sig s +++ "l"
+where
+ sig :: Signedness -> String
+ sig Sig = ""
+ sig Unsig = "u"
+
+append :: Shares Shares -> Shares
+append NoShares ss = ss
+append (Shares s ss) sss = Shares s (append ss sss)
+
+removeDupShares :: Shares -> Shares
+removeDupShares NoShares = NoShares
+removeDupShares (Shares s ss) = if exists id (Shares s) (removeDupShares ss)
+where
+ exists = any (\s` -> s.sname == s`) (sharesMap (\s -> s.sname) ss)
+
+sharesMap :: (A.t rw: (Shared t rw) -> a) Shares -> [a]
+sharesMap _ NoShares = []
+sharesMap f (Shares s ss) = [f s:sharesMap f ss]
+
+instance allShares [t] | allShares t
+where
+ allShares` [] = NoShares
+ allShares` [x:xs] = append (allShares` x) (allShares` xs)
+
+instance allShares (Expr t rw)
+where
+ allShares` (ELit _) = NoShares
+ allShares` (EShared s) = Shares s NoShares
+ allShares` (a +. b) = append (allShares` a) (allShares` b)
+ allShares` (a -. b) = append (allShares` a) (allShares` b)
+ allShares` (a *. b) = append (allShares` a) (allShares` b)
+ allShares` (a /. b) = append (allShares` a) (allShares` b)
+ allShares` (EEq _ a b) = append (allShares` a) (allShares` b)
+ allShares` (ELt _ a b) = append (allShares` a) (allShares` b)
+ allShares` (EAnd _ a b) = append (allShares` a) (allShares` b)
+ allShares` (EOr _ a b) = append (allShares` a) (allShares` b)
+ allShares` (EIf b t e) = append (allShares` b) (append (allShares` t) (allShares` e))
+
+instance allShares Trigger
+where
+ allShares` (Change t) = allShares` t
+ allShares` (s ?= t) = append (allShares` s) (allShares` t)
+ allShares` (a ?& b) = append (allShares` a) (allShares` b)
+ allShares` (a ?| b) = append (allShares` a) (allShares` b)
+
+instance allShares Rule
+where
+ allShares` (s <# e) = append (allShares` s) (allShares` e)
+ allShares` (When t rs) = foldr1 append [allShares` t:map allShares` rs]
+ allShares` (t >>> rs) = foldr1 append [allShares` t:map allShares` rs]
+ allShares` (SetCursor (c,r)) = append (allShares` c) (allShares` r)
+ allShares` (Print v) = allShares` v
+
+instance allShares NamedRule
+where
+ allShares` (_ :=: r) = allShares` r
+
+instance Expr Int where litExpr i = CEInt i
+instance Expr Bool where litExpr b = CEBool b
+instance Expr Char where litExpr c = CEChar c
+
+lit :: (t -> Expr t RO)
+lit = ELit
+
+(?) infix 4 :: (Expr Bool rwa) (Expr t rwb, Expr t rwc) -> Expr t RO
+(?) b (t,e) = EIf b t e
+
+(==.) infix 4 :: (Expr t rwa) (Expr t rwb) -> Expr Bool RO | Expr, == t
+(==.) a b = EEq bm a b
+
+(<.) infix 4 :: (Expr t rwa) (Expr t rwb) -> Expr Bool RO | Expr, < t
+(<.) a b = ELt bm a b
+
+(>.) infix 4 :: (Expr t rwa) (Expr t rwb) -> Expr Bool RO | Expr, < t
+(>.) a b = ELt bm b a
+
+(&&.) infixr 3 :: (Expr Bool rwa) (Expr Bool rwb) -> Expr Bool RO
+(&&.) a b = EAnd bm a b
+
+(||.) infixr 4 :: (Expr Bool rwa) (Expr Bool rwb) -> Expr Bool RO
+(||.) a b = EOr bm a b
+
+instance :. Rule where (:.) a b = [a,b]
+instance :. [Rule] where (:.) r rs = [r:rs]
+
+instance ||| NamedRule where (|||) a b = [a,b]
+instance ||| [NamedRule] where (|||) r rs = [r:rs]
+
+instance gen (Expr t rw) CExpr | Expr t
+where
+ gen (ELit v) = litExpr v
+ gen (EShared s) = CEGlobal ("s" +++ s.sname +++ ".val")
+ gen (a +. b) = CEInfix "+" (gen a) (gen b)
+ gen (a -. b) = CEInfix "-" (gen a) (gen b)
+ gen (a *. b) = CEInfix "*" (gen a) (gen b)
+ gen (a /. b) = CEInfix "/" (gen a) (gen b)
+ gen (EEq _ a b) = CEInfix "==" (gen a) (gen b)
+ gen (ELt _ a b) = CEInfix "<" (gen a) (gen b)
+ gen (EAnd _ a b) = CEInfix "&&" (gen a) (gen b)
+ gen (EOr _ a b) = CEInfix "||" (gen a) (gen b)
+ gen (EIf b t e) = CEIf (gen b) (gen t) (gen e)
+
+instance gen Trigger CExpr
+where
+ gen (Change (EShared shr)) = CEApp (typedfun shr.stype "dirty") [CERef (CEGlobal ("s" +++ shr.sname))]
+ gen (EShared shr ?= e) = CEInfix "&&" (gen (Change (EShared shr))) (CEInfix "==" (CEGlobal ("s" +++ shr.sname +++ ".val")) (gen e))
+ gen (a ?& b) = CEInfix "&&" (gen a) (gen b)
+ gen (a ?| b) = CEInfix "||" (gen a) (gen b)
+
+instance gen Rule CBody
+where
+ gen (EShared shr <# val) = CBExpr (CEApp (typedfun shr.stype "set") [CERef (CEGlobal ("s" +++ shr.sname)), gen val])
+ gen (When b rs) = CBIf (gen b) (gen rs) CBEmpty
+ gen (t >>> rs) = CBIf (gen t) (gen rs) CBEmpty
+ gen (SetCursor (c,r)) = CBExpr (CEApp "lcd.setCursor" [gen c, gen r])
+ gen (Print e) = CBExpr (CEApp "lcd.print" [gen e])
+
+instance gen [r] CBody | gen r CBody
+where
+ gen [] = CBEmpty
+ gen rs = foldr1 CBSeq (map gen rs)
+
+instance gen NamedRule CFun
+where
+ gen (name :=: rs) =
+ { params = []
+ , body = gen rs
+ , fresh = 0
+ , type = CTVoid
+ , name = "t" +++ name
+ }
+
+instance gen (Shared t rw) CVar
+where
+ gen shr =
+ { name = "s" +++ shr.sname
+ , type = CTStruct (typedfun shr.stype "share")
+ , value = shr.srepr.map_to shr.sinit
+ }
+
+instance gen [NamedRule] String
+where
+ gen rs = foldl1 (+++) $
+ [rts] ++
+ ["\n" +++ printToString var \\ var <- sharesMap genv (allShares rs)] ++
+ ["\n" +++ printToString (genf rule) \\ rule <- rs]
+ where
+ genf :: (NamedRule -> CFun)
+ genf = gen
+
+ genv :: ((Shared t rw) -> CVar)
+ genv = gen
+
+Start :: String
+Start = gen example_score
+
+example_score :: [NamedRule]
+example_score =
+ "a" :=: b0 ?= true >>> [scorea <# scorea +. lit 1]
+ ||| "b" :=: b1 ?= true >>> [scoreb <# scoreb +. lit 1]
+ ||| "r" :=: b2 ?= true >>> [scorea <# lit 0, scoreb <# lit 0]
+ ||| "print" :=: Change scorea ?| Change scoreb >>>
+ SetCursor (lit 0, lit 0) :.
+ Print scorea :.
+ Print (lit '-') :.
+ Print scoreb
+where
+ scorea = rwInt "scorea" 0
+ scoreb = rwInt "scoreb" 0
+
+example_countdown :: [NamedRule]
+example_countdown =
+ "time" :=:
+ When (millis -. DELAY >. counter)
+ (counter <# counter +. DELAY :.
+ seconds <# seconds -. lit 1 :.
+ SetCursor (lit 0, lit 0) :.
+ Print minutes :.
+ Print (lit ':') :.
+ Print seconds)
+ :. When (seconds ==. lit 0) (seconds <# lit 60 :. minutes <# minutes -. lit 1)
+ ||| "status" :=:
+ When (seconds ==. lit 60 &&. minutes ==. lit 0) [running <# false]
+where
+ running = rwBool "running" False
+ minutes = rwUInt "minutes" 0
+ seconds = rwUInt "seconds" 0
+ counter = rwULong "counter" 1000 // If set to 0, this will overflow on first iteration
+ DELAY = lit 1000