Lua: Backport new Lua functions from master and add bit.rflagdecode

This commit is contained in:
Ilari Liusvaara 2013-01-23 08:43:31 +02:00
parent 865a450a43
commit ecfec8a1f4
3 changed files with 136 additions and 0 deletions

View file

@ -2146,6 +2146,43 @@ bit.popcount(number a)
Population count of a.
\end_layout
\begin_layout Subsubsection
bit.clshift(number a, number b, [number amount,[number bits]])
\end_layout
\begin_layout Standard
Does chained left shift on a, b by amount positions, assuming numbers to
be of specified number of bits.
\end_layout
\begin_layout Subsubsection
bit.crshift(number a, number b, [number amount,[number bits]])
\end_layout
\begin_layout Standard
Does chained right shift on a, b by amount positions, assuming numbers to
be of specified number of bits.
\end_layout
\begin_layout Subsubsection
bit.flagdecode(number a, number bits, [string on, [string off]])
\end_layout
\begin_layout Standard
Return string of length bits where ith character is ith character of on
if bit i is on, otherwise ith character of off.
Out of range reads give last character, or '*'/'-' if empty.
\end_layout
\begin_layout Subsubsection
bit.rflagdecode(number a, number bits, [string on, [string off]])
\end_layout
\begin_layout Standard
Like bit.flagdecode, but outputs the string in the opposite order (most significa
nt bit first).
\end_layout
\begin_layout Subsection
Table gui:
\end_layout

View file

@ -1059,6 +1059,31 @@ Are all set bits in b also set in a?
Population count of a.
8.2.15 bit.clshift(number a, number b, [number amount,[number
bits]])
Does chained left shift on a, b by amount positions, assuming
numbers to be of specified number of bits.
8.2.16 bit.crshift(number a, number b, [number amount,[number
bits]])
Does chained right shift on a, b by amount positions, assuming
numbers to be of specified number of bits.
8.2.17 bit.flagdecode(number a, number bits, [string on, [string
off]])
Return string of length bits where ith character is ith character
of on if bit i is on, otherwise ith character of off. Out of
range reads give last character, or '*'/'-' if empty.
8.2.18 bit.rflagdecode(number a, number bits, [string on, [string
off]])
Like bit.flagdecode, but outputs the string in the opposite order
(most significant bit first).
8.3 Table gui:
Most of these functions can only be called in on_paint and

View file

@ -1,4 +1,5 @@
#include "lua/internal.hpp"
#include "library/minmax.hpp"
#define BITWISE_BITS 48
#define BITWISE_MASK ((1ULL << (BITWISE_BITS)) - 1)
@ -165,6 +166,79 @@ namespace
return 1;
});
function_ptr_luafun lua_clshift("bit.clshift", [](lua_State* LS, const std::string& fname) -> int {
unsigned amount = 1;
unsigned bits = 48;
uint64_t a = get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
uint64_t b = get_numeric_argument<uint64_t>(LS, 2, fname.c_str());
get_numeric_argument(LS, 3, amount, fname.c_str());
get_numeric_argument(LS, 4, bits, fname.c_str());
uint64_t mask = ((1ULL << bits) - 1);
a &= mask;
b &= mask;
a <<= amount;
a &= mask;
a |= (b >> (bits - amount));
b <<= amount;
b &= mask;
lua_pushnumber(LS, a);
lua_pushnumber(LS, b);
return 2;
});
function_ptr_luafun lua_crshift("bit.crshift", [](lua_State* LS, const std::string& fname) -> int {
unsigned amount = 1;
unsigned bits = 48;
uint64_t a = get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
uint64_t b = get_numeric_argument<uint64_t>(LS, 2, fname.c_str());
get_numeric_argument(LS, 3, amount, fname.c_str());
get_numeric_argument(LS, 4, bits, fname.c_str());
uint64_t mask = ((1ULL << bits) - 1);
a &= mask;
b &= mask;
b >>= amount;
b |= (a << (bits - amount));
b &= mask;
a >>= amount;
lua_pushnumber(LS, a);
lua_pushnumber(LS, b);
return 2;
});
int flagdecode_core(lua_State* LS, const std::string& fname, bool reverse)
{
uint64_t a = get_numeric_argument<uint64_t>(LS, 1, fname.c_str());
uint64_t b = get_numeric_argument<uint64_t>(LS, 2, fname.c_str());
std::string on, off;
if(lua_type(LS, 3) == LUA_TSTRING)
on = get_string_argument(LS, 3, fname.c_str());
if(lua_type(LS, 4) == LUA_TSTRING)
off = get_string_argument(LS, 4, fname.c_str());
size_t onl = on.length();
size_t offl = off.length();
char onc = onl ? on[onl - 1] : '*';
char offc = offl ? off[offl - 1] : '-';
char buffer[65];
unsigned i;
size_t bias = min(b, (uint64_t)64) - 1;
for(i = 0; i < 64 && i < b; i++) {
char onc2 = (i < onl) ? on[i] : onc;
char offc2 = (i < offl) ? off[i] : offc;
buffer[reverse ? (bias - i) : i] = ((a >> i) & 1) ? onc2 : offc2;
}
buffer[i] = '\0';
lua_pushstring(LS, buffer);
return 1;
}
function_ptr_luafun lua_flagdecode("bit.flagdecode", [](lua_State* LS, const std::string& fname) -> int {
return flagdecode_core(LS, fname, false);
});
function_ptr_luafun lua_rflagdecode("bit.rflagdecode", [](lua_State* LS, const std::string& fname) -> int {
return flagdecode_core(LS, fname, true);
});
lua_symmetric_bitwise<combine_none, BITWISE_MASK> bit_none("bit.none");
lua_symmetric_bitwise<combine_none, BITWISE_MASK> bit_bnot("bit.bnot");
lua_symmetric_bitwise<combine_any, 0> bit_any("bit.any");