git @ Cat's Eye Technologies Burro / master src / Language / Kondey / Compiler.hs
master

Tree @master (Download .tar.gz)

Compiler.hs @masterraw · history · blame

-- Copyright (c) 2025, Chris Pressey, Cat's Eye Technologies.
-- This file is distributed under a 2-clause BSD license, see LICENSES/ dir.
-- SPDX-License-Identifier: LicenseRef-BSD-2-Clause-X-Burro

module Language.Kondey.Compiler where

import qualified Language.Kondey.Definition as Kondey
import Language.Kondey.Definition (Kondey)
import Language.Burro.Definition


compile :: String -> Burro
compile kondeyText = genBurro $ Kondey.parse kondeyText

genBurro :: Kondey -> Burro
genBurro Kondey.Null = Null
genBurro Kondey.ToggleHalt = ToggleHalt
genBurro Kondey.Inc = Inc
genBurro Kondey.Dec = Dec
genBurro Kondey.GoLeft = GoLeft
genBurro Kondey.GoRight = GoRight
genBurro (Kondey.Test t f) = Test (genBurro t) (genBurro f)
genBurro (Kondey.Seq k1 k2) = Seq (genBurro k1) (genBurro k2)
genBurro (Kondey.Cond ks) = genCond ks

genCond :: [Kondey] -> Burro
genCond (kbranch:kbranches) =
    let
        counter = 0
        fore = Seq (makeBranch counter (genBurro kbranch)) (Test Null Null)
        rest = genCondRest kbranches kbranch (counter + 1)
    in
        Seq fore rest

genCondRest :: [Kondey] -> Kondey -> Int -> Burro
genCondRest [] _prev _counter = Null
genCondRest (kbranch:kbranches) prev counter =
    let
        b = genBurro kbranch
        invB = inverse (genBurro prev)
        branch = makeBranch counter (catBurros invB b)
        coda = repl (counter * 2) Dec (Test Null Null)
        fore = repl (counter * 2) Dec (Seq branch coda)
        rest = genCondRest kbranches kbranch (counter + 1)
    in
        Seq fore rest

makeBranch :: Int -> Burro -> Burro
makeBranch counter b =
    let
        -- We construct a Test where the "then" side is b, with
        -- counter <'s added in front, and counter+1 >'s added behind.
        thenSide = repl counter GoLeft $ Seq b $ repl counter GoRight GoRight
        elseSide = GoRight
    in
        Test thenSide elseSide

catBurros :: Burro -> Burro -> Burro
catBurros b1 b2 =
    Seq b1 b2

repl :: Int -> Burro -> Burro -> Burro
repl 0 _head tail = tail
repl n head tail = Seq head (repl (n-1) head tail)