summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--assignment-13/uFPL.dcl12
-rw-r--r--assignment-13/uFPL.icl13
-rw-r--r--assignment-13/uFPL.prj.default59
-rw-r--r--assignment-13/uFPL/Sim.dcl78
-rw-r--r--assignment-13/uFPL/Sim.icl180
6 files changed, 333 insertions, 12 deletions
diff --git a/.gitignore b/.gitignore
index 5bd3ac1..92c3fe3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,7 +7,8 @@ a.out
assignment-5/skeleton5
assignment-6/multiplechoice
assignment-8/skeleton8
-assignment-8/skeleton8.prj
+assignment-13/run
+*.prj
# TeX
*-blx.bib
diff --git a/assignment-13/uFPL.dcl b/assignment-13/uFPL.dcl
index 1bd3df4..dd9c047 100644
--- a/assignment-13/uFPL.dcl
+++ b/assignment-13/uFPL.dcl
@@ -8,7 +8,7 @@ from uFPL.C import :: CType, :: CExpr, :: CBody, :: CVar, :: CFun, :: CProg
:: RO = RO
:: RW = RW
-:: Shared t w =
+:: UShared t w =
{ sname :: String
, stype :: CType
, sinit :: t
@@ -17,7 +17,7 @@ from uFPL.C import :: CType, :: CExpr, :: CBody, :: CVar, :: CFun, :: CProg
:: Shares
= NoShares
- | E.t rw: Shares (Shared t rw) Shares
+ | E.t rw: Shares (UShared t rw) Shares
removeDupShares :: Shares -> Shares
@@ -34,14 +34,14 @@ instance allShares Trigger
instance allShares Rule
instance allShares NamedRule
-class Expr t where litExpr :: t -> CExpr
+class Expr t | TC t where litExpr :: t -> CExpr
instance Expr Int
instance Expr Bool
instance Expr Char
:: Expr t rw
= ELit t
- | EShared (Shared t rw)
+ | EShared (UShared 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
@@ -75,7 +75,7 @@ lit :: (t -> Expr t RO)
| 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
+:: NamedRule = E.r: (:=:) infix 1 String r & gen r CBody & allShares r & TC r
class gen f t :: f -> t
@@ -88,7 +88,7 @@ instance ||| NamedRule
instance ||| [NamedRule]
instance gen (Expr t rw) CExpr | Expr t
-instance gen (Shared t rw) CVar
+instance gen (UShared t rw) CVar
instance gen Trigger CExpr
instance gen Rule CBody
instance gen [r] CBody | gen r CBody
diff --git a/assignment-13/uFPL.icl b/assignment-13/uFPL.icl
index 2499da5..3104595 100644
--- a/assignment-13/uFPL.icl
+++ b/assignment-13/uFPL.icl
@@ -18,6 +18,7 @@ import Data.List
import uFPL.Arduino
import uFPL.Bootstrap
import uFPL.C
+import uFPL.Sim
import uFPL.Util
typedfun :: CType String -> String
@@ -41,7 +42,7 @@ 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 :: (A.t rw: (UShared t rw) -> a) Shares -> [a]
sharesMap _ NoShares = []
sharesMap f (Shares s ss) = [f s:sharesMap f ss]
@@ -128,10 +129,11 @@ where
gen (EOr _ a b) = CEInfix "||" (gen a) (gen b)
gen (EIf b t e) = CEIf (gen b) (gen t) (gen e)
-instance gen (Shared t rw) CVar
+instance gen (UShared t rw) CVar
where
gen shr =
- { name = "s" +++ shr.sname
+ { CVar
+ | name = "s" +++ shr.sname
, type = CTStruct (typedfun shr.stype "share")
, value = CEStruct
[ ("val", shr.srepr.map_to shr.sinit)
@@ -180,7 +182,7 @@ where
genf :: (NamedRule -> CFun)
genf = gen
- genv :: ((Shared t rw) -> CVar)
+ genv :: ((UShared t rw) -> CVar)
genv = gen
instance gen NamedRule CProg
@@ -195,7 +197,8 @@ instance gen [NamedRule] CProg
where
gen rs = foldr (combinePrograms o gen) zero rs
-Start = printToString (genp example_score)
+Start w = startEngine (simulate example_countdown) w
+Start _ = printToString (genp example_score)
where
genp :: (a -> CProg) | gen a CProg
genp = gen
diff --git a/assignment-13/uFPL.prj.default b/assignment-13/uFPL.prj.default
new file mode 100644
index 0000000..4bd7872
--- /dev/null
+++ b/assignment-13/uFPL.prj.default
@@ -0,0 +1,59 @@
+Version: 1.4
+Global
+ ProjectRoot: .
+ Target: iTasks
+ Exec: {Project}/run
+ CodeGen
+ CheckStacks: False
+ CheckIndexes: True
+ Application
+ HeapSize: 167772160
+ StackSize: 1048576
+ ExtraMemory: 81920
+ IntialHeapSize: 204800
+ HeapSizeMultiplier: 4096
+ ShowExecutionTime: False
+ ShowGC: False
+ ShowStackSize: False
+ MarkingCollector: False
+ DisableRTSFlags: False
+ StandardRuntimeEnv: True
+ Profile
+ Memory: False
+ MemoryMinimumHeapSize: 0
+ Time: False
+ Stack: False
+ Dynamics: True
+ DescExL: False
+ Output
+ Output: ShowConstructors
+ Font: Monaco
+ FontSize: 9
+ WriteStdErr: False
+ Link
+ LinkMethod: Static
+ GenerateRelocations: False
+ GenerateSymbolTable: False
+ GenerateLinkMap: False
+ LinkResources: False
+ ResourceSource:
+ GenerateDLL: False
+ ExportedNames:
+ Paths
+ Path: {Project}
+ Precompile:
+ Postlink:
+MainModule
+ Name: uFPL
+ Dir: {Project}
+ Compiler
+ NeverMemoryProfile: False
+ NeverTimeProfile: False
+ StrictnessAnalysis: True
+ ListTypes: StrictExportTypes
+ ListAttributes: True
+ Warnings: True
+ Verbose: True
+ ReadableABC: False
+ ReuseUniqueNodes: True
+ Fusion: False
diff --git a/assignment-13/uFPL/Sim.dcl b/assignment-13/uFPL/Sim.dcl
new file mode 100644
index 0000000..6ee6e14
--- /dev/null
+++ b/assignment-13/uFPL/Sim.dcl
@@ -0,0 +1,78 @@
+definition module uFPL.Sim
+
+import iTasks
+
+import uFPL
+from uFPL.C import :: Signedness
+
+:: UFPLException
+ = LiftException String
+ | NoShareException ISharedRef
+ | WriteToROShare ISharedRef
+
+instance toString UFPLException
+
+class lift a :: a -> Task Dynamic
+class unlift a b :: b -> a
+
+:: ReadOrWrite = ReadOnly | ReadWrite
+
+:: ISharedInt =
+ { iisname :: String
+ , iisinit :: Int
+ , iisrw :: ReadOrWrite
+ }
+
+:: ISharedRef :== String
+
+:: IShares =
+ { ishares :: [ISharedInt]
+ }
+
+:: IExpr
+ = ILitInt Int
+ | ILitBool Bool
+ | ILitChar Char
+ | IShared ISharedRef
+ | IAdd IExpr IExpr
+ | ISub IExpr IExpr
+ | IMul IExpr IExpr
+ | IDiv IExpr IExpr
+ | IEq IExpr IExpr
+ | ILt IExpr IExpr
+ | IAnd IExpr IExpr
+ | IOr IExpr IExpr
+ | IIf IExpr IExpr IExpr
+
+:: ITrigger
+ = IChange ISharedRef
+ | IBecomes ISharedRef IExpr
+ | ITAnd ITrigger ITrigger
+ | ITOr ITrigger ITrigger
+
+:: IRule
+ = IAssign ISharedRef IExpr
+ | IWhen IExpr [IRule]
+ | ITrigger ITrigger [IRule]
+ | ISetCursor (IExpr, IExpr)
+ | IPrint IExpr
+
+:: INamedRule = Rule String [IRule]
+
+derive class iTask Signedness, CType, ReadOrWrite, ISharedInt, IShares, IExpr,
+ ITrigger, IRule, INamedRule
+
+instance lift [a] | lift a
+instance unlift [a] [b] | unlift a b
+instance lift IExpr
+instance unlift IExpr (Expr t rw) | Expr t
+instance lift ISharedInt
+instance unlift ISharedInt (UShared Int rw)
+instance lift ITrigger
+instance unlift ITrigger Trigger
+instance lift IRule
+instance unlift IRule Rule
+instance lift INamedRule
+instance unlift INamedRule NamedRule
+
+simulate :: [NamedRule] -> Task ()
diff --git a/assignment-13/uFPL/Sim.icl b/assignment-13/uFPL/Sim.icl
new file mode 100644
index 0000000..ac42046
--- /dev/null
+++ b/assignment-13/uFPL/Sim.icl
@@ -0,0 +1,180 @@
+implementation module uFPL.Sim
+
+import Data.Functor
+import Data.Maybe
+
+import iTasks
+
+import uFPL
+import uFPL.Bootstrap
+import uFPL.C
+
+derive class iTask UFPLException
+instance toString UFPLException
+where
+ toString (LiftException s) = "Lift exception: " +++ s
+ toString (NoShareException s) = "No such share: " +++ s
+ toString (WriteToROShare s) = "Write to RO share: " +++ s
+
+derive class iTask Signedness, CType, ReadOrWrite, ISharedInt, IShares, IExpr,
+ ITrigger, IRule, INamedRule
+
+ishares :: Shared IShares
+ishares = sharedStore "ishares" gDefault{|*|}
+
+getSharedInt :: ISharedRef -> Task ISharedInt
+getSharedInt n = get ishares >>= \shrs -> case [shr \\ shr <- shrs.ishares | shr.iisname == n] of
+ [] -> throw (NoShareException n)
+ [s:_] -> return s
+
+instance lift [a] | lift a
+where
+ lift xs = dynamicList <$> allTasks (map lift xs)
+ where
+ dynamicList :: [Dynamic] -> Dynamic
+ dynamicList ds = list (reverse ds) (dynamic [] :: A.a: [a])
+ where
+ list :: [Dynamic] Dynamic -> Dynamic
+ list [(d :: t):r] (l :: [t]) = list r (dynamic [d:l])
+
+instance unlift [a] [b] | unlift a b where unlift xs = map unlift xs
+
+instance lift IExpr
+where
+ lift (ILitInt i) = return (dynamic ELit i :: Expr Int RO)
+ lift (ILitBool b) = return (dynamic ELit b :: Expr Bool RO)
+ lift (ILitChar c) = return (dynamic ELit c :: Expr Char RO)
+ lift (IShared s) = getSharedInt s >>= lift >>= \s -> case s of
+ (s :: UShared Int rw) -> return (dynamic EShared s)
+ lift (IAdd a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Int rwa, b :: Expr Int rwb) -> return (dynamic a +. b :: Expr Int RO)
+ (a :: Expr Char rwa, b :: Expr Char rwb) -> return (dynamic a +. b :: Expr Char RO)
+ _ -> throw (LiftException "IAdd")
+ lift (ISub a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Int rwa, b :: Expr Int rwb) -> return (dynamic a -. b :: Expr Int RO)
+ (a :: Expr Char rwa, b :: Expr Char rwb) -> return (dynamic a -. b :: Expr Char RO)
+ _ -> throw (LiftException "ISub")
+ lift (IMul a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Int rwa, b :: Expr Int rwb) -> return (dynamic a *. b :: Expr Int RO)
+ _ -> throw (LiftException "IMul")
+ lift (IDiv a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Int rwa, b :: Expr Int rwb) -> return (dynamic a /. b :: Expr Int RO)
+ _ -> throw (LiftException "IDiv")
+ lift (IEq a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Int rwa, b :: Expr Int rwb) -> return (dynamic a ==. b :: Expr Bool RO)
+ (a :: Expr Char rwa, b :: Expr Char rwb) -> return (dynamic a ==. b :: Expr Bool RO)
+ (a :: Expr Bool rwa, b :: Expr Bool rwb) -> return (dynamic a ==. b :: Expr Bool RO)
+ _ -> throw (LiftException "IEq")
+ lift (ILt a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Int rwa, b :: Expr Int rwb) -> return (dynamic a <. b :: Expr Bool RO)
+ (a :: Expr Char rwa, b :: Expr Char rwb) -> return (dynamic a <. b :: Expr Bool RO)
+ _ -> throw (LiftException "ILt")
+ lift (IAnd a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Bool rwa, b :: Expr Bool rwb) -> return (dynamic a &&. b :: Expr Bool RO)
+ _ -> throw (LiftException "IAnd")
+ lift (IOr a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Expr Bool rwa, b :: Expr Bool rwb) -> return (dynamic a ||. b :: Expr Bool RO)
+ _ -> throw (LiftException "IOr")
+ lift (IIf b t e) = lift b >>= \b -> lift t >>= \t -> lift e >>= \e -> case (b,t,e) of
+ (b :: Expr Bool rwa, t :: Expr Int rwb, e :: Expr Int rwc) -> return (dynamic b ? (t,e) :: Expr Int RO)
+ (b :: Expr Bool rwa, t :: Expr Char rwb, e :: Expr Char rwc) -> return (dynamic b ? (t,e) :: Expr Char RO)
+ (b :: Expr Bool rwa, t :: Expr Bool rwb, e :: Expr Bool rwc) -> return (dynamic b ? (t,e) :: Expr Bool RO)
+ _ -> throw (LiftException "IIf")
+
+instance unlift IExpr (Expr t rw) | Expr t
+where
+ unlift (ELit v) = case dynamic v of
+ (i :: Int) -> ILitInt i
+ (c :: Char) -> ILitChar c
+ (b :: Bool) -> ILitBool b
+ unlift (EShared s) = IShared s.sname
+ unlift (a +. b) = IAdd (unlift a) (unlift b)
+ unlift (a -. b) = ISub (unlift a) (unlift b)
+ unlift (a *. b) = IMul (unlift a) (unlift b)
+ unlift (a /. b) = IDiv (unlift a) (unlift b)
+ unlift (EEq _ a b) = IEq (unlift a) (unlift b)
+ unlift (ELt _ a b) = ILt (unlift a) (unlift b)
+ unlift (EAnd _ a b) = IAnd (unlift a) (unlift b)
+ unlift (EOr _ a b) = IOr (unlift a) (unlift b)
+ unlift (EIf b t e) = IIf (unlift b) (unlift t) (unlift e)
+
+instance lift ISharedInt
+where
+ lift s = return case s.iisrw of
+ ReadOnly -> dynamic {sname=s.iisname, stype=CTInt Sig, sinit=s.iisinit, srepr=intmap} :: UShared Int RO
+ ReadWrite -> dynamic {sname=s.iisname, stype=CTInt Sig, sinit=s.iisinit, srepr=intmap} :: UShared Int RW
+
+// NOTE: Compiler doesn't allow instances for both RW and RO, so we assume everything is RW here...
+instance unlift ISharedInt (UShared Int rw)
+where
+ unlift s = {iisname=s.sname, iisinit=s.sinit, iisrw=ReadWrite}
+
+instance lift ITrigger
+where
+ lift (IChange s) = getSharedInt s >>= lift >>= \s -> case s of
+ (s :: UShared Int rw) -> return (dynamic Change (EShared s))
+ _ -> throw (LiftException "IChange")
+ lift (IBecomes s e) = getSharedInt s >>= lift >>= \s -> lift e >>= \e -> case (s,e) of
+ (s :: UShared Int rwa, e :: Expr Int rwb) -> return (dynamic EShared s ?= e)
+ _ -> throw (LiftException "IBecomes")
+ lift (ITAnd a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Trigger, b :: Trigger) -> return (dynamic a ?& b)
+ _ -> throw (LiftException "ITAnd")
+ lift (ITOr a b) = lift a >>= \a -> lift b >>= \b -> case (a,b) of
+ (a :: Trigger, b :: Trigger) -> return (dynamic a ?| b)
+ _ -> throw (LiftException "ITOr")
+
+instance unlift ITrigger Trigger
+where
+ unlift (Change (EShared s)) = IChange s.sname
+ unlift (EShared s ?= e) = IBecomes s.sname (unlift e)
+ unlift (a ?& b) = ITAnd (unlift a) (unlift b)
+ unlift (a ?| b) = ITOr (unlift a) (unlift b)
+
+instance lift IRule
+where
+ lift (IAssign s e) = getSharedInt s >>= lift >>= \s -> lift e >>= \e -> case (s,e) of
+ (s :: UShared Int RW, e :: Expr Int rw) -> return (dynamic EShared s <# e)
+ (s :: UShared Char RW, e :: Expr Char rw) -> return (dynamic EShared s <# e)
+ (s :: UShared Bool RW, e :: Expr Bool rw) -> return (dynamic EShared s <# e)
+ (s :: UShared t RO, _) -> throw (WriteToROShare s.sname)
+ _ -> throw (LiftException "IAssign")
+ lift (IWhen e rs) = lift e >>= \e -> lift rs >>= \rs -> case (e,rs) of
+ (e :: Expr Bool rw, rs :: [Rule]) -> return (dynamic When e rs)
+ _ -> throw (LiftException "IWhen")
+ lift (ITrigger t rs) = lift t >>= \t -> lift rs >>= \rs -> case (t,rs) of
+ (t :: Trigger, rs :: [Rule]) -> return (dynamic t >>> rs)
+ _ -> throw (LiftException "IWhen")
+ lift (ISetCursor (c,r)) = lift c >>= \c -> lift r >>= \r -> case (c,r) of
+ (c :: Expr Int rwa, r :: Expr Int rwb) -> return (dynamic SetCursor (c,r))
+ _ -> throw (LiftException "ISetCursor")
+ lift (IPrint e) = lift e >>= \e -> case e of
+ (e :: Expr Int rw) -> return (dynamic Print e)
+ (e :: Expr Char rw) -> return (dynamic Print e)
+ (e :: Expr Bool rw) -> return (dynamic Print e)
+ _ -> throw (LiftException "IPrint")
+
+instance unlift IRule Rule
+where
+ unlift (EShared s <# e) = IAssign s.sname (unlift e)
+ unlift (When e rs) = IWhen (unlift e) (unlift rs)
+ unlift (t >>> rs) = ITrigger (unlift t) (unlift rs)
+ unlift (SetCursor (c,r)) = ISetCursor (unlift c, unlift r)
+ unlift (Print e) = IPrint (unlift e)
+
+instance lift INamedRule
+where
+ lift (Rule s rs) = lift rs >>= \rs -> case rs of
+ (rs :: [Rule]) -> return (dynamic s :=: rs)
+
+instance unlift INamedRule NamedRule
+where
+ unlift (s :=: rs) = case dynamic rs of
+ (r :: Rule) -> Rule s [unlift r]
+ (rs :: [Rule]) -> Rule s (unlift rs)
+
+simulate :: [NamedRule] -> Task ()
+simulate rs = update >>= \rs -> viewInformation (Title "Your rules") [] rs $> ()
+where
+ update :: Task [INamedRule]
+ update = updateInformation (Title "Rules") [] (unlift rs)