Category talk:Wren-trait: Difference between revisions

m
→‎Source code: Now uses Wren S/H lexer.
(→‎Source code: Comparable now inherits from Cloneable.)
m (→‎Source code: Now uses Wren S/H lexer.)
 
(19 intermediate revisions by the same user not shown)
Line 1:
===Source code===
<langsyntaxhighlight ecmascriptlang="wren">/* Module "trait.wren" */
 
/* Cloneable is an abstract class which enables child classes to automatically be
Line 13:
*/
class CloneableSeq is Sequence {
clone() { this } /* to be overridden by child class */
}
 
Line 29:
 
< (other) { compare(other) < 0 }
> (other) { compare(other) > 0 }
<=(other) { compare(other) <= 0 }
>=(other) { compare(other) >= 0 }
Line 36:
}
 
/* Stepped ByRef wraps a Sequencevalue soto enable it canto be iteratedpassed by stepsreference to a othermethod thanor 1function. */
class Stepped is SequenceByRef {
// Constructs a new steppedByRef sequenceobject.
construct new(seq, stepvalue) {
_value = value
if (!(seq is Sequence)) Fiber.abort("First argument must be a sequence.")
_seq = seq
_step = (step < 1) ? 1 : step // minimum step of 1
}
 
// Properties to get and set the value of the current instance.
// Iterator protocol methods.
value { _value }
iterate(iterator) {
value=(v) { _value = ifv (!iterator) {}
 
return _seq.iterate(iterator)
// Returns the string representation of the current instance's value.
toString { _value.toString }
}
 
/*
ByKey wraps a reference type object to enable it to be used as a Map key. It does this
by using a counter to create a unique integral key for each such object and maintaining
an internal map which enables the object to be quickly retrieved from its key.
*/
class ByKey {
// Retrieves a ByKey object from its key. Returns null if the key is not present.
static [key] { __map ? __map[key] : null }
 
// Retrieves a ByKey object's key from the object it wraps.
// If the same object has been wrapped more than once, returns the first key found which may
// not be the lowest. Returns 0 if the object is unwrapped.
static findKey(obj) {
for (me in __map) {
if (me.value.obj == obj) return me.key
}
return 0
}
 
// Returns the number of objects currently in the internal map.
static mapCount { __tally ? __map.count : 0 }
 
// Returns the total number of keys created to date.
static keyCount { __tally ? __tally : 0 }
 
// Constructs a new ByKey object.
construct new(obj) {
_obj = obj
if (!__tally) {
__map = {}
__tally = 1
} else {
var count__tally = _step__tally + 1
while (count > 0 && iterator) {
iterator = _seq.iterate(iterator)
count = count - 1
}
return iterator
}
_key = __tally
__map[_key] = this
}
 
// Properties
obj { _obj } // returns the current instance
key { _key } // returns the current instance's key
 
// Removes the current instance from the internal map and sets it to null.
unkey() {
__map.remove(_key)
_obj = null
}
 
// Returns the string representation of the current instance.
iteratorValue(iterator) { _seq.iteratorValue(iterator) }
toString { _obj.toString }
}
 
/*
Const represents a group of individually named read-only values which are
Reversed wraps a Sequence (other than a range) so it can be iterated in reverse
stored internally in a map. Any attempt to change such a value is ignored
and by steps other than 1.
though they can be removed from the map.
*/
class Reversed is SequenceConst {
// Returns the value of 'name' if it is present in the internal map
// Constructs a new reversed sequence.
// or null otherwise.
construct new(seq, step) {
static [name] { (__cmap && __cmap.containsKey(name)) ? __cmap[name] : null }
if (!(seq is Sequence) || seq is Range) {
 
Fiber.abort("First argument must be a sequence other than a range.")
// Associates 'value' with 'name' in the internal map.
// If 'name' is already in the map, the change is ignored.
static [name]=(value) {
if (!__cmap) __cmap = {}
if (!__cmap.containsKey(name)) {
__cmap[name] = value
}
_seq = seq
_step = (step < 1) ? 1 : step // minimum step of 1
}
 
// Removes 'name' and its associated value from the internal map and returns
// Convenience method which calls the constructor with a step of 1.
// that value. If 'name' was not present in the map, returns null.
static new(seq) { Reversed.new(seq, 1) }
static remove(name) { __cmap.remove(name) }
 
// Returns a list of the entries (name/value pairs) in the internal map.
// Iterator protocol methods.
static entries { __cmap.toList }
iterate(iterator) {
}
var it = _seq.iterate(iterator)
 
if (it == null || it == 0) {
/*
it = _seq.count - 1
Var represents a group of individually named read/write values which are
} else if (it == false) {
stored internally in a map. It can be used to simulate the creation of
it = _seq.count - 1 - _step
variables at runtime. It can also be used to allow variable names which would
} else {
otherwise be illegal in Wren such as those which include non-ASCII characters.
it = it - 1 - _step
*/
}
class Var {
return (it >= 0) ? it : false
// Returns the value of 'name' if it is present in the internal map
// or null otherwise.
static [name] { (__vmap && __vmap.containsKey(name)) ? __vmap[name] : null }
 
// Associates 'value' with 'name' in the internal map.
// Any existing value is replaced.
static [name]=(value) {
if (!__vmap) __vmap = {}
__vmap[name] = value
}
 
// Removes 'name' and its associated value from the internal map and returns
iteratorValue(iterator) { _seq.iteratorValue(iterator) }
// that value. If 'name' was not present in the map, returns null.
static remove(name) { __vmap.remove(name) }
 
// Returns a list of the entries (name/value pairs) in the internal map.
static entries { __vmap.toList }
}
 
/* TypedVar is similar to Var except that simulated variables always retain the
// Type aliases for classes in case of any name clashes with other modules.
same type as they had when they were originally created.
var Trait_Cloneable = Cloneable
*/
var Trait_CloneableSeq = CloneableSeq
class TypedVar {
var Trait_Comparable = Comparable
// Returns the value of 'name' if it is present in the internal map
var Trait_Stepped = Stepped
// or null otherwise.
var Trait_Reversed = Reversed</lang>
static [name] { (__vmap && __vmap.containsKey(name)) ? __vmap[name] : null }
 
// Associates 'value' with 'name' in the internal map.
// Any existing value is replaced. However, it is an error to attempt to replace
// an existing value with a value of a different type.
static [name]=(value) {
if (!__vmap) __vmap = {}
if (!__vmap.containsKey(name)) {
__vmap[name] = value
} else {
var vtype = value.type
var mtype = __vmap[name].type
if (vtype != mtype) {
Fiber.abort("Expecting an item of type %(mtype), got %(vtype).")
} else {
__vmap[name] = value
}
}
}
 
// Removes 'name' and its associated value from the internal map and returns
// that value. If 'name' was not present in the map, returns null.
static remove(name) { __vmap.remove(name) }
 
// Returns a list of the entries (name/value pairs) in the internal map.
static entries { __vmap.toList }
}</syntaxhighlight>
9,476

edits