Module: emulator-environment-backend Synopsis: Emulator Environment Backend Author: Andy Armstrong 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 /// Proxy objects define method ensure-server-object (server :: , object == #t) => (object :: ) $true-object end method ensure-server-object; define method ensure-server-object (server :: , object == #f) => (object :: ) $false-object end method ensure-server-object; define method ensure-server-object (server :: , object) => (object :: ) let class = select (object by instance?) => ; => ; => ; => ; => ; => ; => ; => ; => ; => ; => ; => ; => ; => case dylan-symbol?(object) => ; dylan-constant?(object) => ; otherwise => ; end; otherwise => case dylan-slot?(object) => ; otherwise => user-object-environment-class(server, object); end end; ensure-server-object-of-class(server, object, class) end method ensure-server-object; define method ensure-server-object-of-class (server :: , object, class :: subclass()) => (object :: ) make-environment-object(class, project: server-project(server), application-object-proxy: object, compiler-object-proxy: object) end method ensure-server-object-of-class; define method do-server-environment-objects (function :: , server :: , objects :: , class :: ) => () for (proxy in objects) function(ensure-server-object-of-class(server, proxy, class)) end end method do-server-environment-objects; /// Object objects define method application-object-class (application :: , object :: ) => (class :: ) let class = dylan-object-class(application-object-proxy(object)); class & ensure-server-object-of-class(application, class, ) end method application-object-class; //--- Hack for the mixed-up world of the Dylan emulator! define method application-object-class (application :: , object :: ) => (class :: ) let class = dylan-object-class(compiler-object-proxy(object)); class & ensure-server-object-of-class(application, class, ) end method application-object-class; define method get-environment-object-primitive-name (application :: , object :: ) => (name :: ) let symbol = compiler-object-proxy(object); dylan-symbol-name(symbol) end method get-environment-object-primitive-name; define method composite-object-contents (project :: , object :: , #key inherited? = #t) => (names :: , values :: ) let local? = if (inherited?) #() else #t end; let (names, contents) = object-slot-contents(application-object-proxy(object), local?: local?); let ensure-function = curry(ensure-server-object, project); values(map(ensure-function, names), map(ensure-function, contents)) end method composite-object-contents; define method composite-object-size (application :: , object :: , #key inherited? = #t) => (size :: ) let (names, contents) = object-slot-contents(application-object-proxy(object), local?: #f); ignore(contents); size(names) end method composite-object-size; /// Core objects define method get-environment-object-primitive-name (application :: , symbol :: ) => (name :: ) dylan-symbol-name(application-object-proxy(symbol)) end method get-environment-object-primitive-name; define method get-environment-object-primitive-name (application :: , number :: ) => (name :: ) format-to-string("%d", application-object-proxy(number)) end method get-environment-object-primitive-name; define method get-environment-object-primitive-name (application :: , character :: ) => (name :: ) format-to-string("%s", application-object-proxy(character)) end method get-environment-object-primitive-name; define method get-environment-object-primitive-name (application :: , string :: ) => (name :: ) application-object-proxy(string) end method get-environment-object-primitive-name; define method pair-head (application :: , pair :: ) => (object :: ) ensure-server-object(application, head(application-object-proxy(pair))) end method pair-head; define method pair-tail (application :: , pair :: ) => (object :: ) ensure-server-object(application, tail(application-object-proxy(pair))) end method pair-tail; /// Source handling //---*** There must be a more efficient way of doing this... define method source-file-contents (file, #key start-line, end-line) => (string :: ) with-open-file (stream = file) start-line := start-line | 0; if (start-line > 0 | end-line) for (line from 0 to start-line) read-line(stream) end; if (end-line) let contents = make(); for (line from start-line to end-line) let line = read-line(stream); contents := format-to-string("%s%s\n", contents, line) end; contents else read-to-end(stream) end else read-to-end(stream) end end end method source-file-contents; define method environment-object-source (database :: , object :: ) => (source :: false-or()) let source-location = definition-source-location(database, object); if (source-location) let source-record = source-location-source-record(source-location); let file = source-record-location(source-record); source-file-contents (file, start-line: source-location-start-line(source-location), end-line: #f) // source-location-end-line(source-location)) end end method environment-object-source; /// Ranges define method range-start (application :: , range :: ) => (start :: ) let (size, first, last, step) = dylan-range-contents(application-object-proxy(range)); ensure-server-object(application, first) end method range-start; define method range-end (application :: , range :: ) => (start :: ) let (size, first, last, step) = dylan-range-contents(application-object-proxy(range)); ensure-server-object(application, last) end method range-end; define method range-by (application :: , range :: ) => (start :: ) let (size, first, last, step) = dylan-range-contents(application-object-proxy(range)); ensure-server-object(application, step) end method range-by; /// Definition objects define method definition-source-location (database :: , object :: ) => (source-location :: false-or()) let (source, start-line, end-line) = dylan-object-source-location(compiler-object-proxy(object)); if (source) let project = server-project(database); let source-record = find-project-source-record(project, source); if (source-record) make-line-location(source-record, start-line) end end end method definition-source-location; define method definition-source-location (database :: , library :: ) => (source-location :: false-or()) let project = library-project(database, library); let source-record = project-sources(project)[0]; if (source-record) make-line-location(source-record, 0) end end method definition-source-location; define method definition-source-location (database :: , object :: ) => (source-location :: false-or()) let library = module-library(database, object); let project = library-project(database, library); let source = project-source-location(project, "module"); let source-record = find-project-source-record(project, source); if (source-record) make-line-location(source-record, 0) end end method definition-source-location; define method do-used-definitions (function :: , database :: , definition :: , #key modules, libraries, client) => () do-dylan-definitions-used-definitions (method (proxy) function(ensure-server-object(database, proxy)) end, compiler-object-proxy(definition)) end method do-used-definitions; define method do-client-definitions (function :: , database :: , definition :: , #key modules, libraries, client) => () do-dylan-definitions-client-definitions (method (proxy) function(ensure-server-object(database, proxy)) end, compiler-object-proxy(definition)) end method do-client-definitions; /// Compiler warnings define method do-compiler-warnings (function :: , database :: , object :: , #key client) => () do-dylan-compiler-warnings (method (object) function (ensure-server-object-of-class (database, object, )) end, compiler-object-proxy(object)) end method do-compiler-warnings; define method get-environment-object-primitive-name (database :: , warning :: ) => (message :: ) dylan-warning-message(compiler-object-proxy(warning)) end method get-environment-object-primitive-name; define method warning-object-definition (database :: , warning :: ) => (definition :: false-or()) let lisp-definition = dylan-warning-definition(compiler-object-proxy(warning)); ensure-server-object(database, lisp-definition) end method warning-object-definition; define method warning-object-source-location (database :: , warning :: ) => (location :: false-or()) let definition = warning-object-definition(database, warning); if (definition) definition-source-location(database, definition) end end method warning-object-source-location; define method environment-object-source (database :: , object :: ) => (source :: false-or()) let definition = warning-object-definition(database, object); if (definition) environment-object-source(database, definition) end end method environment-object-source; /// Collection modeling define method composite-object-size (application :: , object :: , #key inherited? = #t) => (size :: ) ignore(inherited?); size(application-object-proxy(object)) end method composite-object-size; define method collection-elements (application :: , object :: , #key range) => (elements :: ) ignore(range); map(curry(ensure-server-object, application), application-object-proxy(object)) end method collection-elements; define method collection-keys (application :: , collection :: , #key range: collection-range) => (keys :: ) ignore(collection-range); let proxy = application-object-proxy(collection); select (proxy by instance?) => range(from: 0, to: size(proxy)); => map(curry(ensure-server-object, application), key-sequence(proxy)) end end method collection-keys; /// User objects define method user-object-slot-values (application :: , object :: ) => (functions :: , values :: ) let (names, contents) = object-slot-contents(application-object-proxy(object)); let ensure-function = curry(ensure-server-object, application); values(map(ensure-function, names), map(ensure-function, contents)) end method user-object-slot-values; define method user-object-slot-value (application :: , object :: , id :: , #key repeated-value) => (value :: false-or()) ignore(repeated-value); let proxy = application-object-proxy(object); let (value, success?) = object-slot-value(proxy, id-name(id)); if (success?) ensure-server-object(application, value) end end method user-object-slot-values; /// User object class mapping define method user-object-environment-class (server :: , proxy) => (class :: subclass()) let project = server-project(server); let application = project-application(project); let dummy-object = make(, application-object-proxy: proxy); let object-class = application-object-class(application, dummy-object); lookup-user-object-environment-class(application, object-class) | compute-user-object-environment-class(application, object-class) end method user-object-environment-class; define method lookup-user-object-environment-class (application :: , class :: ) => (user-object-class :: false-or(subclass())) let table = user-object-class-mapping-table(application); element(table, class, default: #f) end method lookup-user-object-environment-class; define method cache-user-object-environment-class (application :: , class :: , user-object-class :: subclass()) => (user-object-class :: subclass()) let table = user-object-class-mapping-table(application); element(table, class) := user-object-class end method cache-user-object-environment-class; define method compute-user-object-environment-class (application :: , class :: ) => (user-object-class :: subclass()) let user-object-class = block (return) for (class-info in user-object-class-mappings()) let class-id = user-class-info-id(class-info); let name = id-name(class-id); let module-id = id-module(class-id); let module-name = id-name(module-id); let library-id = id-library(module-id); let library-name = id-name(library-id); when (user-object-class-subclass? (application, class, name, module-name, library-name)) return(user-class-info-class(class-info)) end end; end; cache-user-object-environment-class(application, class, user-object-class); end method compute-user-object-environment-class; define method user-object-class-subclass? (application :: , class :: , name :: , module :: , library :: ) => (subclass? :: ) ignore(library); let project = find-project(library); let superclass = dylan-variable-value(name, module); if (instance?(superclass, )) subtype?(application-object-proxy(class), superclass) end end method user-object-class-subclass?; /// ID handling define method application-proxy-id (application :: , proxy) => (id :: false-or()) //---*** Fill this in! #f end method application-proxy-id; define method find-application-proxy (application :: , id :: ) => (proxy) //---*** Fill this in! #f end method find-application-proxy; define method compiler-database-proxy-id (database :: , proxy) => (id :: false-or()) //---*** Fill this in! #f end method compiler-database-proxy-id; define method compiler-database-proxy-id (database :: , proxy) => (id :: false-or()) //---*** Fill this in! #f end method compiler-database-proxy-id;