Created
January 21, 2022 16:32
-
-
Save hackwaly/033c295764153519fcf3fcf69830f1c9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by ReScript, PLEASE EDIT WITH CARE | |
import * as Caml_array from "rescript/lib/es6/caml_array.js"; | |
function cons(_record, _map) { | |
while(true) { | |
var map = _map; | |
var record = _record; | |
if (!map) { | |
return { | |
hd: record, | |
tl: /* [] */0 | |
}; | |
} | |
var right = map.hd; | |
if (record.op !== right.op) { | |
return { | |
hd: record, | |
tl: map | |
}; | |
} | |
_map = map.tl; | |
_record = { | |
op: record.op, | |
length: record.length + right.length | 0 | |
}; | |
continue ; | |
}; | |
} | |
function fromArray(records) { | |
var _result = /* [] */0; | |
var _index = records.length - 1 | 0; | |
while(true) { | |
var index = _index; | |
var result = _result; | |
if (index === -1) { | |
return result; | |
} | |
_index = index - 1 | 0; | |
_result = cons(Caml_array.get(records, index), result); | |
continue ; | |
}; | |
} | |
function compose(_left, _right) { | |
while(true) { | |
var right = _right; | |
var left = _left; | |
if (!right) { | |
return left; | |
} | |
if (!left) { | |
return right; | |
} | |
var record = right.hd; | |
if (record.op === "insert") { | |
return cons(record, compose(left, right.tl)); | |
} | |
var record$1 = left.hd; | |
if (record$1.op === "delete") { | |
return cons(record$1, compose(left.tl, right)); | |
} | |
var rightRecord = right.hd; | |
var left$1 = left.tl; | |
var left$2 = record$1.length > rightRecord.length ? cons({ | |
op: record$1.op, | |
length: record$1.length - rightRecord.length | 0 | |
}, left$1) : left$1; | |
var right$1 = rightRecord.length > record$1.length ? cons({ | |
op: rightRecord.op, | |
length: rightRecord.length - record$1.length | 0 | |
}, left$2) : right.tl; | |
if (rightRecord.op === "retain") { | |
return cons({ | |
op: record$1.op, | |
length: record$1.length < rightRecord.length ? record$1.length : rightRecord.length | |
}, compose(left$2, right$1)); | |
} | |
_right = right$1; | |
_left = left$2; | |
continue ; | |
}; | |
} | |
function mapOffset(_map, _offset, preferRight) { | |
while(true) { | |
var offset = _offset; | |
var map = _map; | |
if (!map) { | |
return offset; | |
} | |
var match = map.hd; | |
var match$1 = match.op; | |
if (match$1 === "retain") { | |
var length = match.length; | |
if (offset < length) { | |
return offset; | |
} else { | |
return length + mapOffset(map.tl, offset - length | 0, preferRight) | 0; | |
} | |
} | |
if (match$1 === "insert") { | |
if (offset === 0 && !preferRight) { | |
return 0; | |
} else { | |
return match.length + mapOffset(map.tl, offset, preferRight) | 0; | |
} | |
} | |
var length$1 = match.length; | |
if (offset < length$1) { | |
return 0; | |
} | |
_offset = offset - length$1 | 0; | |
_map = map.tl; | |
continue ; | |
}; | |
} | |
export { | |
fromArray , | |
compose , | |
mapOffset , | |
} | |
/* No side effect */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type changeRecord = { | |
op: [#insert | #delete | #retain], | |
length: int, | |
} | |
type changeMap = list<changeRecord> | |
let rec cons = (. record, map) => { | |
switch (record, map) { | |
| (record, list{}) => list{record} | |
| (left, list{right, ...map}) if left.op == right.op => | |
cons(. {...left, length: left.length + right.length}, map) | |
| _ => list{record, ...map} | |
} | |
} | |
let fromArray = (. records: array<changeRecord>): changeMap => { | |
let rec aux = (. result, records, index) => { | |
if index == -1 { | |
result | |
} else { | |
aux(. cons(. records[index], result), records, index - 1) | |
} | |
} | |
aux(. list{}, records, Array.length(records) - 1) | |
} | |
let rec compose = (. left: changeMap, right: changeMap): changeMap => { | |
switch (left, right) { | |
| (left, list{}) => left | |
| (list{}, right) => right | |
| (left, list{{op: #insert} as record, ...right}) => cons(. record, compose(. left, right)) | |
| (list{{op: #delete} as record, ...left}, right) => cons(. record, compose(. left, right)) | |
| (list{leftRecord, ...left}, list{rightRecord, ...right}) => | |
let left = if leftRecord.length > rightRecord.length { | |
cons(. {...leftRecord, length: leftRecord.length - rightRecord.length}, left) | |
} else { | |
left | |
} | |
let right = if rightRecord.length > leftRecord.length { | |
cons(. {...rightRecord, length: rightRecord.length - leftRecord.length}, left) | |
} else { | |
right | |
} | |
if rightRecord.op == #retain { | |
cons(. | |
{...leftRecord, length: min(leftRecord.length, rightRecord.length)}, | |
compose(. left, right), | |
) | |
} else { | |
compose(. left, right) | |
} | |
} | |
} | |
let rec mapOffset = (. map: changeMap, offset: int, preferRight: bool) => { | |
switch map { | |
| list{} => offset | |
| list{{op: #insert, length}, ...map} => | |
if offset == 0 && !preferRight { | |
0 | |
} else { | |
length + mapOffset(. map, offset, preferRight) | |
} | |
| list{{op: #delete, length}, ...map} => | |
if offset < length { | |
0 | |
} else { | |
mapOffset(. map, offset - length, preferRight) | |
} | |
| list{{op: #retain, length}, ...map} => | |
if offset < length { | |
offset | |
} else { | |
length + mapOffset(. map, offset - length, preferRight) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type changeRecord = { | |
op: [#insert | #delete | #retain], | |
length: int, | |
} | |
type changeMap | |
let fromArray: (. array<changeRecord>) => changeMap | |
let compose: (. changeMap, changeMap) => changeMap | |
let mapOffset: (. changeMap, int, bool) => int |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment