git @ Cat's Eye Technologies Equipage / master impl / equipage.purs / src / Equipage.purs
master

Tree @master (Download .tar.gz)

Equipage.purs @masterraw · history · blame

module Equipage (interp, Elem) where

import Prelude (class Show, id, map, negate, otherwise, show, ($), (+), (-), (<), (<<<), (>), (>>>))
import Data.List (List, foldr, fromFoldable, reverse, (:))
import Data.String (toCharArray)

data Elem
  = Int Int
  | Fn (List Elem -> List Elem)

instance showElem :: Show Elem where
  show (Int i) = show i
  show (Fn _)  = "<fn>"

apply :: Partial => List Elem -> List Elem
apply (Fn f : s) = f s

compose :: Partial => List Elem -> List Elem
compose (Fn f1 : Fn f2 : s) = Fn (f1 <<< f2) : s

pop :: Partial => List Elem -> List Elem
pop (_ : s) = s

swap :: Partial => List Elem -> List Elem
swap (e1 : e2 : s) = e2 : e1 : s

add :: Partial => List Elem -> List Elem
add (Int a : Int b : s) = Int (a + b) : s

sub :: Partial =>  List Elem -> List Elem
sub (Int a : Int b : s) = Int (b - a) : s

sign :: Partial => List Elem -> List Elem
sign (Int a : s) = Int x : s
  where x | a > 0     =  1
          | a < 0     = -1
          | otherwise =  0

pick :: Partial => List Elem -> List Elem
pick (Int a : s) = x : s
  where x | a > 0     = pick' a s
          | a < 0     = pick' (0 - a) (reverse s)
          | otherwise = Int 0
        pick' 1 (s : _) = s
        pick' n (_ : t) = pick' (n - 1) t

push :: Elem -> List Elem -> List Elem
push = (:)

stringToCharList :: String -> List Char
stringToCharList = fromFoldable <<< toCharArray

interp :: Partial => String -> List Elem -> List Elem
interp = interp' <<< stringToCharList

interp' :: Partial => List Char -> List Elem -> List Elem
interp' t = foldr (>>>) id (map ic t)

ic :: Partial => Char -> List Elem -> List Elem
ic '!'  = apply
ic ';'  = push $ Fn apply
ic '.'  = push $ Fn compose
ic '$'  = push $ Fn pop
ic '\\' = push $ Fn swap
ic '+'  = push $ Fn add
ic '-'  = push $ Fn sub
ic '%'  = push $ Fn sign
ic '~'  = push $ Fn pick
ic '1'  = push $ Fn (push $ Int 1)
ic ' '  = id
ic '\t' = id
ic '\n' = id
ic '\r' = id