Skip to content

Commit

Permalink
introduce List.splitr() which returns the first list in reverse order
Browse files Browse the repository at this point in the history
- optimizes code that does (l1,l2)=List.split() + listAppend(l1,l2)
  by avoiding double listReverse on first list: (l1r,l2)=List.splitr() + List.append_reverse(l1r,l2);
  • Loading branch information
hkiel committed May 17, 2016
1 parent 389ec43 commit e713fe2
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Compiler/FrontEnd/CevalFunction.mo
Expand Up @@ -2211,12 +2211,12 @@ algorithm
(cache, Values.ARRAY(valueLst = (indices as (Values.INTEGER(integer = i) :: _))), st) =
cevalExp(e, inCache, inEnv, st);
// Split the list of old values at the first slice index.
(old_values, old_values2) = List.split(old_values, i - 1);
(old_values, old_values2) = List.splitr(old_values, i - 1);
// Update the rest of the old value with assignSlice.
(cache, values2, st) =
assignSlice(values, old_values2, indices, rest_subs, i, cache, inEnv, st);
// Assemble the list of values again.
values = listAppend(old_values, values2);
values = List.append_reverse(old_values, values2);
then
(cache, Values.ARRAY(values, dims), st);

Expand Down
33 changes: 29 additions & 4 deletions Compiler/Util/List.mo
Expand Up @@ -453,8 +453,8 @@ protected
list<T> lst1, lst2;
algorithm
true := (inN > 0);
(lst1, lst2) := split(inList, inN-1);
outList := listAppend(lst1,inElement::lst2);
(lst1, lst2) := splitr(inList, inN-1);
outList := append_reverse(lst1,inElement::lst2);
end insert;

public function insertListSorted<T>
Expand Down Expand Up @@ -524,9 +524,9 @@ protected
list<T> lst1, lst2;
algorithm
true := (inN > 0);
(lst1, lst2) := split(inList, inN-1);
(lst1, lst2) := splitr(inList, inN-1);
lst2 := stripFirst(lst2);
outList := listAppend(lst1,inElement::lst2);
outList := append_reverse(lst1,inElement::lst2);
end set;

public function first<T>
Expand Down Expand Up @@ -1145,6 +1145,31 @@ algorithm
outList2 := l2;
end split;

public function splitr<T>
"Takes a list and a position, and splits the list at the position given. The first list is returned in reverse order.
Example: split({1, 2, 5, 7}, 2) => ({2, 1}, {5, 7})"
input list<T> inList;
input Integer inPosition;
output list<T> outList1;
output list<T> outList2;
protected
Integer pos;
list<T> l1 = {}, l2 = inList;
T e;
algorithm
true := inPosition >= 0;
pos := inPosition;

// Move elements from l2 to l1 until we reach the split position.
for i in 1:pos loop
e :: l2 := l2;
l1 := e :: l1;
end for;

outList1 := l1;
outList2 := l2;
end splitr;

public function splitOnTrue<T>
"Splits a list into two sublists depending on predicate function."
input list<T> inList;
Expand Down

0 comments on commit e713fe2

Please sign in to comment.