Skip to content

Commit

Permalink
Added slice to Selene
Browse files Browse the repository at this point in the history
  • Loading branch information
Vexatos committed Aug 27, 2015
1 parent af06a99 commit 21f4934
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
6 changes: 4 additions & 2 deletions selene/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ These functions will not work directly called on a string, i.e. `string.drop("He
- `string.take(s:string, n:number):string` This function will take the first `n` characters from the string and return the new string.
- `string.takeright(s:string, n:number):string` This function will take the last `n` characters from the string and return the new string.
- `string.takewhile(s:string, f:function):string` This function will iterate through the characters of the string and add the characters to the returned string as long as `f` returns `true` on the currently checked character (or on the index and the character).
- `string.slice(s:string, start:number or nil, stop:number or nil [, step:number or nil]):list` This function will slice a specific range of characters out of the string and return it, starting at index `start` and stopping at `stop` with a step size of `step`. `step` must not be 0 but can be negative. `start` will default to `1` if it is `nil` or `0`, `stop` will default to the length of the string. Negative values for `start` or `stop` are interpreted as indexing backwards, from the end of the string.
- `string.fold(s:string, m:anything, f:function):anything` This works exactly like `string.foldleft`.
- `string.foldleft(s:string, m:anything, f:function):anything` This function calls `f` once for every character in the string, with `m` and that character as parameters. The value which `f` returns will then be assigned to `m` for the next iteration. Returns the final value of `m`.
- `string.foldright(s:string, m:anything, f:function):anything` This works exactly like `string.foldleft`, just that it starts iterating at the end of the string.
Expand Down Expand Up @@ -167,10 +168,11 @@ These are the functions you can call on wrapped tables. `$()` represents a wrapp
- `$():shallowcopy()` This works exactly like `table.shallowcopy`.
- `$l():drop(n:number):list` This function will remove the first `n` entries from the list and return a list with the dropped entries.
- `$l():dropright(n:number):list` This function will remove the last `n` entries from the list and return a list with the dropped entries.
- `$l():dropwhile(function):list` This works exactly like `string.dropwhile`, just that it will iterate through each key/value pair in the table and will return a list with the dropped entries.
- `$l():dropwhile(f:function):list` This works exactly like `string.dropwhile`, just that it will iterate through each key/value pair in the table and will return a list with the dropped entries.
- `$l():take(n:number):list` This function will take the first `n` entries from the list and return a list with the taken entries.
- `$l():takeright(n:number):list` This function will take the last `n` entries from the list and return a list with the taken entries.
- `$l():takewhile(function):list` This works exactly like `string.takewhile`, just that it will iterate through each key/value pair in the table and will return a list with the taken entries.
- `$l():takewhile(f:function):list` This works exactly like `string.takewhile`, just that it will iterate through each key/value pair in the table and will return a list with the taken entries.
- `$l():slice(start:number or nil, stop:number or nil [, step:number or nil]):list` This function will slice a specific range of indices out of the list and return it, starting at index `start` and stopping at `stop` with a step size of `step`. `step` must not be 0 but can be negative. `start` will default to `1` if it is `nil` or `0`, `stop` will default to the length of the list. Negative values for `start` or `stop` are interpreted as indexing backwards, from the end of the list.
- `$l():reduce(f:function):anything` This works exactly like `$l():reduceleft`.
- `$l():reduceleft(f:function):anything` This function must not be called with an empty list. If the length of the list is `1`, it will return the only value in the list. Otherwise, this function assigns the first entry in the list to a local variable m and calls `f` for every other value in the list, with `m` and that value as parameters. The value which `f` returns will then be assigned to `m` for the next iteration. Returns the final value of `m`.
- `$l():reduceright(f:function):anything` This works exactly like `$l():reduceleft`, just that it starts at the end of the list.
Expand Down
56 changes: 51 additions & 5 deletions selene/lib/selene/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ local function checkFunc(n, have, ...)
local msg = string.format("[Selene] bad argument #%d (function expected, got %s)", n, have)
error(msg, 2)
end

if #{...} == 0 then return end

local level = 3

local function check(want, ...)
checkArg(level, want, "number")
if not want then
Expand Down Expand Up @@ -381,7 +381,7 @@ local function tbl_foreach(self, f)
local parCnt = checkParCnt(parCount(f, 2))
for i, j in mpairs(self) do
f(parCnt(i, j))
end
end
end

-- Iterates through each entry and calls the function, returns a list if possible, a map otherwise
Expand Down Expand Up @@ -445,7 +445,7 @@ local function wrap_dropOrTake(self, amt, wrap, whenzero, whenall)
amt = clamp(amt, 0, #self)
return wrap_handleDropReturn(self, amt, wrap, whenzero, whenall, wrap_tableDropReturn)
end

-- Removes the first amt entries of the list, returns a list
local function tbl_drop(self, amt)
return wrap_dropOrTake(self, amt, wrap_dropfromleft, wrap_returnself, wrap_returnempty)
Expand Down Expand Up @@ -489,6 +489,32 @@ local function tbl_takewhile(self, f)
return wrap_dropOrTakeWhile(self, f, wrap_takefromleft, wrap_returnempty, wrap_returnself)
end

local function wrap_makeSliceable(self, start, stop, step)
step = step or 1
if step == 0 then
error("[Selene] bad argument #4 (got step size of 0)", 3)
end
start = math.max(1, (not start or start == 0) and 1 or (start < 0 and start + #self + 1) or start)
stop = math.min(#self, (not stop or stop == 0) and #self or (stop < 0 and stop + #self + 1) or stop)
return start, stop, step
end

local function tbl_slice(self, start, stop, step)
checkType(1, self, "list", "stringlist")
checkArg(2, start, "number", "nil")
checkArg(3, stop "number", "nil")
checkArg(4, step, "number", "nil")
start, stop, step = wrap_makeSliceable(self, start, stop, step)
if start > stop then
return newListOrMap({})
end
local sliced = {}
for i = start, stop, step do
insert(sliced, false, self._tbl[i])
end
return newListOrMap(sliced)
end

--inverts the list
local function wrap_reverse(self, newl)
checkType(1, self, "list", "stringlist")
Expand Down Expand Up @@ -833,6 +859,22 @@ local function str_takewhile(self, f)
return wrap_str_dropOrTakeWhile(self, f, wrap_takefromleft, wrap_emptystring, wrap_returnself)
end

local function str_slice(self, start, stop, step)
checkArg(1, self, "string")
checkArg(2, start, "number", "nil")
checkArg(3, stop "number", "nil")
checkArg(4, step, "number", "nil")
start, stop, step = wrap_makeSliceable(self, start, stop, step)
if start > stop then
return newListOrMap({})
end
local sliced = {}
for i = start, stop, step do
insert(sliced, false, self:sub(i,i))
end
return newListOrMap(sliced)
end

-- Returns the accumulator
local function str_foldleft(self, start, f)
checkArg(1, self, "string")
Expand Down Expand Up @@ -986,6 +1028,7 @@ local function patchNativeLibs(env)
env.string.take = str_take
env.string.takeright = str_takeright
env.string.takewhile = str_takewhile
env.string.slice = str_slice
env.string.fold = str_foldleft
env.string.foldleft = str_foldleft
env.string.foldright = str_foldright
Expand Down Expand Up @@ -1028,6 +1071,7 @@ local function loadSeleneConstructs()
_Table.take = tbl_take
_Table.takeright = tbl_takeright
_Table.takewhile = tbl_takewhile
_Table.slice = tbl_slice
_Table.reverse = tbl_reverse
_Table.flip = tbl_flip
_Table.fold = tbl_foldleft
Expand Down Expand Up @@ -1062,6 +1106,7 @@ local function loadSeleneConstructs()
_String.take = strl_take
_String.takeright = strl_takeright
_String.takewhile = strl_takewhile
_String.slice = tbl_slice
_String.reverse = strl_reverse
_String.flip = tbl_flip
_String.foldleft = tbl_foldleft
Expand Down Expand Up @@ -1113,7 +1158,7 @@ local function loadSelene(env)

if env._selene and env._selene.liveMode then
env._selene.oldload = env.load
env.load = function(ld, src, mv, loadenv)
env.load = function(ld, src, mv, loadenv)
if env._selene and env._selene.liveMode then
if type(ld) == "function" then
local s = ""
Expand Down Expand Up @@ -1159,6 +1204,7 @@ local function unloadSelene(env)
env.string.take = nil
env.string.takeright = nil
env.string.takewhile = nil
env.string.slice = nil
env.string.fold = nil
env.string.foldleft = nil
env.string.foldright = nil
Expand Down

0 comments on commit 21f4934

Please sign in to comment.