X-Git-Url: https://git.martlubbers.net/?a=blobdiff_plain;f=mTaskInterpret.icl;h=71555a524026a4c715d18449e653caacbcea2172;hb=e37402e7672352aa3642df4c1183417a72f59641;hp=615aa10688de4f01a80b1593e40e92181f698882;hpb=ff7049a99f7fdd701d49222019df65a9aee8f05a;p=mTask.git diff --git a/mTaskInterpret.icl b/mTaskInterpret.icl index 615aa10..71555a5 100644 --- a/mTaskInterpret.icl +++ b/mTaskInterpret.icl @@ -1,6 +1,5 @@ implementation module mTaskInterpret -//import iTasks import Generics.gCons import GenEq, StdMisc, StdArray, GenBimap @@ -20,12 +19,24 @@ import Data.Monoid import Data.Functor import StdList from Data.Func import $ -from Text import class Text(concat,join,toUpperCase), instance Text String +from Text import class Text(lpad,concat,toUpperCase), instance Text String +import qualified Text +import Text.JSON + +import Control.Monad.RWST +import Control.Monad.Identity +import Control.Monad +import Control.Applicative +import Data.Functor +import Data.Either import Data.Array import qualified Data.Map as DM +import qualified Data.List as DL import Text.Encodings.Base64 +import Tasks.Examples + encode :: MTaskMSGSend -> String encode (MTTask to data) = "t" +++ tob +++ to16bit (size data) +++ data +++ "\n" where @@ -77,23 +88,6 @@ instance toString MTaskMSGRecv where toString (MTMessage m) = m toString MTEmpty = "Empty message" -bclength :: BC -> Int -bclength (BCPush _) = 3 -bclength (BCLab _) = 2 -bclength (BCSdsStore _) = 3 -bclength (BCSdsFetch _) = 3 -bclength (BCSdsPublish _) = 3 -bclength (BCAnalogRead _) = 2 -bclength (BCAnalogWrite _) = 2 -bclength (BCDigitalRead _) = 2 -bclength (BCDigitalWrite _) = 2 -bclength (BCLedOn _) = 2 -bclength (BCLedOff _) = 2 -bclength (BCJmp i) = 2 -bclength (BCJmpT i) = 2 -bclength (BCJmpF i) = 2 -bclength _ = 1 - toByteVal :: BC -> String toByteVal b = {toChar $ consIndex{|*|} b} +++ case b of @@ -106,39 +100,18 @@ toByteVal b = {toChar $ consIndex{|*|} b} +++ (BCAnalogWrite i) = {toChar i} (BCDigitalRead i) = {toChar i} (BCDigitalWrite i) = {toChar i} - (BCLedOn i) = toByteCode i - (BCLedOff i) = toByteCode i (BCJmp i) = {toChar i} (BCJmpT i) = {toChar i} (BCJmpF i) = {toChar i} _ = "" -instance Semigroup (ByteCode a p) where - mappend m n = BC \s->let (b1, (b2, t)) = runBC m <$> runBC m s in (b1 ++ b2, t) - -instance Monoid (ByteCode a p) where - mempty = retrn [] - -(<++>) infixl 2 :: (ByteCode a p) (ByteCode b q) -> ByteCode c r -(<++>) m n = BC \s->let (b1, (b2, t)) = runBC n <$> runBC m s in (b1 ++ b2, t) - -(<+->) infixr 1 -(<+->) m n :== m <++> retrn n - -runBC (BC m) = m - -retrn :: ([BC] -> ByteCode a p) -retrn = BC o tuple -fmp :: ([BC] -> [BC]) (ByteCode a p) -> ByteCode a q -fmp f b = BC \s->let (bc, s`) = runBC b s in (f bc, s`) - -instance toByteCode Bool where toByteCode b = if b "\x01" "\x00" +instance toByteCode Bool where toByteCode b = toByteCode $ if b 1 0 instance toByteCode Int where toByteCode n = {toChar $ n/256,toChar $ n rem 256} instance toByteCode Long where toByteCode (L n) = toByteCode n -instance toByteCode Char where toByteCode s = toString s -instance toByteCode String where toByteCode s = undef -instance toByteCode Button where toByteCode s = {toChar $ consIndex{|*|} s} -instance toByteCode UserLED where toByteCode s = {toChar $ consIndex{|*|} s} +instance toByteCode Char where toByteCode c = toByteCode $ toInt c +instance toByteCode String where toByteCode s = abort $ "Undef on toBytecode String" +++ s +instance toByteCode Button where toByteCode s = toByteCode $ consIndex{|*|} s +instance toByteCode UserLED where toByteCode s = toByteCode $ consIndex{|*|} s instance toByteCode MTaskInterval where toByteCode OneShot = toByteCode 0 //Intervals have the first bit 0 and the rest is a 15 bit unsigned int @@ -146,13 +119,13 @@ instance toByteCode MTaskInterval where //Intervals have the first bit 1 and the rest is a 15 bit unsigned int toByteCode (OnInterrupt i) = {toChar $ i/256 bitor 127, toChar $ i rem 256} -instance fromByteCode Bool where fromByteCode s = s == "\x01" +instance fromByteCode Bool where fromByteCode s = fromByteCode s == 1 instance fromByteCode Int where fromByteCode s = (toInt s.[0])*256 + toInt s.[1] instance fromByteCode Long where fromByteCode s = L $ fromByteCode s -instance fromByteCode Char where fromByteCode s = toChar s.[0] -instance fromByteCode String where fromByteCode s = undef -instance fromByteCode Button where fromByteCode s = fromJust $ consByName s -instance fromByteCode UserLED where fromByteCode s = fromJust $ consByName s +instance fromByteCode Char where fromByteCode s = fromInt $ fromByteCode s +instance fromByteCode String where fromByteCode s = abort $ "Undef on fromBytecode String" +++ s +instance fromByteCode Button where fromByteCode s = conses{|*|} !! fromByteCode s +instance fromByteCode UserLED where fromByteCode s = conses{|*|} !! fromByteCode s instance fromByteCode MTaskInterval where fromByteCode s @@ -169,31 +142,41 @@ instance toChar Pin where derive gPrint BC derive class gCons BC +op2 :: (ByteCode a p1) (ByteCode a p2) BC -> ByteCode b Expr +op2 (BC x) (BC y) bc = BC $ x >>| y >>| tell [bc] + +op :: (ByteCode a p) BC -> ByteCode a Expr +op (BC x) bc = BC $ x >>| tell [bc] + +tell` x = BC $ tell x + +instance zero Bool where zero = False + instance arith ByteCode where - lit x = retrn [BCPush $ toByteCode x] - (+.) x y = x <++> y <+-> [BCAdd] - (-.) x y = x <++> y <+-> [BCSub] - (*.) x y = x <++> y <+-> [BCMul] - (/.) x y = x <++> y <+-> [BCDiv] + lit x = tell` [BCPush $ toByteCode x] + (+.) x y = op2 x y BCAdd + (-.) x y = op2 x y BCSub + (*.) x y = op2 x y BCMul + (/.) x y = op2 x y BCDiv instance boolExpr ByteCode where - (&.) x y = x <++> y <+-> [BCAnd] - (|.) x y = x <++> y <+-> [BCOr] - Not x = x <+-> [BCNot] - (==.) x y = x <++> y <+-> [BCEq] - (!=.) x y = x <++> y <+-> [BCNeq] - (<.) x y = x <++> y <+-> [ BCLes] - (>.) x y = x <++> y <+-> [BCGre] - (<=.) x y = x <++> y <+-> [BCLeq] - (>=.) x y = x <++> y <+-> [BCGeq] + (&.) x y = op2 x y BCAnd + (|.) x y = op2 x y BCOr + Not x = op x BCNot + (==.) x y = op2 x y BCEq + (!=.) x y = op2 x y BCNeq + (<.) x y = op2 x y BCLes + (>.) x y = op2 x y BCGre + (<=.) x y = op2 x y BCLeq + (>=.) x y = op2 x y BCGeq instance analogIO ByteCode where - analogRead p = retrn [BCAnalogRead $ pin p] - analogWrite p b = b <+-> [BCAnalogWrite $ pin p] + analogRead p = tell` [BCAnalogRead $ pin p] + analogWrite p b = op b (BCAnalogWrite $ pin p) instance digitalIO ByteCode where - digitalRead p = retrn [BCDigitalRead $ pin p] - digitalWrite p b = b <+-> [BCDigitalWrite $ pin p] + digitalRead p = tell` [BCDigitalRead $ pin p] + digitalWrite p b = op b (BCDigitalWrite $ pin p) instance If ByteCode Stmt Stmt Stmt where If b t e = BCIfStmt b t e instance If ByteCode e Stmt Stmt where If b t e = BCIfStmt b t e @@ -201,75 +184,84 @@ instance If ByteCode Stmt e Stmt where If b t e = BCIfStmt b t e instance If ByteCode x y Stmt where If b t e = BCIfStmt b t e instance IF ByteCode where IF b t e = BCIfStmt b t e - (?) b t = BCIfStmt b t $ retrn [] -BCIfStmt b t e = - withLabel \else->withLabel \endif-> - b <++> retrn [BCJmpF else] <++> t - <++> retrn [BCJmp endif,BCLab else] <++> e <++> retrn [BCLab endif] - -instance noOp ByteCode where noOp = retrn [BCNop] + (?) b t = BCIfStmt b t $ tell` mempty +BCIfStmt (BC b) (BC t) (BC e) = BC $ + freshl >>= \else->freshl >>= \endif-> + b >>| tell [BCJmpF else] >>| + t >>| tell [BCJmp endif, BCLab else] >>| + e >>| tell [BCLab endif] -withLabel :: (Int -> (ByteCode b q)) -> ByteCode b q -withLabel f = BC \s->let [fresh:fs] = s.freshl - in runBC (f fresh) {s & freshl=fs} +freshl = get >>= \st=:{freshl=[fr:frs]}->put {st & freshl=frs} >>| pure fr +freshs = get >>= \st=:{freshs=[fr:frs]}->put {st & freshs=frs} >>| pure fr -withSDS :: (Int -> (ByteCode b q)) -> ByteCode b q -withSDS f = BC \s->let [fresh:fs] = s.freshs - in runBC (f fresh) {s & freshs=fs} +instance noOp ByteCode where noOp = tell` [BCNop] -setSDS :: Int v -> ByteCode b q | toByteCode v -setSDS ident val = BC \s->([], {s & sdss=[ - {BCShare|sdsi=ident,sdspub=False,sdsval=toByteCode val}:s.sdss]}) +unBC (BC x) = x instance sds ByteCode where - sds f = {main = withSDS \sds-> - let (v In body) = f $ retrn [BCSdsFetch sds] - in setSDS sds v <++> unMain body - } + sds f = {main = BC $ freshs + >>= \sds->pure (f (tell` [BCSdsFetch sds])) + >>= \(v In bdy)->modify (addSDS sds v) >>| unBC (unMain bdy)} +// >>= \(v In bdy)->modify (addSDS sds (toByteCode v)) >>| unBC (unMain bdy)} + where + addSDS i v s = {s & sdss=[{sdsi=i,sdspub=False,sdsval=(dynamic v),sdsbc=toByteCode v}:s.sdss]} + con f = undef - pub x = BC \s-> let ((i, bc), s`) = appFst makePub $ runBC x s - in (bc, {s` & sdss=map (publish i) s`.sdss}) + pub (BC x) = BC $ censor (\[BCSdsFetch s]->[BCSdsPublish s]) + (listen x >>= \(_, [BCSdsFetch s])->modify (publish s)) >>| tell mempty where - publish i s = if (i == s.sdsi) {s & sdspub=True} s - makePub [BCSdsFetch i:xs] = (i, [BCSdsPublish i:xs]) + publish i st = {st & sdss=[if (i == s.sdsi) {s & sdspub=True} s \\s<-st.sdss]} instance assign ByteCode where - (=.) v e = e <++> fmp makeStore v - where makeStore [BCSdsFetch i:xs] = [BCSdsStore i:xs] + (=.) (BC v) (BC e) = BC $ e >>| censor makeStore v + where + //This is going to include pins as well, as variables + makeStore [BCSdsFetch i] = [BCSdsStore i] instance seq ByteCode where (>>=.) _ _ = abort "undef on >>=." - (:.) x y = x <++> y + (:.) (BC x) (BC y) = BC $ x >>| y instance serial ByteCode where - serialAvailable = retrn [BCSerialAvail] - serialPrint s = retrn [BCSerialPrint] - serialPrintln s = retrn [BCSerialPrintln] - serialRead = retrn [BCSerialRead] - serialParseInt = retrn [BCSerialParseInt] + serialAvailable = tell` [BCSerialAvail] + serialPrint s = tell` [BCSerialPrint] + serialPrintln s = tell` [BCSerialPrintln] + serialRead = tell` [BCSerialRead] + serialParseInt = tell` [BCSerialParseInt] instance userLed ByteCode where - ledOn l = retrn [BCLedOn l] - ledOff l = retrn [BCLedOff l] + ledOn (BC l) = BC $ l >>| tell [BCLedOn] + ledOff (BC l) = BC $ l >>| tell [BCLedOff] + +func :: (a -> BC) [BC] -> [BC] | mTaskType a +func f b = abort ('Text'.join "\n" (map printToString b)) instance zero BCState where zero = {freshl=[1..], freshs=[1..], sdss=[]} toRealByteCode :: (ByteCode a b) BCState -> (String, BCState) toRealByteCode x s -# (bc, st) = runBC x s +# (s, bc) = runBC x s # (bc, gtmap) = computeGotos bc 1 -= (concat $ map (toString o toByteVal) (map (implGotos gtmap) bc), st) += (concat $ map (toString o toByteVal) (map (implGotos gtmap) bc), s) implGotos map (BCJmp t) = BCJmp $ fromJust ('DM'.get t map) implGotos map (BCJmpT t) = BCJmpT $ fromJust ('DM'.get t map) implGotos map (BCJmpF t) = BCJmpF $ fromJust ('DM'.get t map) implGotos _ i = i +import StdDebug +bclength :: BC -> Int +bclength (BCPush s) = 1 + size s +bclength (BCSdsStore _) = 3 +bclength (BCSdsFetch _) = 3 +bclength (BCSdsPublish _) = 3 +bclength x = 1 + consNum{|*|} x + computeGotos :: [BC] Int -> ([BC], 'DM'.Map Int Int) computeGotos [] _ = ([], 'DM'.newMap) computeGotos [BCLab l:xs] i = appSnd ('DM'.put l i) (computeGotos xs i) -computeGotos [x:xs] i = appFst (\bc->[x:bc]) (computeGotos xs (i+(bclength x))) +computeGotos [x:xs] i = appFst (\bc->[x:bc]) (computeGotos xs $ i + bclength x) readable :: BC -> String readable (BCPush d) = "BCPush " +++ concat [safe c\\c<-:d] @@ -277,22 +269,36 @@ readable (BCPush d) = "BCPush " +++ concat [safe c\\c<-:d] safe c = if (isControl c) ("\\d" +++ toString (toInt c)) (toString c) readable b = printToString b -toReadableByteCode :: (ByteCode a b) -> (String, BCState) -toReadableByteCode x -# (bc, st) = runBC x zero +runBC :: (ByteCode a b) -> (BCState -> (BCState, [BC])) +runBC (BC x) = execRWS x () + +toReadableByteCode :: (ByteCode a b) BCState -> (String, BCState) +toReadableByteCode x s +# (s, bc) = runBC x s +| not (trace_tn $ ('Text'.join "\n" $ lineNumbers numbers bc) +++ "\n") = undef # (bc, gtmap) = computeGotos bc 0 -= (join "\n" $ map readable (map (implGotos gtmap) bc), st) += ('Text'.join "\n" $ lineNumbers numbers (map (implGotos gtmap) bc), s) + where + numbers = map (\n->lpad (toString n) 3 ' ' +++ ". ") [0..] + lineNumbers ls [] = [] + lineNumbers [l:ls] [b:bc] = [l +++ readable b:ex ++ lineNumbers newls bc] + where + (ex, newls) = splitAt (bclength b - 1) ls toMessages :: MTaskInterval (String, BCState) -> ([MTaskMSGSend], BCState) toMessages interval (bytes, st=:{sdss}) = ( - [MTSds s.sdsi (toString s.sdsval)\\s<-sdss] ++ + [MTSds s.sdsi s.sdsbc\\s<-sdss] ++ [MTTask interval bytes], st) toSDSUpdate :: Int Int -> [MTaskMSGSend] toSDSUpdate i v = [MTUpd i (to16bit v)] -Start = toMessages (OnInterval 500) $ toRealByteCode (unMain bc) zero +//Start = toMessages (OnInterval 500) $ toRealByteCode (unMain bc) zero +Start = fst $ toReadableByteCode (unMain $ blink LED1) zero +//Start = let (bcs, st) = toReadableByteCode (unMain bc) zero +// in (bcs, st.sdss) where +// bc = {main = ledOn (lit LED1)} bc = sds \x=5 In sds \y=4 In {main = If (y ==. lit 0) (pub x) (x =. x *. y :. y =. y -. lit 1)}