Module: dfmc-modeling Synopsis: Limited collections Author: Jonathan Bachrach and Keith Playford 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 define class () constant slot limited-element-type-mapping-default :: false-or(), required-init-keyword: default:; constant slot limited-class-element-type-mappings :: , required-init-keyword: class-mappings:; constant slot limited-limited-integer-element-type-mappings :: , required-init-keyword: limited-integer-mappings:; end class; define constant $limited-element-type-mappings = make(); define method install-limited-element-type-mappings (collection :: , mappings :: ) add!($limited-element-type-mappings, pair(collection, mappings)); end method; define macro limited-element-type-mappings-definer { define limited-element-type-mappings (?collection:name) ?mappings:* end } => { define limited-element-type-mappings-aux (?collection) (?mappings) (?mappings) (?mappings) end } end macro; define macro limited-element-type-mappings-aux-definer { define limited-element-type-mappings-aux (?collection:name) (?class-mappings) (?limited-integer-mappings) (?default-mapping) end } => { define constant "$" ## ?collection ## "-mappings" = make(, default: ?default-mapping, class-mappings: vector(?class-mappings), limited-integer-mappings: vector(?limited-integer-mappings)); install-limited-element-type-mappings (?#"collection", "$" ## ?collection ## "-mappings") } class-mappings: { } => { } { otherwise => ?concrete-class:name; ... } => { ... } { ?element-type:name => ?concrete-class:name; ... } => { pair(?#"element-type", ?#"concrete-class"), ... } { ?anything:* => ?concrete-class:name; ... } => { ... } limited-integer-mappings: { } => { } { limited(, min: ?min:expression, max: ?max:expression) => ?concrete-class:name; ... } => { pair(pair(?min, ?max), ?#"concrete-class"), ... } { ?anything:* => ?concrete-class:name; ... } => { ... } default-mapping: { } => { #f } { otherwise => ?concrete-class:name; ... } => { ?#"concrete-class" } { ?anything:* => ?concrete-class:name; ... } => { ... } end macro; define method lookup-limited-collection-concrete-class (element-type :: <&type>, mappings :: ) => (concrete-class :: <&class>, default :: <&class>) let default = dylan-value(limited-element-type-mapping-default(mappings)); block (return) if (instance?(element-type, <&limited-integer>)) for (limited-integer-mapping in limited-limited-integer-element-type-mappings(mappings)) let limited-integer-min-max = head(limited-integer-mapping); let limited-integer = ^limited-integer(min: head(limited-integer-min-max), max: tail(limited-integer-min-max)); if (^subtype?(element-type, limited-integer)) return(dylan-value(tail(limited-integer-mapping)), default); end if end for; else for (class-mapping in limited-class-element-type-mappings(mappings)) if (element-type == dylan-value(head(class-mapping))) return(dylan-value(tail(class-mapping)), default); end if end for; end if; values(default, default) end block; end method; define method lookup-limited-collection-element-type (concrete-class :: <&class>, mappings :: ) => (element-type :: false-or(<&type>)) block (return) for (class-mapping in limited-class-element-type-mappings(mappings)) if (concrete-class == dylan-value(tail(class-mapping))) return(dylan-value(head(class-mapping))); end if end for; for (limited-integer-mapping in limited-limited-integer-element-type-mappings(mappings)) let limited-integer = head(limited-integer-mapping); if (concrete-class == dylan-value(tail(limited-integer-mapping))) return(^limited-integer(min: head(limited-integer), max: tail(limited-integer))) end if end for; if (concrete-class == dylan-value(limited-element-type-mapping-default(mappings))) dylan-value(#"") else #f end if end block; end method; define method lookup-any-limited-collection-element-type (concrete-class :: <&class>) => (element-type :: false-or(<&type>)) block (return) for (mapping in $limited-element-type-mappings) if (^subtype?(concrete-class, dylan-value(head(mapping)))) return(lookup-limited-collection-element-type(concrete-class, tail(mapping))) end if end for; #f end block; end method; define limited-element-type-mappings () => ; => ; otherwise => ; end limited-element-type-mappings; define method select-limited-string (of, size) let concrete-class = lookup-limited-collection-concrete-class(of, $-mappings); if (size) ^make(<&limited-vector-type>, class: dylan-value(#""), concrete-class: concrete-class, element-type: of, size: size); else concrete-class end if; end method; define limited-element-type-mappings () => ; => ; => ; => ; => ; limited(, min: 0, max: 255) => ; limited(, min: 0, max: 65535) => ; otherwise => ; end limited-element-type-mappings; define method select-limited-vector (of, size) let (concrete-class, default-concrete-class) = lookup-limited-collection-concrete-class(of, $-mappings); if (size | concrete-class == default-concrete-class) ^make(<&limited-vector-type>, class: dylan-value(#""), concrete-class: concrete-class, element-type: of, size: size); else concrete-class end if; end method; define limited-element-type-mappings () => ; => ; => ; => ; => ; limited(, min: 0, max: 255) => ; limited(, min: 0, max: 65535) => ; otherwise => ; end limited-element-type-mappings; define method select-limited-array (of, sz, dimensions) if (sz) select-limited-vector(of, sz) elseif (dimensions & size(dimensions) = 1) select-limited-vector(of, first(dimensions)) else let (concrete-class, default-concrete-class) = lookup-limited-collection-concrete-class(of, $-mappings); if (dimensions | concrete-class == default-concrete-class) ^make(<&limited-array-type>, class: dylan-value(#""), concrete-class: concrete-class, element-type: of, dimensions: dimensions); else concrete-class end if; end if; end method; define limited-element-type-mappings () => ; => ; limited(, min: 0, max: 255) => ; otherwise => ; end limited-element-type-mappings; define method select-limited-stretchy-vector (of) let (concrete-class, default-concrete-class) = lookup-limited-collection-concrete-class(of, $-mappings); if (concrete-class == default-concrete-class) ^make(<&limited-stretchy-vector-type>, class: dylan-value(#""), concrete-class: concrete-class, element-type: of); else concrete-class end if end method; define limited-element-type-mappings () => ; otherwise => ; end limited-element-type-mappings; define method select-limited-table (of, size) let (concrete-class, default-concrete-class) = lookup-limited-collection-concrete-class(of, $
-mappings); if (size | concrete-class == default-concrete-class) ^make(<&limited-table-type>, class: dylan-value(#"
"), concrete-class: dylan-value(#""), element-type: of, size: size); else concrete-class end if; end method; define limited-element-type-mappings () => ; otherwise => ; end limited-element-type-mappings; define method select-limited-set (of, size) let (concrete-class, default-concrete-class) = lookup-limited-collection-concrete-class(of, $-mappings); if (size | concrete-class == default-concrete-class) ^make(<&limited-set-type>, class: dylan-value(#""), concrete-class: concrete-class, element-type: of, size: size); else concrete-class end if end method; define limited-element-type-mappings () => ; otherwise => ; end limited-element-type-mappings; define method select-limited-deque (of) let (concrete-class, default-concrete-class) = lookup-limited-collection-concrete-class(of, $-mappings); if (size | concrete-class == default-concrete-class) ^make(<&limited-deque-type>, class: dylan-value(#""), concrete-class: concrete-class, element-type: of); else concrete-class end if end method; define method ^limited-collection (class :: <&class>, #rest all-keys, #key of, size, dimensions, #all-keys) let of = of | lookup-keyword-value(all-keys, #"of"); // HACK: FOR EMULATOR let size = size | lookup-keyword-value(all-keys, #"size"); // HACK: FOR EMULATOR let dimensions = dimensions | lookup-keyword-value(all-keys, #"dimensions"); // HACK: FOR EMULATOR if (of) // PARALLELS RUNTIME METHODS ON LIMITED select (class) dylan-value(#"") // TODO: NOT YET IMPLEMENTED => class; dylan-value(#"") => select-limited-string(of, size); dylan-value(#"") => select-limited-deque(of); dylan-value(#"") => select-limited-stretchy-vector(of); dylan-value(#""), dylan-value(#"") => select-limited-vector(of, size); dylan-value(#"") => select-limited-array(of, size, dimensions); dylan-value(#"") => select-limited-set(of, size); dylan-value(#"
"), dylan-value(#"") => select-limited-table(of, size); // UNINSTANTIATEABLE LIMITED COLLECTION TYPES dylan-value(#"") => ^make(<&limited-collection-type>, class: class, element-type: of, size: size); dylan-value(#"") => ^make(<&limited-explicit-key-collection-type>, class: class, element-type: of, size: size); dylan-value(#"") => ^make(<&limited-mutable-collection-type>, class: class, element-type: of, size: size); dylan-value(#"") => ^make(<&limited-stretchy-collection-type>, class: class, element-type: of); dylan-value(#"") => ^make(<&limited-mutable-explicit-key-collection-type>, class: class, element-type: of, size: size); dylan-value(#"") => ^make(<&limited-sequence-type>, class: class, element-type: of, size: size); dylan-value(#"") => ^make(<&limited-mutable-sequence-type>, class: class, element-type: of, size: size); otherwise => #f; end select else class end if; end method; // eof