import Cocoa import Doubt import Prelude func readFile(path: String) -> String? { guard let data = try? NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) else { return nil } return data as String? } typealias Term = Cofree> func termWithInput(string: String) -> Term? { let document = ts_document_make() defer { ts_document_free(document) } return string.withCString { ts_document_set_language(document, ts_language_javascript()) ts_document_set_input_string(document, $0) ts_document_parse(document) let root = ts_document_root_node(document) return Cofree .ana { node in let count = ts_node_named_child_count(node) guard count > 0 else { return String.fromCString(ts_node_name(node, document)).map(Syntax.Leaf)! } return .Indexed((0..(equal: Term.equals(annotation: const(true), leaf: ==), comparable: const(true), cost: Free.sum(Patch.difference)).run(a, b) let range: Range -> Doubt.JSON = { let start = $0.startIndex let end = $0.endIndex return [ .Number(Double(start)), .Number(Double(end - start)), ] } let JSON: Doubt.JSON = [ "before": .String(aString), "after": .String(bString), "diff": diff.JSON(pure: { $0.JSON { $0.JSON(annotation: range, leaf: Doubt.JSON.String) } }, leaf: Doubt.JSON.String, annotation: { [ "before": range($0), "after": range($1), ] }), ] JSON.serialize() } }