Verified Commit 68d5fba0 authored by Camil Staps's avatar Camil Staps 🚀

Add WIP gDiff

parent 74ba164b
Pipeline #9515 passed with stage
in 3 minutes and 15 seconds
definition module Data.Generics.GenDiff
import StdGeneric
* The difference between two values.
:: Diff =
{ status :: !DiffStatus //* Whether this node is common, added or removed.
, value :: !String //* A String representation of the value.
, children :: ![Diff] //* Diffs on the childrens of this node.
:: DiffStatus
= Common
| Added
| Removed
* Compute the {{`Diff`}} between two values.
generic gDiff a :: a a -> [Diff]
derive gDiff Int, UNIT, PAIR, EITHER, OBJECT, CONS of d
derive gDiff []
* A String representation of a {{`Diff`}} using ANSI escape codes.
diffToConsole :: ([Diff] -> String)
implementation module Data.Generics.GenDiff
import StdBool
from StdFunc import o
import StdGeneric
import StdInt
import StdList
import StdString
import Data.List
import Data.Maybe
from Text import class Text(concat), instance Text String
instance zero Diff where zero = {status=Common, value="", children=[]}
setStatus :: DiffStatus Diff -> Diff
setStatus s d = {d & status=s, children=map (setStatus s) d.children}
generic gDiff a :: a a -> [Diff]
gDiff{|Int|} x y
| x == y = [{status=Common, value=toString x, children=[]}]
| otherwise = [{status=Removed, value=toString x, children=[]}, {status=Added, value=toString y, children=[]}]
gDiff{|UNIT|} UNIT UNIT = []
gDiff{|PAIR|} fx fy (PAIR x1 y1) (PAIR x2 y2) = fx x1 x2 ++ fy y1 y2
gDiff{|OBJECT|} fx (OBJECT x) (OBJECT y) = fx x y
gDiff{|CONS of d|} fx (CONS x) (CONS y) = [{status=Common, value=d.gcd_name, children=fx x y}]
gDiff{|EITHER|} fl fr (LEFT x) (LEFT y) = fl x y
gDiff{|EITHER|} fl fr (RIGHT x) (RIGHT y) = fr x y
gDiff{|EITHER|} fl fr (LEFT x) (RIGHT y) = map (setStatus Removed) (fl x x) ++ map (setStatus Added) (fr y y)
gDiff{|EITHER|} fl fr (RIGHT x) (LEFT y) = map (setStatus Removed) (fr x x) ++ map (setStatus Added) (fl y y)
derive gDiff []
diffToConsole :: ([Diff] -> String)
diffToConsole = concat o intersperse " " o map (display False)
display :: Bool Diff -> String
display p d =
color +++
if p` "(" "" +++
d.value +++
concat (map ((+++) " " o display True) d.children) +++
if p` ")" "" +++
color = case d.status of
Common -> "\033[0m"
Added -> "\033[0;32m"
Removed -> "\033[0;31m"
p` = p && not (isEmpty d.children)
......@@ -43,6 +43,7 @@ import qualified Data.Generics._Array
import qualified Data.Generics.GenBimap
import qualified Data.Generics.GenCompress
import qualified Data.Generics.GenDefault
import qualified Data.Generics.GenDiff
import qualified Data.Generics.GenEq
import qualified Data.Generics.GenFMap
import qualified Data.Generics.GenFDomain
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment