module: dfmc-browser-support Synopsis: Browser-specific routines 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 macro with-context { with-context (?context:expression) ?:body end } => { dfmc-do-with-library-context(method () ?body end, ?context) } end macro; define macro with-form-context { with-form-context (?form:expression) ?:body end } => { dfmc-do-with-library-context (method () ?body end, ?form.source-form-context) } end macro; define macro with-no-context { with-no-context ?:body end } => { dynamic-bind (dfmc-*library-description* = #f) ?body end } end macro; //// //// COMPILATION-CONTEXT-SOURCES //// define sealed class () constant slot source-sequence-records :: dfmc-, required-init-keyword: records:; end class; define method type-for-copy (seq :: ) => (type :: singleton()) end; define sealed method size (seq :: ) size(seq.source-sequence-records) end method; define sealed method element (seq :: , index :: , #key default = unsupplied()) => (res :: dfmc-) if (supplied?(default)) let cr = element(seq.source-sequence-records, index, default: not-found()); if (found?(cr)) cr.dfmc-compilation-record-source-record else default end else seq.source-sequence-records[index].dfmc-compilation-record-source-record end end method; define sealed method forward-iteration-protocol (seq :: ) => (i, s, n :: , f? :: ,k :: , e :: , es :: , c :: ); local method next (seq, i) => res; i + 1 end; local method finished? (seq, i, limit) => res; i == limit end; local method key (seq, i) => res; i end; local method elt (seq, i) => res; let cr = seq.source-sequence-records[i]; cr.dfmc-compilation-record-source-record end; local method elt-setter (val, seq, i) => res; seq[i] := val end; local method copy (seq, i) => res; i end; values(0, seq.source-sequence-records.size, next, finished?, key, elt, elt-setter, copy) end method; define function compilation-context-sources (cc :: dfmc-) => (sr* :: ); make(, records: as(dfmc-, dfmc-library-description-compilation-records(cc))) end function; define function compilation-context-version (cc :: dfmc-) => (major-version, minor-version, time-stamp) values(cc.dfmc-library-description-major-version, cc.dfmc-library-description-minor-version, as(, cc.dfmc-library-description-change-count)) end function; define function compilation-context-compiler-settings (ld :: dfmc-) list(operating-system: ld.dfmc-library-description-os-name, processor: ld.dfmc-library-description-processor-name, back-end: ld.dfmc-library-description-compiler-back-end-name, mode: ld.dfmc-library-description-compilation-mode, build-location: ld.dfmc-library-description-build-location, library-pack: ld.dfmc-library-description-library-pack) end function; define function compilation-context-compiler-settings-setter (settings, ld :: dfmc-) local method setter (ld, #key operating-system = unsupplied(), processor = unsupplied(), back-end = unsupplied(), mode = unsupplied(), build-location = unsupplied(), library-pack = unsupplied()) if (supplied?(operating-system)) ld.dfmc-library-description-os-name := operating-system end; if (supplied?(processor)) ld.dfmc-library-description-processor-name := processor end; if (supplied?(back-end)) ld.dfmc-library-description-compiler-back-end-name := back-end end; if (supplied?(mode)) ld.dfmc-library-description-compilation-mode := mode end; if (supplied?(build-location)) ld.dfmc-library-description-build-location := build-location end; if (supplied?(library-pack)) ld.dfmc-library-description-library-pack := library-pack end; end; apply(setter, ld, settings) end function; define class () constant slot unresolved-variable-name :: , required-init-keyword: name:; constant slot unresolved-variable-module-name :: , required-init-keyword: module:; end class; define method variable-name (var :: dfmc-) let name = var.dfmc-fragment-identifier; let module = var.dfmc-fragment-context; values(name, if (module) module.dfmc-namespace-name else #"internal" end) end method; define method variable-name (var :: dfmc-) let name = var.dfmc-dependency-name; let module = var.dfmc-dependency-module; values(name, module.dfmc-namespace-name) end method; // This isn't quite right - it's supposed to return the module name as it's // known in the library the variable was referenced from, but that's gone, all // we have is the home name of the module in the library the module was // defined in. define method variable-name (var :: dfmc-) let name = var.dfmc-binding-identifier; let module = var.dfmc-binding-home; values(name, module.dfmc-namespace-name) end method; define method variable-name (var :: ) values(var.unresolved-variable-name, var.unresolved-variable-module-name) end method; define function make-variable (name, module-name) make(, name: as(,name), module: as(, module-name)) end function; define function dylan-variable (name, #key module = #"dylan") make-variable(name, module) end function; // Since a binding is a kind of , we can just return the // binding as the home variable. Do that consistently, so can have // a more efficient same-variable?. define method variable-home (context :: dfmc-, var :: dfmc-) => home :: dfmc-; dfmc-local-binding-in(context.dfmc-language-definition, var); end method; define method variable-home (context :: dfmc-, var :: dfmc-) => home :: dfmc-; with-context (context) dfmc-untracked-lookup-binding(var) end end method; define method variable-home (context :: dfmc-, var :: dfmc-) => home :: dfmc-; with-context (context) let name = var.dfmc-referenced-variable-name; let module = var.dfmc-referenced-variable-module; dfmc-untracked-lookup-binding-in(module, name) end end method; define method variable-home (context :: dfmc-, var :: ) => home :: dfmc-; with-context (context) let (name, module-name) = variable-name(var); let library = context.dfmc-language-definition; let module = dfmc-lookup-module-in(library, module-name); dfmc-untracked-lookup-binding-in(module, name) end end method; define function same-variable? (context :: dfmc-, v1 :: , v2 :: ) variable-home(context, v1) == variable-home(context, v2) end function; define function same-variable-name? (v1 :: , v2 :: ) let (v1-n, v1-m) = variable-name(v1); let (v2-n, v2-m) = variable-name(v2); v1-n == v2-n & v1-m == v2-m end function; define function project-library-definition (context :: dfmc-) let library = context.dfmc-language-definition; library & library.dfmc-namespace-definition end function; define function do-namespace-names (space :: dfmc-, function :: , inherited?, internal?, local-bindings?) let local-bindings = space.dfmc-namespace-local-bindings; if (internal?) for (local-binding keyed-by name in local-bindings) let kind = if (dfmc-exported-name?(space, name)) #"exported" else #"internal" end; if (local-bindings?) function(name, kind, local-binding: local-binding) else function(name, kind) end; end else for (name in space.dfmc-exported-names) if (local-bindings?) function(name, #"exported", local-binding: local-bindings[name]) else function(name, #"exported") end; end; end; if (inherited?) dfmc-do-imported-names(function, space, internal?: internal?); end if; end function; define function do-library-modules (context :: dfmc-, function :: , #key inherited?, internal?) let library = context.dfmc-language-definition; debug-assert(library); let action = method (name, kind) with-no-context function(name, kind) end end; do-namespace-names(library, action, inherited?, internal?, #f); end function; define function find-module-definition (context :: dfmc-, name) => (definition, kind) let library = context.dfmc-language-definition; debug-assert(library); let name = as(, name); let module = dfmc-lookup-module-in(library, name, default: #f); let defined? = dfmc-defined-name?(library, name); if (module) values(module.dfmc-namespace-definition, if (defined?) #"defined" else #"inherited" end) end; end function; define inline function name-exported-from? (space :: dfmc-, name :: ) dfmc-lookup-name(space, name, default: #f, exported?: #t) & #t end function; define function module-exported? (context :: dfmc-, name) name-exported-from?(context.dfmc-language-definition, as(, name)) end function; define function do-module-variables (context :: dfmc-, definition :: , function :: , #key inherited?, internal?) with-context (context) // needed for fragment-module let module-name = definition.dfmc-form-namespace-name; let module = dfmc-lookup-module-in(context.dfmc-language-definition, module-name); let active-definition = module & module.dfmc-namespace-definition; if (definition == active-definition) local method variable-function (name, kind, #key local-binding) if (local-binding) // ignore local bindings without any properties... if (kind == #"exported" | dfmc-canonical-binding-properties(local-binding)) with-no-context function(local-binding, kind) end; end; else let variable = make-variable(name, module-name); with-no-context function(variable, kind) end; end; end method; do-namespace-names(module, variable-function, inherited?, internal?, #t); end if; end with-context; end function; define method variable-exported? (context :: dfmc-, var :: dfmc-) dfmc-exported-name?(var.dfmc-binding-home, var.dfmc-binding-identifier) end method; define method variable-exported? (context :: dfmc-, var :: dfmc-) with-context (context) // needed for fragment-module. name-exported-from?(var.dfmc-fragment-module, var.dfmc-fragment-identifier) end end method; define method variable-exported? (context :: dfmc-, var :: dfmc-) with-context (context) name-exported-from?(var.dfmc-dependency-module, var.dfmc-dependency-name) end end method; define method variable-exported? (context :: dfmc-, var :: ) with-context (context) let library = context.dfmc-language-definition; let module-name = var.unresolved-variable-module-name; let module = dfmc-lookup-module-in(library, module-name); name-exported-from?(module, var.unresolved-variable-name) end; end method; // #t means something not representable in the API. define constant = type-union(, singleton(#t), dfmc-); define generic externalize-type (type) => (res :: false-or()); define method externalize-type (type) => (res :: singleton(#t)) #t end method; define method externalize-type (type == #f) => (res :: singleton(#f)) #f end method; define method externalize-type (type :: ) => (res :: ) type end method; define method externalize-type (type :: dfmc-) => (res :: ) type /* if (instance?(type, )) // Hack to work around the fact that actually precedes // in the CPL of a name fragment. type else let loc = dfmc-fragment-source-location(type); loc | #t end; */ end method; define function source-locator-positions (loc :: ) values(loc.dfmc-source-location-start-character, loc.dfmc-source-location-end-character) end function; define function source-locator-lines (loc :: ) values(loc.dfmc-source-location-start-line, loc.dfmc-source-location-end-line) end function; define generic source-form-defined-variables (form :: ) => (variables :: ); define method source-form-defined-variables (form :: ) => (variables :: ) #() end method; define method source-form-defined-variables (form :: dfmc-) => (variables :: ) with-form-context (form) form.dfmc-form-variable-names; end; end method; define method source-form-defined-variables (macro-form :: ) => (variables :: ) with-form-context (macro-form) let variables = #(); for (form in macro-form.macro-form-expanded-forms) for (var in form.source-form-defined-variables) variables := add-new!(variables, var); end; end; reverse!(variables) end; end method; define generic source-form-variable-type (form :: , variable :: ) => (type :: false-or()); define function explicit-variable-type (form :: dfmc-, variable :: ) => (type :: false-or(), found? :: ) with-form-context (form) let index = find-key(form.dfmc-form-variable-names, method (v) same-variable-name?(variable, v) end); if (index) let type = form.dfmc-form-type-expressions[index]; values(externalize-type(type), #t) else values(#f, #f) end; end; end function; define method source-form-variable-type (form :: dfmc-, variable :: ) => (type :: singleton(#f)) // Strictly speaking should err if variable is not defined by the form, // but it's not worth checking #f; end method; define method source-form-variable-type (form :: dfmc-, variable :: ) => (type :: false-or()) // Strictly speaking should err if not found?, but since the base case // doesn't err, we won't either... with-form-context (form) let (type, found?) = explicit-variable-type(form, variable); found? & type end; end method; define method source-form-variable-type (macro-form :: , variable :: ) => (type :: false-or()) with-form-context (macro-form) block (return) for (form in macro-form.macro-form-expanded-forms) if (instance?(form, dfmc-)) let (type, found?) = explicit-variable-type(form, variable); if (found?) return(type) end; end if; end for; end block; end; end method; // we are not exporting it since this is an internal error in the env // no assert since we want to continue define class () end; define function canonical-compilation-record (context :: dfmc-, sr) => (cr :: false-or(dfmc-)) let cr = dfmc-source-record-compilation-record(context, sr, default: #f); unless(cr) signal(make(, format-string: "Invalid canonical source record %s passed to the compiler", format-arguments: list(sr.source-record-name))) end; cr end; define function source-record-top-level-forms (context :: dfmc-, sr) with-context (context) let cr = canonical-compilation-record(context, sr); let all-forms = cr & cr.dfmc-compilation-record-top-level-forms; choose(method (form) ~instance?(form, dfmc-) & form.dfmc-form-parent-form == #f end, all-forms | #()) end; end function; define function source-record-dispatch-decisions (context :: dfmc-, sr) => (dds :: false-or()) with-context (context) let cr = dfmc-source-record-compilation-record(context, sr, default: #f); let dds = cr & cr.dfmc-compilation-record-dispatch-decisions; // Do not return dispatch decisions if they're still in the process // of being computed (i.e. before they are turned into a vector). instance?(dds, ) & dds end; end; define function macro-form-expanded-forms (macro-form :: ) with-form-context (macro-form) choose(method(form) form.dfmc-form-parent-form == macro-form end, macro-form.dfmc-form-derived-forms) end; end function; define function module-definition-name (form :: ) dfmc-form-namespace-name(form) end function; define function library-definition-name (form :: ) dfmc-form-namespace-name(form) end function; define function module-definition-used-modules (form :: ) map(dfmc-used-name, form.dfmc-form-use-clauses) end function; define function library-definition-used-libraries (form :: ) map(dfmc-used-name, form.dfmc-form-use-clauses) end function; define function class-definition-superclass-types (form :: ) with-form-context (form) map(externalize-type, dfmc-form-superclass-expressions(form)) end; end function; define function class-definition-init-keywords (form :: ) with-form-context (form) map(dfmc-spec-init-keyword, form.dfmc-form-keyword-specs) end; end function; define function keyword-spec (form :: , keyword :: ) block (return) for (spec in form.dfmc-form-keyword-specs) if (keyword == spec.dfmc-spec-keyword-expression) return(spec) end; end for; end block; end function; define function class-definition-init-keyword-required? (form :: , init-keyword) with-form-context (form) let spec = keyword-spec(form, init-keyword); spec.dfmc-spec-init-keyword-required? end; end function; define function class-definition-init-keyword-init-kind (form :: , init-keyword) with-form-context (form) let spec = keyword-spec(form, init-keyword); slot-definition-init-kind(spec) end; end function; define function class-definition-init-keyword-type (form :: , init-keyword) with-form-context (form) let spec = keyword-spec(form, init-keyword); externalize-type(spec.dfmc-spec-type-expression) end; end function; define function functional-parameters (form :: ) with-form-context (form) let sig = form.dfmc-form-signature; let reqs = sig.dfmc-spec-argument-required-variable-specs; let next = sig.dfmc-spec-argument-next-variable-spec; let rest? = sig.dfmc-spec-argument-rest?; let rest = rest? & sig.dfmc-spec-argument-rest-variable-spec; let key? = sig.dfmc-spec-argument-key?; let keys = key? & sig.dfmc-spec-argument-key-variable-specs; let req-vals = sig.dfmc-spec-value-required-variable-specs; let rest-val = sig.dfmc-spec-value-rest-variable-spec; local method var (spec) if (spec) spec.dfmc-spec-variable-name end end; local method vars (specs) if (specs) map(var, specs) end end; values(vars(reqs), var(rest), var(next), vars(keys), vars(req-vals),var(rest-val)) end; end function; define function functional-keys (form :: ) with-form-context (form) let sig = form.dfmc-form-signature; let key? = sig.dfmc-spec-argument-key?; let all-keys? = sig.dfmc-spec-argument-all-keys?; let keys = key? & sig.dfmc-spec-argument-key-variable-specs; local method key (spec) if (spec) let key = spec.dfmc-spec-keyword-expression; if (instance?(key, )) key else // What the key name is defaulted, it gets stored as a literal key.dfmc-fragment-value end end; end; values(if (keys) map(key, keys) end, all-keys?) end; end function; define function functional-parameter-types (form :: ) with-form-context (form) let sig = form.dfmc-form-signature; let reqs = sig.dfmc-spec-argument-required-variable-specs; let next = sig.dfmc-spec-argument-next-variable-spec; let rest? = sig.dfmc-spec-argument-rest?; let rest = rest? & sig.dfmc-spec-argument-rest-variable-spec; let key? = sig.dfmc-spec-argument-key?; let keys = key? & sig.dfmc-spec-argument-key-variable-specs; let req-vals = sig.dfmc-spec-value-required-variable-specs; let rest-val = sig.dfmc-spec-value-rest-variable-spec; local method var (spec) spec & externalize-type(spec.dfmc-spec-type-expression) end; local method vars (specs) specs & map(var, specs) end; values (vars(reqs), var(rest), var(next), vars(keys), vars(req-vals), var(rest-val)) end; end function; define function generic-definition-options (form :: ) with-form-context (form) dfmc-form-options(form) end; end function; define function domain-definition-domain-types (form :: ) with-form-context (form) map(externalize-type, form.dfmc-form-domain-type-expressions) end; end function; define function slot-definition-init-kind (form :: ) with-form-context (form) if (form.dfmc-spec-init-supplied?) if (form.dfmc-spec-init-expression?) #"init-expression" // #"="? elseif (form.dfmc-spec-init-value?) #"init-value" else #"init-function" end elseif (form.dfmc-spec-init-keyword-required?) #"init-keyword" end end; end function; define function slot-definition-keyword (form :: ) with-form-context (form) values(form.dfmc-spec-init-keyword, form.dfmc-spec-init-keyword-required?) end; end function; define function slot-definition-class-definition (form :: ) with-form-context (form) form.dfmc-form-parent-form end; end function; define function slot-definition-type (form :: ) with-form-context (form) externalize-type(form.dfmc-spec-type-expression) end; end function; /***********************************************************************/ // Global derived info define function variable-active-definition (context :: dfmc-, var :: ) with-context (context) let binding = variable-home(context, var); let def = dfmc-untracked-binding-definition(binding, default: #f); def & ~instance?(def, dfmc-) & def end end function; define function variable-active-method-definitions (context :: dfmc-, var :: ) with-context (context) let binding = variable-home(context, var); dfmc-choose-instances(, dfmc-untracked-binding-modifying-definitions(binding)) end end function; define function variable-all-definitions (context :: dfmc-, var :: ) with-context (context) let binding = variable-home(context, var); concatenate(dfmc-untracked-binding-all-definitions(binding), choose(method (form) instance?(form, ) | instance?(form, ) end, dfmc-untracked-binding-all-modifying-definitions(binding))) end end function; define function source-form-browsing-context (context :: dfmc-, form :: ) with-context (context) dfmc-form-library(form) end; end function; define function class-binding-in-context (context :: dfmc-, form :: ) let var = dfmc-form-variable-name(form); unless (dfmc-form-ignored?(form)) dfmc-form-variable-binding(form) end; end function; define method class-direct-subclass-definitions (context :: dfmc-, form :: ) // Someday, might know about define constant x = make(), but not now #f end method; define method class-direct-subclass-definitions (context :: dfmc-, form :: ) with-context (context) let binding = class-binding-in-context(context, form); if (binding) dfmc-choose-instances(, dfmc-untracked-binding-modifying-definitions(binding)) end end end method; define method class-all-superclass-definitions (context :: dfmc-, form :: ) #f end method; define method class-all-superclass-definitions (context :: dfmc-, form :: ) with-context (context) let binding = class-binding-in-context(context, form); if (binding) let (c, c?) = dfmc-untracked-binding-model-object-if-computed(binding); if (c?) let defs = map(dfmc-model-definition, dfmc-^all-superclasses(c)); if (~member?(#f, defs)) defs end if; end if; end if; end with-context; end method; define method class-all-slot-definitions (context :: dfmc-, form :: ) #f end method; define method class-all-slot-definitions (context :: dfmc-, form :: ) with-context (context) let binding = class-binding-in-context(context, form); if (binding) let (c, c?) = dfmc-untracked-binding-model-object-if-computed(binding); if (c?) let sds = dfmc-^slot-descriptors(c); if (sds) let defs = map(dfmc-model-definition, sds); if (~member?(#f, defs)) defs end; end; end; end; end with-context end method; define method class-direct-method-definitions (context :: dfmc-, form :: ) #f end method; define method direct-method-on? (form :: , binding) #f end method; define method direct-method-on? (form :: , binding) let sig = dfmc-form-signature(form); any?(method (vspec) let type = dfmc-spec-type-expression(vspec); instance?(type, dfmc-) & dfmc-untracked-lookup-binding(type) == binding end method, sig.dfmc-spec-argument-required-variable-specs) end method; define method class-direct-method-definitions (context :: dfmc-, form :: ) // TODO: should the compiler pre-compute these? with-context (context) let binding = class-binding-in-context(context, form); if (binding) reduce(method (methods, def) if (direct-method-on?(def, binding)) pair(def, methods) else methods end end method, #(), dfmc-binding-local-referers(binding)) end; end with-context; end method; // These next two return a lot of internal info. Could probably narrow it down // to refs directly referenced from source by only selecting names in the // module of the form... define method source-form-referenced-variables (context :: dfmc-, form :: , #key kind) with-context (context) dfmc-form-referenced-binding-variables(form) | dfmc-choose-name-dependencies(form, dfmc-dep$name-binding-ref); end; end method; define method source-form-referenced-macros (context :: dfmc-, form :: ) with-context (context) dfmc-form-referenced-macro-variables(form) | dfmc-choose-name-dependencies(form, dfmc-dep$name-macro-ref); end; end method; define method variable-referencing-forms (context :: dfmc-, var :: , #key kind) with-context (context) let binding = variable-home(context, var); dfmc-binding-local-referers(binding); end; end method; /// Warnings define function program-note-message (note :: ) apply(format-to-string, condition-format-string(note), condition-format-arguments(note)) end; define function program-note-creator (note :: ) => (creator :: type-union(, dfmc-, singleton(#f))); let creator = dfmc-condition-program-note-creator(note); if (instance?(creator, dfmc-)) dfmc-compilation-record-source-record(creator) else creator end end function; define function program-note-< (n1 :: , n2 :: ) let c1 = n1.dfmc-condition-program-note-creator; let c2 = n2.dfmc-condition-program-note-creator; ~c1 | (c2 & dfmc-defined-after?(c1, c2)) end; define inline function choose-notes (cc :: dfmc-, test :: ) => (notes :: ) let notes = #(); for (q :: keyed-by dependent in cc.dfmc-library-conditions-table) when (test(dependent)) notes := concatenate!(as(, q), notes); end; end; sort!(as(, notes), test: program-note-<, stable: #t); end; define method compilation-context-notes (cc :: dfmc-) with-context (cc) choose-notes(cc, method (dep) #t end) end; end method; define method execution-transaction-notes (cc :: dfmc-, transaction-id) with-context (cc) choose-notes(cc, method (dep) dep == transaction-id | ((instance?(dep, dfmc-) | instance?(dep, dfmc-)) & dfmc-compilation-record-transaction-id (dfmc-compilation-record-of(dep)) == transaction-id) end); end; end method; define function source-record-notes (cc :: dfmc-, sr) let cr = dfmc-source-record-compilation-record(cc, sr); with-context (cc) choose-notes(cc, method (dep) dep == cr | (instance?(dep, dfmc-) & dep.dfmc-form-compilation-record == cr) end) end; end function; define function source-form-notes (context :: dfmc-, form :: ) with-context (context) element(context.dfmc-library-conditions-table, form, default: #()) end end function; ///// //// Project compilation ///// define dfmc-program-error slot condition-project, init-keyword: project:; slot condition-library-pack, init-keyword: library-pack:; format-string "Library Pack %d must be installed to use %s"; format-arguments library-pack, project; end dfmc-program-error ; define function open-compilation-context (project, #key database-location, profile-location, build-settings, read-only?, load-namespace? = #t) let (ld, database-already-exists?) = dfmc-make-library-description(project, database-location: database-location, profile-location: profile-location, build-settings: build-settings, read-only?: read-only?, load-namespace?: load-namespace?); ld end function; define function compilation-context-project (context :: dfmc-) dfmc-library-description-project(context) end function; define function compilation-context-database-location (context :: dfmc-) dfmc-library-description-database-location(context) end function; // define function compilation-context-profile-location // (context :: dfmc-) // dfmc-library-description-profile-location(context) // end function; define function close-compilation-context (context :: dfmc-) dfmc-close-library-description(context) end function; define function save-compilation-context (context :: dfmc-, #key flush?) with-context (context) dfmc-save-definition-database(context, flush?: flush?) end; end function; define method compile-project-definitions (context :: dfmc-, #rest keys, #key compile-all?, compile-if-built?, build-settings = #(), strip? = #f, #all-keys) => (did-it? :: ) // other keys: skip-link?, start-at, skip-emit?, harp-output? = unsupplied(), // force-link?, form?, force-emit?, assembler-output?, save?, flush?, apply(dfmc-compile-library-from-definitions, context, keys) end method; define function used-compilation-contexts (context :: dfmc-) => (contexts :: ) with-context (context) // ensures language-definition dfmc-library-description-used-descriptions(context) end; end function; // Returns all compilation-contexts used by context, plus context itself, // sorted so that a library preceeds all the libraries it uses. context // itself is first in the list. The return value is explicitly a list so // you can use .tail to get just the used contexts. define function all-known-compilation-contexts (context :: dfmc-) => (contexts :: ) with-context (context) // ensures language-definition dfmc-all-library-descriptions(context) end; end function; define function compilation-context-built? (context :: dfmc-) dfmc-library-description-built?(context) end function; define function dylan-library-compilation-context? (context :: dfmc-) dfmc-dylan-library-library-description?(context) end function; ////// ///// Interactive execution ///// define function establish-execution-context (ld :: dfmc-, debug-target, #key allow-interaction? = #t) => (ild :: dfmc-) dfmc-lookup-interactive-context(debug-target, ld, force-shadow?: allow-interaction?) end function; define function find-execution-context (ld :: dfmc-, debug-target) => (ild :: false-or(dfmc-)) dfmc-lookup-interactive-context(debug-target, ld, default: #f); end function; define function release-execution-context (ild :: dfmc-) dfmc-close-library-description(ild); end function; define function condition-database-name(c :: ) => (name) dfmc-dood-name(dfmc-dood-failed-dood(c)) end;