We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Tandem/Tandem.hs

From Esolang
Jump to navigation Jump to search
← Back to Tandem

Here is an skeleton of an interpreter for Tandem, written in Haskell. It is "strictly deterministic", does not implement parsing, I/O, or other niceties, and reflects the new, post-June 25th definition of &. (It is however not well tested.)

module Tandem where

import qualified Data.Map as Map

type Label = String

data Rule = Zero
          | One
          | RewExact Label String String
          | RewReplace Label String String
          | RewFront Label String String
          | Disj Rule Rule
          | Conj Rule Rule
          | Many Rule

type Collection = Map.Map Label String

get l c = Map.findWithDefault "" l c
put l b c = Map.insert l b c

startsWith s "" = True
startsWith "" s = False
startsWith (c1:s1) (c2:s2) = c1 == c2 && startsWith s1 s2

stripFront "" s = s
stripFront s "" = ""
stripFront (c1:s1) (c2:s2) = stripFront s1 s2

rewrite :: Rule -> Collection -> Maybe Collection

rewrite Zero c = Nothing

rewrite One c = Just c

rewrite (RewExact l a b) c =
    if (get l c) == a then Just (put l b c) else Nothing

rewrite (RewReplace l a b) c =
    if startsWith (get l c) a then Just (put l b c) else Nothing

rewrite (RewFront l a b) c =
    if startsWith (get l c) a then Just (put l (b ++ (stripFront a $ get l c)) c) else Nothing

rewrite (Disj r1 r2) c =
    case (rewrite r1 c, rewrite r2 c) of
        (Nothing, Nothing) -> Nothing
        (Just c1, Nothing) -> Just c1
        (Nothing, Just c2) -> Just c2
        (Just c1, Just c2) -> if c1 == c2 then (Just c1) else error "choice of more than one redex"

rewrite (Conj r1 r2) c =
    case (rewrite r1 c) of
        Nothing -> Nothing
        Just c1 -> rewrite r2 c1

rewrite (Many r) c =
    case (rewrite r c) of
        Nothing -> Just c
        (Just c') -> rewrite (Many r) c'