hslua-list 1.1.1 → 1.1.2
raw patch · 7 files changed
+91/−9 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +11/−0
- LICENSE +1/−1
- cbits/listmod.c +43/−2
- hslua-list.cabal +7/−4
- src/HsLua/List.hs +1/−1
- test/test-hslua-list.hs +1/−1
- test/test-list.lua +27/−0
CHANGELOG.md view
@@ -2,6 +2,17 @@ `hslua-list` uses [PVP Versioning](https://pvp.haskell.org). +## hslua-list-1.1.2++Released 2024-09-20.++- Lists can now be constructed from iterators.++- Added method `:at` to access list elements by index; negative+ indices are counted from the end. A second value can be+ passed, which will be returned if there is no item at the+ given index.+ ## hslua-list-1.1.1 Released 2023-03-17.
LICENSE view
@@ -1,4 +1,4 @@-Copyright © 2021-2023 Albert Krewinkel+Copyright © 2021-2024 Albert Krewinkel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the
cbits/listmod.c view
@@ -45,12 +45,31 @@ ** given. */ static int list_new (lua_State *L) {- lua_settop(L, 2); if (lua_isnoneornil(L, 2)) {+ lua_settop(L, 1); lua_newtable(L);- lua_remove(L, 2);+ } else if (lua_type(L, 2) == LUA_TFUNCTION) {+ /* try to use the function as an iterator */+ lua_settop(L, 5);+ lua_newtable(L); /* create new table */+ /* move the table and toclose variable out of the way */+ lua_insert(L, 2);+ lua_insert(L, 3);+ lua_toclose(L, 3);+ lua_Integer i = 0; /* list index */+ do {+ lua_pushvalue(L, 4); /* iterator function */+ lua_pushvalue(L, 5); /* state */+ lua_rotate(L, 6, -1); /* move control variable to the top */+ lua_call(L, 2, 1); /* get next list element */+ /* add return value to table */+ lua_pushvalue(L, -1);+ lua_rawseti(L, 2, ++i);+ } while (lua_type(L, -1) != LUA_TNIL);+ lua_settop(L, 2); /* keep only the new table */ } else { luaL_checktype(L, 2, LUA_TTABLE);+ lua_settop(L, 2); } lua_pushvalue(L, 1); lua_setmetatable(L, 2);@@ -58,6 +77,27 @@ } /*+** Returns the item at that index, or the default value if no item was+** found.+*/+static int list_at (lua_State *L) {+ lua_settop(L, 3); /* table; index; default value */+ lua_Integer i = luaL_checkinteger(L, 2);+ lua_Integer len = luaL_len(L, 1);++ if (i < -len || i > len) {+ /* out of bounds, do not try to get a value */+ return 1; /* return the default value */+ }++ i = i >= 0 ? i : len + i + 1;+ if (lua_rawgeti(L, 1, i) == LUA_TNIL) {+ lua_pop(L, 1); /* pop result; default value is now at the top */+ };+ return 1;+}++/* ** Creates a shallow clone of the given list; the clone will contain ** only the list elements, not any other elements that might have been ** present.@@ -343,6 +383,7 @@ {"__concat", list_concat}, {"__eq", list_eq}, {"__tostring", list_tostring},+ {"at", list_at}, {"clone", list_clone}, {"extend", list_extend}, {"filter", list_filter},
hslua-list.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: hslua-list-version: 1.1.1+version: 1.1.2 synopsis: Opinionated, but extensible Lua list type. description: List type for Lua, with a Haskell interface. homepage: https://hslua.org/@@ -9,7 +9,7 @@ license-file: LICENSE author: Albert Krewinkel maintainer: Albert Krewinkel <tarleb@hslua.org>-copyright: © 2022-2023 Albert Krewinkel+copyright: © 2022-2024 Albert Krewinkel category: Foreign build-type: Simple extra-doc-files: README.md@@ -20,8 +20,11 @@ , GHC == 8.8.4 , GHC == 8.10.7 , GHC == 9.0.2- , GHC == 9.2.5- , GHC == 9.4.4+ , GHC == 9.2.8+ , GHC == 9.4.8+ , GHC == 9.6.5+ , GHC == 9.8.2+ , GHC == 9.10.1 source-repository head type: git
src/HsLua/List.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE LambdaCase #-} {- |-Copyright : © 2021-2023 Albert Krewinkel+Copyright : © 2021-2024 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb@hslua.org>
test/test-hslua-list.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE TypeApplications #-} {-| Module : Main-Copyright : © 2021-2023 Albert Krewinkel+Copyright : © 2021-2024 Albert Krewinkel License : MIT Maintainer : Albert Krewinkel <tarleb@hslua.org>
test/test-list.lua view
@@ -16,6 +16,33 @@ test('returns a new list if called without args', function () assert.are_same(List(), {}) end),++ test('works with a simple iterator function', function ()+ local text = "two words"+ local result = List(string.gmatch(text, '[^%s]+'))+ assert.are_same({'two', 'words'}, result)+ end),++ test('can convert an interator into a list', function ()+ local tbl = {one = 1, two = 2}+ local result = List(next, tbl, nil)+ result:sort()+ assert.are_same(List{'one', 'two'}, result)+ end),+ },++ group 'at' {+ test('gets the item at the given index', function ()+ assert.are_equal(2, List{1, 1, 2, 3, 5}:at(3))+ end),++ test('negative indices are counted from the end', function ()+ assert.are_equal(5, List{1, 1, 2, 3, 5}:at(-1))+ end),++ test('the default value is returned if no item is found', function ()+ assert.are_equal(0, List{1, 1, 2, 3, 5}:at(9, 0))+ end) }, group 'clone' {