git @ Cat's Eye Technologies Carriage / master src / Language / Carriage / Evaluator.hs
master

Tree @master (Download .tar.gz)

Evaluator.hs @masterraw · history · blame

-- SPDX-FileCopyrightText: Chris Pressey, the original author of this work, has dedicated it to the public domain.
-- For more information, please refer to <https://unlicense.org/>
-- SPDX-License-Identifier: Unlicense

module Language.Carriage.Evaluator where

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 "\n" = 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)