Category talk:Wren-dynamic: Difference between revisions
Content added Content deleted
(→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: | Line 30: | ||
The enum has: |
The enum has: |
||
1. static property getters for each member, |
1. static property getters for each member, |
||
2. a static 'startsFrom' property, |
2. a static 'startsFrom' property, |
||
3. a static 'members' property which returns a list of its members as strings |
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 { |
class Enum { |
||
Line 50: | Line 52: | ||
var mems = members.map { |m| "\"%(m)\"" }.join(", ") |
var mems = members.map { |m| "\"%(m)\"" }.join(", ") |
||
s = s + " static startsFrom { %(startsFrom) }\n" |
s = s + " static startsFrom { %(startsFrom) }\n" |
||
s = s + " static members { [%(mems)] |
s = s + " static members { [%(mems)] }\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)" |
s = s + "return %(name)" |
||
return Meta.compile(s).call() |
return Meta.compile(s).call() |
||
} |
} |
||
Line 64: | Line 77: | ||
The flags enum has: |
The flags enum has: |
||
1. static property getters for each member, |
1. static property getters for each member, |
||
2. a static 'hasZero' property which returns whether or not there is a zero member, |
2. a static 'hasZero' property which returns whether or not there is a zero member, |
||
3. a static 'members' property which returns a list of its members as strings |
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 { |
class Flags { |
||
Line 81: | Line 96: | ||
var m = members[i] |
var m = members[i] |
||
if (i == 0 && hasZero) { |
if (i == 0 && hasZero) { |
||
s = s + " static %(m) { 0 }\n" |
s = s + " static %(m) { 0 }\n" |
||
} else if (hasZero) { |
} else if (hasZero) { |
||
s = s + " static %(m) { %(1 << (i-1)) }\n" |
s = s + " static %(m) { %(1 << (i-1)) }\n" |
||
Line 90: | Line 105: | ||
var mems = members.map { |m| "\"%(m)\"" }.join(", ") |
var mems = members.map { |m| "\"%(m)\"" }.join(", ") |
||
s = s + " static hasZero { %(hasZero) }\n" |
s = s + " static hasZero { %(hasZero) }\n" |
||
s = s + " static members { [%(mems)] |
s = s + " static members { [%(mems)] }\n" |
||
s = s + " static [member] {\n" |
|||
s = s + " var ix = members.indexOf(member)\n" |
|||
⚫ | |||
s = s + " if (ix == 0) return 0\n" |
|||
s = s + " return 1 << (ix-1)\n" |
|||
⚫ | |||
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 + " 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)" |
s = s + "return %(name)" |
||
return Meta.compile(s).call() |
return Meta.compile(s).call() |
||
Line 97: | Line 135: | ||
// Convenience version of above method which does not have a member with a value of zero. |
// Convenience version of above method which does not have a member with a value of zero. |
||
static create(name, members) { create(name, members, false) } |
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 |
|||
⚫ | |||
⚫ | |||
⚫ | |||
// 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 |
|||
} |
} |
||