Skip to content

Commit b427cc6

Browse files
author
Dimitri Scheftelowitsch
committed
generics for optimizing brainfuck dialects
1 parent 66f78ac commit b427cc6

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

GenericSteps.hs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import Data.List
2+
3+
data Command = Nop | Loop [(Int, Command)]
4+
5+
isLoop :: Command -> Bool
6+
isLoop (Loop _) = True
7+
isLoop _ = False
8+
9+
type Program = ([(Int, Structure)], [(Int, Command)])
10+
11+
data Structure = BoundedTape | Register | InfBoundedTapes | Tape
12+
deriving (Ord, Enum, Eq)
13+
14+
reduce :: Structure -> [Structure]
15+
reduce Register = [BoundedTape]
16+
reduce InfBoundedTapes = [BoundedTape, BoundedTape, BoundedTape, BoundedTape, Register]
17+
reduce Tape = [InfBoundedTapes]
18+
19+
freshTapes :: Program -> Int -> [Structure] -> (Program, [Int])
20+
freshTapes p _ [] = (p, [])
21+
freshTapes (structs, cmds) oldIdx (s:ss) = (p, oldIdx:is)
22+
where (p, is) = freshTapes (structs', cmds) idx ss
23+
structIndexes = sort $ (map fst structs)
24+
structs' = (oldIdx, s) : (case oldIdx `elem` structIndexes of
25+
True -> filter ( (/= oldIdx) . fst ) structs
26+
False -> structs )
27+
idx = head $ [1..] \\ structIndexes
28+
29+
compileSingle :: Structure -> Command -> [Int] -> [(Int, Command)]
30+
compileSingle = undefined -- TODO: Specify
31+
32+
mapSingle :: Structure -> Int -> Program -> Program
33+
mapSingle struct idx p@(structs, cmds) = (structs', cmds')
34+
where newStructs = reduce struct
35+
((structs', _), idxs) = freshTapes p idx newStructs
36+
cmds' = concat $ map (\(i, c) ->
37+
case i == idx of
38+
True -> compileSingle struct c idxs
39+
False -> [(i, c)] ) cmds
40+
41+
reorderStep :: Program -> Program
42+
reorderStep (structs, cmds) = (structs, untangledInit ++ ( case restCommands of
43+
[] -> []
44+
((i, Loop l):rs) -> (i, Loop (snd $ reorderStep (structs, l))) : (snd $ reorderStep (structs, rs))
45+
_ -> [] ) )
46+
where initCommands = takeWhile (not . isLoop . snd) cmds
47+
restCommands = dropWhile (not . isLoop . snd) cmds
48+
struct idx = snd $ head $ filter ( (==idx) . fst) structs
49+
reorderedInit = sortBy (\ (ix, cmd) (ix', cmd') ->
50+
case (compare (struct ix) (struct ix'), compare ix ix') of
51+
(GT, _) -> LT
52+
(LT, _) -> GT
53+
(EQ, x) -> x) initCommands
54+
zippedInit = map ( \(i,c) -> (i, (struct i), c) ) reorderedInit
55+
partitionedInit = partitioned' [] zippedInit
56+
partitioned' acc [] = [acc]
57+
partitioned' [] (x:xs) = partitioned' [x] xs
58+
partitioned' (y@(_, s, _):ys) (x@(_, s', _):xs) = case s == s' of
59+
True -> partitioned' (y:ys ++ [x]) xs
60+
False -> (y:ys) : partitioned' [x] xs
61+
optimizedInit = concat $ map optimize partitionedInit
62+
untangledInit = map ( \(i, _, c) -> (i, c) ) optimizedInit
63+
64+
compileStep :: Program -> Program
65+
compileStep p@(structs, cmds) = case maxLevelStructs of
66+
(x:xs) -> mapSingle (snd x) (fst x) p
67+
[] -> p
68+
where maxLevelStructs = filter ( (==maxLevel) . snd ) structs
69+
maxLevelCommands = filter ( (flip elem) (map fst maxLevelStructs) . fst ) $ cmds
70+
maxLevel = maximum $ map snd structs
71+
struct idx = snd $ head $ filter ( (==idx) . fst) structs
72+
-- computedInit = map (\(idx, cmd) -> (idx, struct idx, cmd) ) initCommands
73+
74+
75+
optimize :: [(Int, Structure, Command)] -> [(Int, Structure, Command)]
76+
optimize = id

0 commit comments

Comments
 (0)