Adapt genCond to convert Kondey to Burro.
Chris Pressey
6 months ago
460 | 460 | -> Functionality "Compile Kondey Program" is implemented by |
461 | 461 | -> shell command "bin/burro compile-kondey %(test-body-file)" |
462 | 462 | |
463 | A Kondey program (for now) consists of a sequence of Burro program fragments, | |
464 | one on each line. It generates a conditional structure following this pattern: | |
463 | Kondey is a proper superset of Burro. Every Burro program is a Kondey program, but not | |
464 | vice versa. | |
465 | ||
466 | Kondey adds a conditional structure to Burro, which looks like this: | |
467 | ||
468 | {3.../.../...} | |
469 | ||
470 | where each `...` is a Kondey program. (FIXME the hardcoded 3 to make 3 branches is an | |
471 | awful hack and will be replaced by it supporting an arbitrary number of branches.) | |
472 | This form maps to a Burro conditional structure following this pattern: | |
465 | 473 | |
466 | 474 | * if the current cell is greater than 0, then execute the 1st fragment |
467 | 475 | * if the current cell is greater than 2, then undo the 1st fragment and execute the 2nd fragment |
468 | 476 | * if the current cell is greater than 4, then undo the 2nd fragment and execute the 3rd fragment |
469 | 477 | |
470 | etc. | |
471 | ||
472 | 478 | So given these three lines |
473 | 479 | |
474 | +++++++++ | |
475 | +++++++++++++ | |
476 | +++++++ | |
477 | ||
478 | we will obtain the conditional structure shown in the "Notes" section above. (It omits | |
480 | {3+++++++++/+++++++++++++/+++++++} | |
481 | ||
482 | we will obtain the conditional structure shown in the "Notes" section above (omitting | |
479 | 483 | the prelude where we set up "5" as the value to be tested, and the postlude where we |
480 | tear down "5" again.) | |
481 | ||
482 | +++++++++ | |
483 | +++++++++++++ | |
484 | +++++++ | |
484 | tear down "5" again). | |
485 | ||
486 | {3+++++++++/+++++++++++++/+++++++} | |
485 | 487 | ===> (+++++++++>/>)(/)--(<---------+++++++++++++>>/>)--(/)----(<<-------------+++++++>>>/>)----(/) |
4 | 4 | module Language.Kondey.Compiler where |
5 | 5 | |
6 | 6 | import qualified Language.Kondey.Definition as Kondey |
7 | import Language.Kondey.Definition (Kondey) | |
7 | 8 | import Language.Burro.Definition |
8 | 9 | |
9 | 10 | |
10 | 11 | compile :: String -> Burro |
11 | compile kondeyText = | |
12 | let | |
13 | kondey = Kondey.parse kondeyText | |
14 | in | |
15 | -- genBurro kondey | |
16 | genCond $ map (parse) (lines kondeyText) | |
12 | compile kondeyText = genBurro $ Kondey.parse kondeyText | |
17 | 13 | |
18 | genBurro :: Kondey.Kondey -> Burro | |
14 | genBurro :: Kondey -> Burro | |
19 | 15 | genBurro Kondey.Null = Null |
20 | 16 | genBurro Kondey.ToggleHalt = ToggleHalt |
21 | 17 | genBurro Kondey.Inc = Inc |
24 | 20 | genBurro Kondey.GoRight = GoRight |
25 | 21 | genBurro (Kondey.Test t f) = Test (genBurro t) (genBurro f) |
26 | 22 | genBurro (Kondey.Seq k1 k2) = Seq (genBurro k1) (genBurro k2) |
27 | genBurro (Kondey.Cond ks) = error "need to refactor genCond" | |
23 | genBurro (Kondey.Cond ks) = genCond ks | |
28 | 24 | |
29 | genCond :: [Burro] -> Burro | |
30 | genCond (b:bs) = | |
25 | genCond :: [Kondey] -> Burro | |
26 | genCond (kbranch:kbranches) = | |
31 | 27 | let |
32 | 28 | counter = 0 |
33 | fore = Seq (makeBranch counter b) (Test Null Null) | |
34 | rest = genCondRest bs b (counter + 1) | |
29 | fore = Seq (makeBranch counter (genBurro kbranch)) (Test Null Null) | |
30 | rest = genCondRest kbranches kbranch (counter + 1) | |
35 | 31 | in |
36 | 32 | Seq fore rest |
37 | 33 | |
38 | genCondRest :: [Burro] -> Burro -> Int -> Burro | |
34 | genCondRest :: [Kondey] -> Kondey -> Int -> Burro | |
39 | 35 | genCondRest [] _prev _counter = Null |
40 | genCondRest (b:bs) prev counter = | |
36 | genCondRest (kbranch:kbranches) prev counter = | |
41 | 37 | let |
42 | invB = inverse prev | |
38 | b = genBurro kbranch | |
39 | invB = inverse (genBurro prev) | |
43 | 40 | branch = makeBranch counter (catBurros invB b) |
44 | 41 | coda = repl (counter * 2) Dec (Test Null Null) |
45 | 42 | fore = repl (counter * 2) Dec (Seq branch coda) |
46 | rest = genCondRest bs b (counter + 1) | |
43 | rest = genCondRest kbranches kbranch (counter + 1) | |
47 | 44 | in |
48 | 45 | Seq fore rest |
49 | 46 |
36 | 36 | parseProgram rest (Seq acc GoRight) |
37 | 37 | parseProgram ('!':rest) acc = |
38 | 38 | parseProgram rest (Seq acc ToggleHalt) |
39 | ||
39 | 40 | parseProgram ('(':rest) acc = |
40 | 41 | let |
41 | 42 | (rest', thenprog) = parseProgram rest Null |
47 | 48 | (rest, acc) |
48 | 49 | parseProgram (')':rest) acc = |
49 | 50 | (rest, acc) |
50 | --TODO: parse Cond structure | |
51 | ||
52 | -- FIXME: an awful hack | |
53 | parseProgram ('{':'3':rest) acc = | |
54 | let | |
55 | (rest', prog1) = parseProgram rest Null | |
56 | (rest'', prog2) = parseProgram rest' Null | |
57 | (rest''', prog3) = parseProgram rest'' Null | |
58 | test = Cond [prog1, prog2, prog3] | |
59 | in | |
60 | parseProgram rest''' (Seq acc test) | |
61 | parseProgram ('}':rest) acc = | |
62 | (rest, acc) | |
63 | ||
51 | 64 | parseProgram (_:rest) acc = |
52 | 65 | parseProgram rest acc |
53 | 66 |