Module: dfmc-definitions Synopsis: The domain definition processor. Author: 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 //// Domain definitions. // Domain definition objects. define dood-class () lazy constant slot form-domain-type-expressions :: , required-init-keyword: domain-type-expressions:; end dood-class; define leaf packed-slots form-properties (, ) boolean slot form-sealed? = #t, // vs. open init-keyword: sealed?:; boolean slot form-sideways? = #f, // vs. upwards (maybe!) init-keyword: sideways?:; end packed-slots; define inline method domain-definition? (object) => (well? :: ) instance?(object, ) end method; define method form-define-word (form :: ) => (word :: ) #"domain" end method; define generic form-domain-type-expressions (form :: ) => (types :: ); // Conversion to a definition object. define &definition domain-definer { define ?mods:* domain ?:name (?domain-types:*) } => do-define-domain(form, mods, name, domain-types); end &definition; define function do-define-domain (form, mods, name, domain-types) => (forms) let (options, adjectives) = parse-domain-adjectives(name, mods); let domain-types = parse-domain-types(domain-types); let tlf = apply(make, , source-location: fragment-source-location(form), variable-name: name, adjectives: adjectives, domain-type-expressions: as(, domain-types), options); list(tlf) end function; define function parse-domain-types (types-form) macro-case (types-form) { ?types:* } => types; types: { } => #(); { ?:expression, ... } => pair(expression, ...); end macro-case end function; //// Domain adjective parsing. // In fact "define domain" only accepts "sealed", so it would be simple to // handle it in the main converter. It's only done this way to give error // reports consistent with those generated by other forms that accept // adjectives. And in case the syntax gets extended somehow one day. define property => sealed?: = #t value sealed = #t; end property; define property => sideways?: = #f value sideways = #t; // The following becomes #f when the compiler is being compiled as a // single component. value compiler-sideways = #t; end property; define constant domain-adjectives = list(, ); define function parse-domain-adjectives (name, adjectives-form) => (initargs) parse-property-adjectives (domain-adjectives, adjectives-form, name) end function; //// Definition protocol. define serious-program-warning slot condition-definition, required-init-keyword: definition:; format-string "This domain extends the definition %= which does not define a " "generic function - ignoring."; format-arguments definition; end serious-program-warning; define serious-program-warning slot condition-variable, required-init-keyword: variable:; format-string "This domain attempts to extend the definition of an undefined variable " "%s from another library - ignoring."; format-arguments variable; end serious-program-warning; define method add-local-definition (definitions :: , definition :: ) => (new-definitions :: ) add-in-order(definitions, definition, test: defined-before?) end method; // define method install-top-level-form-bindings // (form :: ) => () // add-modifying-definition(form-variable-name(form), form); // end method; define method install-top-level-form-bindings (form :: ) => () let name = form-variable-name(form); let binding = lookup-binding(name); let def = binding-definition(binding, default: #f); if (~def & binding-imported-into-library?(binding)) note(, source-location: form-source-location(form), variable: binding); ignore-modifying-definition(name, form); elseif (def & ~instance?(def, )) note(, source-location: form-source-location(form), definition: def); ignore-modifying-definition(name, form); else add-modifying-definition(name, form); end; end method; define method uninstall-top-level-form-bindings (form :: ) => () remove-modifying-definition(form-variable-name(form), form); end method; // eof