Module: dom-internals Synopsis: Document Object Model Author: Scott McKay Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Useful constants // The XML namespace URI define constant $xml-namespace-uri :: = "http://www.w3.org/XML/1998/namespace"; // The XMLNS namespace URI define constant $xmlns-namespace-uri :: = "http://www.w3.org/XML/2000/xmlns/"; /// Sequence hacking functions define inline function range-check (sequence :: , _size :: , _start :: , _end :: ) => () when (_start < 0 | _start > _size) element-range-error(sequence, _start) end; when (_end < 0 | _end > _size) element-range-error(sequence, _end) end end function range-check; define inline function primitive-position (sequence :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (index :: false-or()) range-check(sequence, size(sequence), _start, _end); block (return) let (_start :: , _end :: , increment :: ) = if (from-end?) values(_end - 1, _start - 1, -1) else values(_start, _end, 1) end; without-bounds-checks for (i :: = _start then i + increment, until: i = _end) when (test(item, sequence[i])) return(i) end end end; #f end end function primitive-position; define method position (sequence :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (index :: false-or()) primitive-position(sequence, item, test: test, start: _start, end: _end, from-end?: from-end?) end method position; define sealed method position (vector :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(vector), from-end?) => (index :: false-or()) primitive-position(vector, item, test: test, start: _start, end: _end, from-end?: from-end?) end method position; define sealed method position (vector :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(vector), from-end?) => (index :: false-or()) primitive-position(vector, item, test: test, start: _start, end: _end, from-end?: from-end?) end method position; define sealed method position (string :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(string), from-end?) => (index :: false-or()) primitive-position(string, item, test: test, start: _start, end: _end, from-end?: from-end?) end method position; define inline function primitive-position-if (sequence :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (index :: false-or()) range-check(sequence, size(sequence), _start, _end); block (return) let (_start :: , _end :: , increment :: ) = if (from-end?) values(_end - 1, _start - 1, -1) else values(_start, _end, 1) end; without-bounds-checks for (i :: = _start then i + increment, until: i = _end) when (predicate(sequence[i])) return(i) end end end; #f end end function primitive-position-if; define method position-if (sequence :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (index :: false-or()) primitive-position-if(sequence, predicate, start: _start, end: _end, from-end?: from-end?) end method position-if; define sealed method position-if (vector :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(vector), from-end?) => (index :: false-or()) primitive-position-if(vector, predicate, start: _start, end: _end, from-end?: from-end?) end method position-if; define sealed method position-if (vector :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(vector), from-end?) => (index :: false-or()) primitive-position-if(vector, predicate, start: _start, end: _end, from-end?: from-end?) end method position-if; define sealed method position-if (string :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(string), from-end?) => (index :: false-or()) primitive-position-if(string, predicate, start: _start, end: _end, from-end?: from-end?) end method position-if; define inline function primitive-find (sequence :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (object :: false-or()) range-check(sequence, size(sequence), _start, _end); block (return) let (_start :: , _end :: , increment :: ) = if (from-end?) values(_end - 1, _start - 1, -1) else values(_start, _end, 1) end; without-bounds-checks for (i :: = _start then i + increment, until: i = _end) let elt = sequence[i]; when (test(item, elt)) return(elt) end end end; #f end end function primitive-find; define method find (sequence :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (object :: false-or()) primitive-find(sequence, item, test: test, start: _start, end: _end, from-end?: from-end?) end method find; define sealed method find (vector :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(vector), from-end?) => (object :: false-or()) primitive-find(vector, item, test: test, start: _start, end: _end, from-end?: from-end?) end method find; define sealed method find (vector :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(vector), from-end?) => (object :: false-or()) primitive-find(vector, item, test: test, start: _start, end: _end, from-end?: from-end?) end method find; define sealed method find (string :: , item, #key test = \==, start: _start :: = 0, end: _end :: = size(string), from-end?) => (object :: false-or()) primitive-find(string, item, test: test, start: _start, end: _end, from-end?: from-end?) end method find; define inline function primitive-find-if (sequence :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (object :: false-or()) range-check(sequence, size(sequence), _start, _end); block (return) let (_start :: , _end :: , increment :: ) = if (from-end?) values(_end - 1, _start - 1, -1) else values(_start, _end, 1) end; without-bounds-checks for (i :: = _start then i + increment, until: i = _end) let elt = sequence[i]; when (predicate(elt)) return(elt) end end end; #f end end function primitive-find-if; define method find-if (sequence :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(sequence), from-end?) => (object :: false-or()) primitive-find-if(sequence, predicate, start: _start, end: _end, from-end?: from-end?) end method find-if; define sealed method find-if (vector :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(vector), from-end?) => (object :: false-or()) primitive-find-if(vector, predicate, start: _start, end: _end, from-end?: from-end?) end method find-if; define sealed method find-if (vector :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(vector), from-end?) => (object :: false-or()) primitive-find-if(vector, predicate, start: _start, end: _end, from-end?: from-end?) end method find-if; define sealed method find-if (string :: , predicate :: , #key start: _start :: = 0, end: _end :: = size(string), from-end?) => (object :: false-or()) primitive-find-if(string, predicate, start: _start, end: _end, from-end?: from-end?) end method find-if; define method count (predicate :: , sequence :: ) => (count :: ) let n :: = 0; for (item in sequence) when (predicate(item)) inc!(n) end end; n end method count; define sealed method count (predicate :: , vector :: ) => (count :: ) let n :: = 0; without-bounds-checks for (i :: from 0 below size(vector)) when (predicate(vector[i])) inc!(n) end end end; n end method count; define sealed method count (predicate :: , vector :: ) => (count :: ) let n :: = 0; without-bounds-checks for (i :: from 0 below size(vector)) when (predicate(vector[i])) inc!(n) end end end; n end method count; // Inserts the new item at the given index, effectively discarding the very // last item in the vector define method insert-at! (v :: type-union(, ), item, index) => (v :: type-union(, )) local method expand (v, index :: ) => () without-bounds-checks for (i :: from (size(v) - 1) to (index + 1) by -1) v[i] := v[i - 1] end end end method; select (index) #"start" => expand(v, 0); v[0] := item; #"end" => add!(v, item); otherwise => expand(v, index); v[index] := item; end; v end method insert-at!; // Like the above, but grows the stretchy vector define sealed method insert-at! (sv :: , item, index) => (sv :: ) local method expand (sv, index :: ) => () without-bounds-checks for (i :: from (size(sv) - 1) to (index + 1) by -1) sv[i] := sv[i - 1] end end end method; select (index) #"start" => sv.size := sv.size + 1; expand(sv, 0); sv[0] := item; #"end" => add!(sv, item); otherwise => sv.size := sv.size + 1; expand(sv, index); sv[index] := item; end; sv end method insert-at!; define method remove-at! (v :: type-union(, ), index) => (v :: type-union(, )) local method contract (v, index :: ) => () without-bounds-checks for (i :: from index to (size(v) - 2)) v[i] := v[i + 1] end end end method; select (index) #"start" => contract(v, 0); #"end" => #f; otherwise => contract(v, index); end; v end method remove-at!; define sealed method remove-at! (sv :: , index) => (sv :: ) local method contract (sv, index :: ) => () without-bounds-checks for (i :: from index to (size(sv) - 2)) sv[i] := sv[i + 1] end end end method; select (index) #"start" => contract(sv, 0); #"end" => #f; otherwise => contract(sv, index); end; sv.size := sv.size - 1; sv end method remove-at!;