Category talk:Wren-dynamic: Difference between revisions

→‎Source code: Added 2 new methods to Enum and Flags classes. Removed redundant Flags.indexOf method.
(→‎Source code: Flags enums now support an optional zero value member.)
(→‎Source code: Added 2 new methods to Enum and Flags classes. Removed redundant Flags.indexOf method.)
Line 30:
The enum has:
1. static property getters for each member,
2. a static 'startsFrom' property, and
3. a static 'members' property which returns a list of its members as strings.,
4. a static '[member]' indexer which returns its integer value from its member name (string), and
5. a static 'fromValue(v)' method which returns the member name (string) from its integer value.
*/
class Enum {
Line 50 ⟶ 52:
var mems = members.map { |m| "\"%(m)\"" }.join(", ")
s = s + " static startsFrom { %(startsFrom) }\n"
s = s + " static members { [%(mems)] }\n}\n"
s = s + " static [member] {\n"
s = s + " var ix = members.indexOf(member)\n"
s = s + " return (ix >= 0) ? ix + %(startsFrom) : null\n"
s = s + " }\n"
s = s + " static fromValue(v) {\n"
s = s + " if (!v.isInteger || v < %(startsFrom) || v >= %(startsFrom) + members.count) {\n"
s = s + " return null\n"
s = s + " }\n"
s = s + " return members[v - %(startsFrom)]\n"
s = s + " }\n}\n"
s = s + "return %(name)"
 
return Meta.compile(s).call()
}
Line 64 ⟶ 77:
The flags enum has:
1. static property getters for each member,
2. a static 'hasZero' property which returns whether or not there is a zero member, and
3. a static 'members' property which returns a list of its members as strings.,
4. a static '[member]' indexer which returns its integer value from its member name (string), and
5. a static 'fromValue(v)' method which returns the member name (string) from its integer value.
*/
class Flags {
Line 81 ⟶ 96:
var m = members[i]
if (i == 0 && hasZero) {
s = s + " static %(m) { 0 }\n"
} else if (hasZero) {
s = s + " static %(m) { %(1 << (i-1)) }\n"
Line 90 ⟶ 105:
var mems = members.map { |m| "\"%(m)\"" }.join(", ")
s = s + " static hasZero { %(hasZero) }\n"
s = s + " static members { [%(mems)] }\n}\n"
s = s + " static [member] {\n"
s = s + " var ix = members.indexOf(member)\n"
returnif (hasZero) ? res + 1 : res{
s = s + " if (ix == 0) return 0\n"
s = s + " return 1 << (ix-1)\n"
} else {
s = s + " return 1 << ix\n"
}
s = s + " }\n"
s = s + " static fromValue(v) {\n"
if (hasZero) {
s = s + " if (v == 0) return members[0]\n"
s = s + " if (!v.isInteger || v < 1 || v & (v-1) != 0) return null\n"
s = s + " var resix = (memberv.log / 2.log).round\n"
s = s + " if (ix + 1 >= members.count) return null\n"
s = s + " return members[ix+1]\n"
} else {
s = s + " if (!v.isInteger || v < 1 || v & (v-1) != 0) return null\n"
s = s + " var ix = (v.log / 2.log).round\n"
s = s + " if (ix >= members.count) return null\n"
s = s + " return members[ix]\n"
}
s = s + " }\n}\n"
s = s + "return %(name)"
return Meta.compile(s).call()
Line 97 ⟶ 135:
// Convenience version of above method which does not have a member with a value of zero.
static create(name, members) { create(name, members, false) }
 
// Returns the zero based index into the Fields property
// for a given Flags enum member and whether or not there is a zero member.
// Returns -1 if the member doesn't exist.
static indexOf(member, hasZero, memCount) {
if (hasZero.type != Bool) Fiber.abort("'hasZero' must be true or false.")
var maxCount = hasZero ? 33 : 32
if (memCount.type != Num || !memCount.isInteger || memCount < 1 || memCount > maxCount) {
Fiber.abort("Member count must be between 1 and %(maxCount).")
}
var limit = hasZero ? 1 << (memCount-2) : 1 << (memCount-1)
if (member.type != Num || !member.isInteger || member < 0 || member > limit) {
Fiber.abort("Member must be a non-negative integer <= %(limit).")
}
if (member == 0) return hasZero ? 0 : -1
if (member & (member-1) != 0) return -1 // not a power of two
var res = (member.log / 2.log).round
return hasZero ? res + 1 : res
}
 
// Convenience versions of above method where the number of members is assumed to be the maximum.
static indexOf(member, hasZero) { indexOf(member, hasZero, hasZero ? 33 : 32) }
static indexOf(member) { indexOf(member, false, 32) } // assumes no zero memmber
}
 
9,485

edits