Category talk:Wren-dynamic: Difference between revisions

→‎Source code: Flags enums now support an optional zero value member.
(→‎Source code: Added some enums and removed the type aliases which are no longer needed.)
(→‎Source code: Flags enums now support an optional zero value member.)
Line 59:
}
 
/* Flags creates a 'flags' enum with up to 32 read-only static members, plus an optional zero member.
Members are assigned in order an integer value starting from 1 and multiplying by 2 each time., unless
they have a zero member, when the first member has a value of 0.
The flags enum has:
1. static property getters for each member, and
2. a static 'membershasZero' property which returns awhether listor ofnot itsthere is a memberszero asmember, strings.and
3. a static 'members' property which returns a list of its members as strings.
*/
class Flags {
// Creates a class for the Flags enum (with an underscore after the name) and
// returns a reference to it.
static create(name, members, hasZero) {
if (name.type != String || name == "") Fiber.abort("Name must be a non-empty string.")
if (members.isEmpty || members.count > (hasZero ? 33 : 32)) {
Fiber.abort("A flags enum must have between 1 and 32 members, plus an optional zero member.")
}
if (hasZero.type != Bool) Fiber.abort("'hasZero' must be true or false.")
name = name + "_"
var s = "class %(name) {\n"
for (i in 0...members.count) {
var m = members[i]
sif (i == s0 +&& " static %(mhasZero) { %(1 << i) }\n"
s = s + " static %(m) { 0 }\n"
} else if (hasZero) {
s = s + " static %(m) { %(1 << (i-1)) }\n"
} else {
s = s + " static %(m) { %(1 << i) }\n"
}
}
var mems = members.map { |m| "\"%(m)\"" }.join(", ")
s = s + " static hasZero { %(hasZero) }\n"
s = s + " static members { [%(mems)] }\n}\n"
s = s + "return %(name)"
Line 85 ⟶ 95:
}
 
// ReturnsConvenience theversion zeroof basedabove indexmethod intowhich thedoes Fieldsnot property forhave a givenmember Flagswith enuma membervalue of zero.
static indexOfcreate(membername, members) { create(member.logname, /members, 2.logfalse).round }
 
// 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,482

edits