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.

Carriage/Carriage.hs

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

Quick and dirty implementation of Carriage in Haskell. Program might not explode under every condition it is supposed to explode (but please do consider every error to be an explosion, not just BOOM). Runs the two examples given in the article.

 explode = error "BOOM"
 
 data Elem = Int Integer
           | Fn ([Elem] -> [Elem])
           | Sym Char
 instance Show Elem where
     show (Int i) = show i
     show (Fn _)  = "<fn>"
     show (Sym c) = show c
  
 pop (e:s) = (e, s)
 push s e = (e:s)
 
 pick 0 ((Sym _):_) = explode
 pick 0 (e:_) = e
 pick n (_:s) = pick (n-1) s
 
 slice _ 0 _ = []
 slice p k s = slice' p (reverse s)
     where
         slice' 0 s = take (fromIntegral k) s
         slice' n (_:s) = slice' (n-1) s
 
 ci " " = id
 ci "1" = \s -> push s $ Int 1
 ci "$" = snd . pop
 ci "#" = \s -> push s $ Int $ fromIntegral $ length s
 ci "~" = (\s ->
     let
         (Int a, s') = pop(s)
     in
         push s' $ pick a s')
 ci "\\" = (\s ->
     let
         (a, s') = pop(s)
         (b, s'') = pop(s')
     in
         push (push s'' a) b)
 ci "+" = (\s ->
     let
         (Int a, s') = pop(s)
         (Int b, s'') = pop(s')
     in
         push s'' $ Int (a + b))
 ci "-" = (\s ->
     let
         (Int a, s') = pop(s)
         (Int b, s'') = pop(s')
     in
         push s'' $ Int (b - a))
 ci "@" = (\s ->
     let
         (Int k, s') = pop(s)
         (Int p, s'') = pop(s')
         fn = ci $ map (\(Sym c) -> c) $ slice p k s''
     in
         push s'' (Fn fn))
 ci "!" = \s -> let (Fn f, s') = pop(s) in f s'
 ci [] = id
 ci [_] = explode
 ci (sym:rest) = \x -> (ci rest) ((ci [sym]) x)
 
 di = reverse . map (\x -> Sym x) . filter (\x -> x /= ' ')
 
 run prog = (ci prog) (di prog)
 

See also