[Haskell-cafe] Haskell implementation of ideas from StandardML as
a Metaprogramming language
Stephen Tetley
stephen.tetley at gmail.com
Thu Jan 14 14:38:20 EST 2010
Hello Kashyap
I can do MSL and Region, maybe I did the parser combinators but I
can't find them at the moment.
I tried to keep the code close to the original SML, so as Haskell code
its not pretty. Not having quasiquote was a problem.
Best wishes
Stephen
--------------------------------------------------------------------------------
-- MSL
module MSL where
type Expr = String
type Predicate = Expr
type Statement = String
type Fieldname = String
data Bitsource = Source Expr Expr
deriving Show
newbitsource a i = Source a i
initbs (Source _ i) = i ++ " = 0;"
getByte (Source a i) = a ++ "[" ++ i ++ "/8]"
getNthByte :: Bitsource -> Int -> Expr
getNthByte (Source a i) n
| n == 0 = a ++ "[" ++ i ++ "/8]"
| otherwise = a ++ "[" ++ i ++ "/8+" ++ show n ++ "]"
advanceByte (Source a i) = i ++ " = " ++ i ++ "-(" ++ i ++ "%8)+8;"
advanceNBytes (Source a i) n
| n == 0 = ""
| otherwise = i ++ " = " ++ i ++ "-(" ++ i ++ "%8)+(8*" ++ show n++");"
data Recordfield = Field Expr [Fieldname]
deriving Show
recordptr :: Expr -> Recordfield
recordptr e = Field e []
subfield :: Recordfield -> Fieldname -> Recordfield
subfield (Field e fl) f = Field e (f:fl)
deref :: Recordfield -> Expr
deref (Field e fl)
= "(*" ++e++ ")" ++ concat ( map cojoin (reverse fl) )
where
cojoin :: Fieldname -> String
cojoin s = "." ++ s
type Message = Bitsource -> Recordfield -> Statement -> Statement
infield :: Fieldname -> Message -> Message
infield f m src tgt
= m src (subfield tgt f)
c_if :: Expr -> Statement -> Statement -> Statement
c_if e s1 s2
= if e=="1" || e=="(1)"
then s1
else "if("++e++"){"
++ s1
++ "}" ++ if s2 /= "" then "else {" ++ s2 ++ "}" else ""
seqmsg :: [Message] -> Message
seqmsg (m:ml) src tgt s
= (m src tgt "error_action();") ++ (seqmsg ml src tgt s)
seqmsg [] _ _ _ = ""
asc2Int :: Int -> (Int,Int) -> Message
asc2Int w (lo,hi) src tgt s
= c_if ("inrange(" ++ (getByte src) ++ ", "
++ (ms w) ++ ", " ++ (ms lo)
++ ", " ++ (ms hi))
""
s
where
ms n = show n
alt :: [Message] -> Message
alt (m:ml) src tgt s
= m src tgt (alt ml src tgt s)
delim :: Expr -> Message
delim e src tgt s
= "if (" ++ getByte src ++ " == " ++ e ++")"
++ advanceByte src
rangex :: Int -> Int -> [Int]
rangex i j
| i > j = []
| otherwise = (i:(rangex (i+1) j))
c_and [] = ""
c_and [pred] = "(" ++ pred ++ ")"
c_and (pred1:pred2:preds) = "(" ++ pred1 ++ " && " ++ c_and (pred2:preds) ++ ")"
asc :: String -> String -> Message
asc chars value src tgt s
= c_if ""
(deref tgt ++ " == " ++ value ++ ";" )
s
skip :: Int -> Message
skip n src tgt s
= (deref tgt) ++ "= 1;"
++ (advanceNBytes src n)
--------------------------------------------------------------------------------
bs = newbitsource "A" "bit"
f = recordptr "target"
main = delim "6" bs f "abort();"
to_confidence = alt [ asc "HH" "High"
, asc "MM" "Medium"
, asc "LL" "Low"
, asc "NN" "None"
]
--------------------------------------------------------------------------------
-- Region
-- This one doesn't work properly -
-- CPoints are difficult to manipulate as strings, hence the `hasVar`
-- problems, it gives some idea of the method though.
module Region where
import Data.Char ( isAlpha )
import Data.List ( foldl' )
-- Prolog
type CExpr = String
type CPred = String
type CFloat = Float
infixr 6 ++&
(++&) :: Show a => String -> a -> String
s ++& a = s ++ show a
sqrdist _ = ""
add :: CPoint -> CPoint -> CPoint
add a b = a ++ "+" ++ b
sub :: CPoint -> CPoint -> CPoint
sub a b = a ++ "-" ++ b
hasVar :: CExpr -> Bool
hasVar = any isAlpha
cfst :: CPoint -> CExpr
cfst a | hasVar a = a ++ ".x"
| otherwise = "1.1"
csnd :: CPoint -> CExpr
csnd a | hasVar a = a ++".y"
| otherwise = "2.2"
pt :: (CFloat,CFloat) -> CPoint
pt = show
intersect :: [Region] -> Region
intersect (r:rs) = foldl' (/\) r rs
intersect [] = error $ "intersect on empty list"
-- presentation
type CPoint = CExpr
type Region = CPoint -> CPred
circle :: CFloat -> Region
circle n = \p -> "(" ++ sqrdist p ++ "<" ++& n ++ "*" ++& n ++ ")"
halfplane :: CPoint -> CPoint -> Region
halfplane a b = \p -> "(" ++ zcross (a `sub` p) (b `sub` a) ++ " > 0.0)"
where
zcross e1 e2 =
"(" ++ cfst e1 ++ "*" ++ csnd e2 ++ "-" ++ csnd e2 ++ "*" ++
cfst e1 ++ ")"
(/\) :: Region -> Region -> Region
r1 /\ r2 = \p -> "(" ++ r1 p ++ " && " ++ r2 p ++ ")"
(\/) :: Region -> Region -> Region
r1 \/ r2 = \p -> "(" ++ r1 p ++ " || " ++ r2 p ++ ")"
at :: Region -> CPoint -> Region
r `at` p0 = \p -> r (p `sub` p0)
convexPoly :: [CPoint] -> Region
convexPoly (p:ps) =
intersect (zipWith halfplane ([p] ++ ps) (ps ++ [p]))
tightZone :: CPoint -> CPred
tightZone =
(convexPoly [pt (0.0,5.0), pt (118.0,32.0),
pt (118.0,62.0), pt (0.0,25.0) ])
\/
(convexPoly [pt (118.0,32.0), pt (259.0,5.0),
pt (259.0, 25.0), pt (118.0,62.0)])
main = tightZone e1 where
e1::CExpr
e1 = "p"
More information about the Haskell-Cafe
mailing list