> module Edlib where > import Type_defs > import Core_datatype > infixr 9 <: > infixl 8 /// , />/ , /:>/ , /./ , /.>/, /.:>/, |||, |>|, |@|, |.| > infixl 8 ..., ./., \\\ > infixl 1 `handle`, `ihandle` >-- infixl 8 >>, >>>, *>>, *>>>, >>+, >>>+, *>>+, *>>>+, >>^, >>>^, *>>^, *>>>^ >-- type Xin = ( String , [Response] , [Int]) > type Xin = ( String , [Int] , [Int]) > type Xout = String >-- type Xout = [Request] > type Xio = ( Xin , Xout ) > type Xio_fn = Xin -> Xio > type Xst a = ( Xin , a , Xout ) > type Xst_fn a = ( Xin , a ) -> ( Xin , a , Xout ) >--partain: id x = x {- composition function to allow output fns to be written 'sequentially' -} > (\\\) :: Xio -> Xio_fn -> Xio > ( xin , xout ) \\\ g > = ( xin2 , xout ++ xout2 ) > where > ( xin2, xout2 ) = g xin > (...) :: Xio_fn -> Xio_fn -> Xin -> Xio > (...) f g xin > = f xin \\\ g composition f - output fn, g - input fn with state (st) > (./.) :: Xio_fn -> ( Xin -> Xst ( MayBe a b )) -> Xin -> Xst ( MayBe a b ) > (./.) f g xin > = ( xin2 , st, xout' ++ xout2 ) > where > ( xin', xout' ) = f xin > ( xin2, st, xout2 ) = g xin' utility to apply a list of functions to a state > app :: [ Xin -> Xio ] -> Xin -> Xio > app ( fn : fns ) = fn ... app fns > app [] = \ xin -> ( xin , [] ) > --partain: (|||) :: MayBe a b -> ( a -> MayBe c d ) -> MayBe c d > (|||) :: MayBe a b -> ( a -> MayBe c b ) -> MayBe c b > ( Ok s ) ||| f > = f s > ( Bad mesg ) ||| f = Bad mesg vanilla Maybe composed with IO fn > s |.| f > = case s of > Ok t -> f t > Bad err -> return_err err > ( Ok ( s , u )) |@| f > = f s u > ( Bad mesg ) |@| f = Bad mesg > ( Ok ( s , u )) |>| f > = case f u of > Ok t -> Ok (( s , t ) , u ) > Bad err -> Bad err > (///) :: Xst (MayBe a b) -> ( a -> Xin -> Xst (MayBe c b)) -> Xst (MayBe c b) > x@( xin , st , xout ) /// f > = sendout x x' > where > x' = case st of > Ok val -> f val xin > Bad mesg -> ( xin , Bad mesg , [] ) as above except second argument not fully evaluated > (/./) :: (Xin -> Xst (MayBe a b)) -> ( a -> Xin -> Xst (MayBe c b)) > -> Xin -> Xst (MayBe c b) > (/./) f g xin > = f xin /// g > (/>/) :: Xst (MayBe a b) -> ( Xin -> Xst (MayBe c b)) -> Xst (MayBe (a,c) b) > x1@( xin , st , xout ) />/ f > = sendout x1 x1' > where > x1' = case st of > Ok val -> ( xin2, st2', xout2 ) > where > st2' = case st2 of > Ok val2 -> Ok ( val, val2 ) > Bad mesg -> Bad mesg > Bad mesg -> ( xin, Bad mesg, [] ) > ( xin2, st2, xout2 ) = f xin > (/.>/) :: (Xin -> Xst (MayBe a b)) -> ( Xin -> Xst (MayBe c b)) > -> Xin -> Xst (MayBe (a,c) b) > (/.>/) f g xin > = f xin />/ g as above except form list as state output rather than nested two tuples (note, first read, first in list) > x1@( xin , st , xout ) /:>/ f > = sendout x1 x1' > where > x1' = case st of > Ok val -> ( xin2, st2', xout2 ) > where > st2' = case st2 of > Ok val2 -> Ok ( val : val2 ) > Bad mesg -> Bad mesg > Bad mesg -> ( xin, Bad mesg, [] ) > ( xin2, st2, xout2 ) = f xin > (/.:>/) :: (Xin -> Xst (MayBe a b)) -> ( Xin -> Xst (MayBe [a] b)) > -> Xin -> Xst (MayBe [a] b) > (/.:>/) f g xin > = f xin /:>/ g error handler > handle f handler xin > = f xin `ihandle` handler > ihandle x@( xin , st , _ ) handler > = sendout x x' > where > x' = case st of > Ok val -> ( xin, Ok val, [] ) > Bad mesg -> handler mesg xin push non-MayBe Xio fn into valid MayBe result with unused non-xio result > mk_ok x_fn arg > = Ok ( x_fn arg ) split a list on a given element > split :: ( Eq a ) => a -> [a] -> [[a]] > split c ( a : x ) > | a == c = [] : split c x > | a /= c = case split c x of > b : y -> ( a : b ) : y > [] -> [[a]] > split _ [] = [] append a character to the end of a list > (<:) :: [a] -> a -> [a] > l <: c = l ++ [c] > sendout ( _, _, xout ) x > = ( xin, st, xout ++ xout2 ) > where > ( xin, st, xout2 ) = x > return_val st xin = ( xin , st , [] ) > return_err st xin = ( xin, Bad st , [] ) > reTurn st xin = ( xin, Ok st, [] ) > genuid ( ins , rsps , ( gno : gnoL ) ) > = ( ( ins , rsps , gnoL ) , Ok ( show gno ) , [] ) parsing functions > {- > ( f >> g ) > = next_tk f /./ ( next_tk . g ) > ( f >>> g) > = next_tk f /:>/ next_tk g > ( f *>> g ) > = f >> ( g . discard_tk ) > ( f *>>> g) > = f >>> ( g . discard_tk ) > ( f >>+ g ) > = ( \ tk -> f tk /./ pst_extend ) >> g > ( f >>>+ g ) > = ( \ tk -> f tk /./ pst_extend ) >>> g > ( f *>>+ g ) > = ( \ tk -> f tk /./ pst_extend ) *>> g > ( f *>>>+ g ) > = ( \ tk -> f tk /./ pst_extend ) *>>> g > ( f >>^ g ) > = f >> ( g . pst_retract ) > ( f >>>^ g ) > = f >>> ( g . pst_retract ) > ( f *>>^ g ) > = f *>> ( g . pst_retract ) > ( f *>>>^ g ) > = f *>>> ( g . pst_retract ) > next_tk f ( tk : tkL, pst, xin ) > = f tk ( tkL, pst, xin ) > next_tk _ st@( [] , _ , _ ) > = return_err "Unexpected end of input" st > discard_tk ( _ : tkL , pst , xin ) > = ( tkL , pst , xin ) > discard_tk st@( [] , _ , _ ) = st > pst_retract ( tkL , (tgL, Extend _ isg _ ), xin ) > = ( tkL, (tgL, isg), xin ) > pst_retract _ = error "pst_retract on empty sg -- impossible" > pst_extend resL st > = pst_extend' resL st ./. > return resL > pst_extend' ( Opnd ( Idec idc ) : _ ) ( tkL, ( tgL, isg ), xin ) > = ( tkL, ( tgL, Extend idc isg [] ), xin ) > pst_extend' ( _ : resL ) > = pst_extend' resL > pst_extend' [] > = return_err "No dc with which to extend sg" > -}