From: Mark Wooding Date: Sun, 30 Aug 2015 09:58:38 +0000 (+0100) Subject: Merge branch 'master' into doc X-Git-Url: https://git.distorted.org.uk/~mdw/sod/commitdiff_plain/1818107e8198734df843841a51bca3713bd37596?hp=54fa70952116ba0eb0f95b31376c925ae3c6dad2 Merge branch 'master' into doc * master: src/parser/parser-expr-impl.lisp: Compare paren tags with `eql'. src/module-impl.lisp: Expose `c-fragment' state. src/lexer-proto.lisp: Export some more symbols. src/pset-proto.lisp (default-slot-from-property): Make `slot-names' optional. src/pset-proto.lisp: Fix export of `check-unused-properties'. src/: Fix some docstrings. --- diff --git a/.gitignore b/.gitignore index 0bf9e54..b841037 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,9 @@ *.out *.log *.dvi +*.toc *.aux +_region_.tex Makefile.in /COPYING /COPYING.LIB @@ -11,4 +13,3 @@ Makefile.in /autom4te.cache/ /config/ /configure -/doc/SYMBOLS diff --git a/doc/SYMBOLS b/doc/SYMBOLS new file mode 100644 index 0000000..a6ae09d --- /dev/null +++ b/doc/SYMBOLS @@ -0,0 +1,1957 @@ +----------------------------------------------------------------------------- +Package `sod' + +pset-proto.lisp + add-property function + check-unused-properties function + coerce-property-value generic + decode-property generic + get-property function + make-property function + make-property-set function + make-pset function + p-key function setf + p-name function setf + p-seenp function setf + p-type function setf + p-value function setf + property class + property-key function + property-set generic + propertyp function + pset class + pset-get function + pset-map function + pset-store function + psetp function + store-property function + with-pset-iterator macro + +pset-parse.lisp + parse-property-set function + +output-proto.lisp + add-sequencer-constraint generic + add-sequencer-item-function generic + ensure-sequencer-item generic + hook-output generic + invoke-sequencer-items generic + make-sequencer-item function + sequence-output macro + sequencer class + sequencer-constraints generic setf + sequencer-item class + sequencer-item-functions function setf + sequencer-item-name function + sequencer-item-p function + sequencer-table generic + +module-proto.lisp + *module* variable + add-clear-the-decks-function function + add-module-binding function + add-to-module generic + clear-the-decks function + define-clear-the-decks macro + define-module macro + define-module-var macro + finalize-module generic + module class + module-dependencies generic setf + module-import generic + module-items generic setf + module-name generic + module-pset generic + with-module-environment macro + with-temporary-module macro + +module-parse.lisp + read-module function + +module-output.lisp + banner function + declare-output-type function + guard-name function + output-module function + output-type-pathname function + +module-impl.lisp + *module-dirs* variable + c-fragment class + c-fragment-text generic setf + code-fragment-item class + find-file function + type-item class + +method-proto.lisp + codegen-class generic + codegen-message generic + codegen-method generic + codegen-target generic + compute-effective-method-body generic + compute-effective-methods generic + compute-method-entry-functions generic + compute-sod-effective-method generic + convert-to-ilayout-inst class + effective-method class + effective-method-basic-argument-names generic + effective-method-class generic + effective-method-function-name generic + effective-method-message generic + ensure-ilayout-var function + inst-chain-head generic + inst-class generic + inst-expr generic + invoke-delegation-chain function + invoke-method function + make-convert-to-ilayout-inst function + make-method-entries generic + make-trampoline function + message-effective-method-class generic + method-codegen class + method-entry class + method-entry-chain-head generic + method-entry-chain-tail generic + method-entry-effective-method generic + method-entry-function-name generic + method-entry-function-type generic + method-entry-slot-name generic + primary-method-class generic + simple-method-body generic + sod-message-argument-tail generic + sod-message-no-varargs-tail generic + sod-method-function-name generic + sod-method-function-type generic + sod-method-next-method-type generic + varargs-message-p function + +method-impl.lisp + basic-direct-method class + basic-effective-method class + basic-effective-method-body function + basic-message class + daemon-direct-method class + delegating-direct-method class + simple-effective-method class + simple-message class + standard-effective-method class + standard-message class + +method-aggregate.lisp + aggregating-effective-method class + aggregating-message class + aggregating-message-properties generic + check-aggregating-message-type generic + compute-aggregating-message-kernel generic + define-aggregating-method-combination macro + +lexer-proto.lisp + define-indicator function + cl:error function class parser + lexer-error function + scan-comment function + skip-until function parser + sod-token-scanner class + syntax-error function + +fragment-parse.lisp + parse-delimited-fragment function + scan-c-fragment function + +final.lisp + *debugout-pathname* variable + *sod-version* variable + exercise function + test-module function + +codegen-proto.lisp + *sod-ap* variable + *sod-master-ap* variable + block-inst class + break-inst class + codegen-add-function generic + codegen-build-function function + codegen-functions generic setf + codegen-pop generic + codegen-pop-block generic + codegen-pop-function generic + codegen-push generic + continue-inst class + convert-stmts function + definst macro + deliver-expr function + emit-decl generic + emit-decls generic + emit-inst generic + emit-insts generic + ensure-var generic + expr-inst class + format-compound-statement macro + format-temporary-name generic + function-inst class + inst class + inst-body generic + inst-decls generic + inst-expr generic + inst-init generic + inst-metric generic + inst-name generic + inst-op generic + inst-type generic + inst-var generic + make-block-inst function + make-break-inst function + make-continue-inst function + make-expr-inst function + make-function-inst function + make-return-inst function + make-set-inst function + make-update-inst function + make-var-inst function + return-inst class + set-inst class + temp-tag generic + temporary-name class + temporary-var generic + update-inst class + var-in-use-p generic setf + var-inst class + with-temporary-var macro + +codegen-impl.lisp + call-inst class + codegen class + do-while-inst class + if-inst class + inst-alt generic + inst-ap generic + inst-arg generic + inst-args generic + inst-body generic + inst-cond generic + inst-conseq generic + inst-from generic + inst-func generic + inst-to generic + make-call-inst function + make-do-while-inst function + make-if-inst function + make-va-copy-inst function + make-va-end-inst function + make-va-start-inst function + make-while-inst function + temporary-argument class + temporary-function function class + temporary-variable class + va-copy-inst class + va-end-inst class + va-start-inst class + while-inst class + +classes.lisp + sod-class class + sod-class-chain generic setf + sod-class-chain-head generic setf + sod-class-chain-link generic + sod-class-chains generic setf + sod-class-class-initializers generic setf + sod-class-direct-superclasses generic + sod-class-ilayout generic setf + sod-class-initializer class + sod-class-instance-initializers generic setf + sod-class-messages generic setf + sod-class-metaclass generic + sod-class-methods generic setf + sod-class-name generic + sod-class-nickname generic + sod-class-precedence-list generic setf + sod-class-slots generic setf + sod-class-state generic setf + sod-class-type generic setf + sod-class-vtables generic setf + sod-initializer class + sod-initializer-class generic + sod-initializer-slot generic + sod-initializer-value-form generic + sod-initializer-value-kind generic + sod-instance-initializer class + sod-message class + sod-message-class generic + sod-message-name generic + sod-message-type generic + sod-method class + sod-method-body generic + sod-method-class generic + sod-method-message generic + sod-method-type generic + sod-slot class + sod-slot-class generic + sod-slot-name generic + sod-slot-type generic + +class-utilities.lisp + argument-lists-compatible-p function + find-class-slot-by-name function + find-instance-slot-by-name function + find-message-by-name function + find-root-metaclass function + find-root-superclass function + find-superclass-by-nick function + ichain-struct-tag function + ichain-union-tag function + ilayout-struct-tag function + islots-struct-tag function + message-macro-name function + sod-subclass-p function + valid-name-p function + vtable-name function + vtable-struct-tag function + vtable-union-tag function + vtmsgs-struct-tag function + +class-make-proto.lisp + check-message-type generic + check-method-type generic + define-sod-class macro + guess-metaclass generic + make-sod-class function + make-sod-class-initializer generic + make-sod-initializer-using-slot generic + make-sod-instance-initializer generic + make-sod-message generic + make-sod-method generic + make-sod-method-using-message generic + make-sod-slot generic + sod-message-method-class generic + +class-layout-proto.lisp + base-offset class + base-offset-chain-head generic + base-offset-class generic + chain-offset class + chain-offset-chain-head generic + chain-offset-class generic + chain-offset-target-head generic + class-pointer class + class-pointer-chain-head generic + class-pointer-class generic + class-pointer-meta-chain-head generic + class-pointer-metaclass generic + compute-effective-slot generic + compute-ichain generic + compute-ilayout generic + compute-islots generic + compute-vtable generic + compute-vtable-items generic + compute-vtables generic + compute-vtmsgs generic + effective-slot class + effective-slot-class generic + effective-slot-direct-slot generic + effective-slot-initializer generic + find-slot-initializer generic + ichain class + ichain-body generic + ichain-class generic + ichain-head generic + ichain-tail generic + ilayout class + ilayout-class generic + ilayout-ichains generic + islots class + islots-class generic + islots-slots generic + islots-subclass generic + make-base-offset generic + make-class-pointer generic + vtable class + vtable-body generic + vtable-chain-head generic + vtable-chain-tail generic + vtable-class generic + vtable-pointer class + vtable-pointer-chain-head generic + vtable-pointer-chain-tail generic + vtable-pointer-class generic + +class-layout-impl.lisp + sod-class-effective-slot class + sod-class-slot class + +c-types-proto.lisp + argument class + argument-name function setf + argument-type function setf + argumentp function + c-name-case function + c-type macro class + c-type-alias macro + c-type-equal-p generic + c-type-qualifiers generic + c-type-space function + c-type-subtype generic + canonify-qualifiers function + commentify-argument-name generic + defctype macro + define-c-type-syntax macro + expand-c-type-form generic + expand-c-type-spec generic + format-qualifiers function + make-argument function + maybe-in-parens macro + pprint-c-type generic + print-c-type generic + qualifiable-c-type class + qualify-c-type generic + +c-types-parse.lisp + parse-c-type function + parse-declarator function + +c-types-impl.lisp + cl:* variable function c-type + cl:array class c-type + c-array-dimensions generic + c-array-type class + c-enum-type class + c-function-arguments generic + c-function-type class + c-pointer-type class + c-struct-type class + c-tagged-type-kind generic + c-type-name generic + c-type-tag generic + c-union-type class + cl:char function setf c-type parser + commentify-argument-names function + commentify-function-type function + const-string c-type + define-simple-c-type macro + double c-type + enum c-type + cl:float function class c-type + fn c-type + fun c-type + func c-type + cl:function function class c-type + int c-type + kind-c-tagged-type generic + llong c-type + long c-type + long-double c-type + long-int c-type + long-long c-type + long-long-int c-type + make-array-type function + make-c-tagged-type function + make-enum-type function + make-function-type function + make-pointer-type function + make-simple-type function + make-struct-type function + make-union-type function + cl:nil constant c-type parser + pointer c-type + ptr c-type + ptrdiff-t c-type + cl:schar function setf c-type + short c-type + short-int c-type + signed c-type + signed-char c-type + signed-int c-type + signed-long c-type + signed-long-int c-type + signed-long-long c-type + signed-long-long-int c-type + signed-short c-type + signed-short-int c-type + simple-c-type class + sint c-type + size-t c-type + sllong c-type + slong c-type + sshort c-type + cl:string function class c-type opthandler + struct c-type + tagged-c-type class + uchar c-type + uint c-type + ullong c-type + ulong c-type + cl:union function c-type + unsigned c-type + unsigned-char c-type + unsigned-int c-type + unsigned-long c-type + unsigned-long-int c-type + unsigned-long-long c-type + unsigned-long-long-int c-type + unsigned-short c-type + unsigned-short-int c-type + ushort c-type + va-list c-type + vec c-type + void c-type + [] c-type + +c-types-class-impl.lisp + c-class-type class + c-type-class generic setf + cl:class class c-type + find-class-type function + find-sod-class function + make-class-type function + record-sod-class function + +builtin.lisp + *builtin-module* variable + make-builtin-module function + +Classes: +cl:t + sb-pcl::slot-object + cl:standard-object + base-offset + sod::basic-codegen + codegen + method-codegen + c-fragment + c-type + c-array-type + c-function-type + qualifiable-c-type + c-pointer-type + simple-c-type + c-class-type + tagged-c-type + c-enum-type + c-struct-type + c-union-type + chain-offset + class-pointer + code-fragment-item + sb-pcl::definition-source-mixin + cl:class [sb-pcl::dependent-update-mixin sb-pcl::standard-specializer] + effective-method + basic-effective-method + simple-effective-method + aggregating-effective-method + standard-effective-method + effective-slot + sod-class-effective-slot + ichain + ilayout + inst + block-inst + break-inst + call-inst + continue-inst + convert-to-ilayout-inst + do-while-inst + expr-inst + function-inst + if-inst + return-inst + set-inst + update-inst + va-copy-inst + va-end-inst + va-start-inst + var-inst + while-inst + islots + sb-mop:metaobject + sb-mop:specializer + sb-pcl::standard-specializer + cl:class [sb-pcl::dependent-update-mixin sb-pcl::definition-source-mixin] + method-entry + module + sb-pcl::plist-mixin + sb-pcl::dependent-update-mixin + cl:class [sb-pcl::definition-source-mixin sb-pcl::standard-specializer] + sequencer + sod-class + sod-initializer + sod-class-initializer + sod-instance-initializer + sod-message + basic-message + simple-message + aggregating-message + standard-message + sod-method + basic-direct-method + daemon-direct-method + delegating-direct-method + sod-slot + sod-class-slot + temporary-name + temporary-argument + temporary-function + temporary-variable + sod-parser:token-scanner + sod-token-scanner + type-item + vtable + vtable-pointer + cl:structure-object + argument + property + pset + sequencer-item + +Methods: +add-sequencer-constraint + sequencer cl:list +add-sequencer-item-function + sequencer t t +add-to-module + module t +aggregating-message-properties + aggregating-message (eql :custom) + t t +base-offset-chain-head + base-offset +base-offset-class + base-offset +c-array-dimensions + c-array-type +c-fragment-text + c-fragment +(setf c-fragment-text) + t c-fragment +c-function-arguments + c-function-type +c-tagged-type-kind + c-union-type + c-struct-type + c-enum-type +c-type-class + c-class-type +(setf c-type-class) + t c-class-type +c-type-equal-p + c-class-type c-class-type + c-function-type c-function-type + c-array-type c-array-type + c-pointer-type c-pointer-type + tagged-c-type tagged-c-type + simple-c-type simple-c-type + qualifiable-c-type qualifiable-c-type + t t +c-type-name + simple-c-type +c-type-qualifiers + qualifiable-c-type +c-type-subtype + c-function-type + c-array-type + c-pointer-type +c-type-tag + tagged-c-type +chain-offset-chain-head + chain-offset +chain-offset-class + chain-offset +chain-offset-target-head + chain-offset +check-aggregating-message-type + aggregating-message (eql :or) c-function-type + aggregating-message (eql :and) c-function-type + aggregating-message (eql :progn) c-function-type + t t t +check-message-type + aggregating-message t + sod-message c-type + sod-message c-function-type +check-method-type + daemon-direct-method sod-message c-function-type + sod-method sod-message c-function-type + sod-method sod-message c-type +class-pointer-chain-head + class-pointer +class-pointer-class + class-pointer +class-pointer-meta-chain-head + class-pointer +class-pointer-metaclass + class-pointer +codegen-add-function + codegen t +codegen-class + method-codegen +codegen-functions + codegen +(setf codegen-functions) + t codegen +codegen-message + method-codegen +codegen-method + method-codegen +codegen-pop + codegen +codegen-pop-block + t +codegen-pop-function + t t t +codegen-push + codegen +codegen-target + method-codegen +coerce-property-value + cl:symbol (eql :symbol) (eql :id) + cl:string (eql :string) (eql :id) + cl:string (eql :string) (eql :symbol) + cl:string (eql :id) (eql :symbol) + cl:string (eql :string) (eql :keyword) + cl:string (eql :id) (eql :keyword) + cl:symbol (eql :symbol) (eql :keyword) + t t t + t t (eql cl:t) +commentify-argument-name + temporary-name + cl:null + t +compute-aggregating-message-kernel + aggregating-message (eql :custom) t t t t + aggregating-message (eql :or) t t t t + aggregating-message (eql :and) t t t t + aggregating-message (eql :max) t t t t + aggregating-message (eql :min) t t t t + aggregating-message (eql :product) t t t t + aggregating-message (eql :sum) t t t t + aggregating-message (eql :progn) t t t t +compute-effective-method-body + simple-effective-method t t +compute-effective-methods + sod-class +compute-effective-slot + sod-class sod-class-slot + sod-class sod-slot +compute-ichain + sod-class t +compute-ilayout + sod-class +compute-islots + sod-class sod-class +compute-method-entry-functions + simple-effective-method + basic-effective-method +compute-sod-effective-method + sod-message sod-class +compute-vtable + sod-class cl:list +compute-vtable-items + sod-class sod-class sod-class sod-class cl:function +compute-vtables + sod-class +compute-vtmsgs + sod-class sod-class sod-class sod-class +decode-property + cl:symbol + cl:integer + cl:string + cl:character + property + cl:cons + cl:function +effective-method-basic-argument-names + basic-effective-method +effective-method-class + effective-method +effective-method-function-name + effective-method +effective-method-message + effective-method +effective-slot-class + effective-slot +effective-slot-direct-slot + effective-slot +effective-slot-initializer + effective-slot +emit-decl + sod::basic-codegen t +emit-decls + sod::basic-codegen t +emit-inst + sod::basic-codegen t +emit-insts + sod::basic-codegen t + t t +ensure-sequencer-item + sequencer t +ensure-var + sod::basic-codegen t t +expand-c-type-form + (eql cl:class) t + (eql fn) t + (eql func) t + (eql cl:nil) t + (eql cl:function) t + (eql fun) t + (eql vec) t + (eql cl:array) t + (eql []) t + (eql ptr) t + (eql pointer) t + (eql cl:*) t + (eql cl:union) t + (eql struct) t + (eql enum) t + (eql ptrdiff-t) t + (eql size-t) t + (eql va-list) t + (eql long-double) t + (eql double) t + (eql cl:float) t + (eql unsigned-long-long) t + (eql long-long) t + (eql unsigned-long) t + (eql long) t + (eql unsigned-short) t + (eql short) t + (eql unsigned) t + (eql int) t + (eql signed-char) t + (eql unsigned-char) t + (eql cl:char) t + (eql void) t + cl:string t + (eql sod-parser:lisp) t +expand-c-type-spec + (eql const-string) + (eql cl:string) + (eql ptrdiff-t) + (eql size-t) + (eql va-list) + (eql long-double) + (eql double) + (eql cl:float) + (eql ullong) + (eql unsigned-long-long-int) + (eql unsigned-long-long) + (eql sllong) + (eql llong) + (eql signed-long-long-int) + (eql long-long-int) + (eql signed-long-long) + (eql long-long) + (eql ulong) + (eql unsigned-long-int) + (eql unsigned-long) + (eql slong) + (eql signed-long-int) + (eql long-int) + (eql signed-long) + (eql long) + (eql ushort) + (eql unsigned-short-int) + (eql unsigned-short) + (eql sshort) + (eql signed-short-int) + (eql short-int) + (eql signed-short) + (eql short) + (eql uint) + (eql unsigned-int) + (eql unsigned) + (eql sint) + (eql signed-int) + (eql signed) + (eql int) + (eql cl:schar) + (eql signed-char) + (eql uchar) + (eql unsigned-char) + (eql cl:char) + (eql void) + cl:string + cl:list +sod-parser:file-location + property + sod-method + sod-message + sod-initializer + sod-slot + sod-class +finalize-module + module +find-slot-initializer + sod-class sod-slot +format-temporary-name + temporary-function t + temporary-variable t + temporary-argument t + temporary-name t +guess-metaclass + sod-class +hook-output + effective-slot (eql cl:class) t + sod-class-effective-slot (eql cl:class) t + vtable-pointer (eql cl:class) t + islots (eql cl:class) t + ichain (eql cl:class) t + method-entry (eql :c) t + sod::vtmsgs (eql :c) t + chain-offset (eql :c) t + base-offset (eql :c) t + class-pointer (eql :c) t + vtable (eql :c) t + basic-effective-method (eql :c) t + sod-method (eql :c) t + delegating-direct-method (eql :c) t + sod-class (eql :c) t + chain-offset (eql :h) t + base-offset (eql :h) t + class-pointer (eql :h) t + method-entry (eql sod::vtmsgs) t + sod::vtmsgs t t + sod::vtmsgs (eql sod::vtmsgs) t + sod::vtmsgs (eql :h) t + vtable (eql :h) t + sod-method (eql :h) t + vtable t t + islots (eql :h) t + islots t t + vtable-pointer (eql :h) t + ichain (eql ilayout) t + ichain (eql :h) t + ilayout (eql :h) t + ichain t t + ilayout t t + sod-slot (eql islots) t + sod-class t t + sod-class (eql :h) t + module (eql :c) t + module (eql :h) t + code-fragment-item t t + module t t + t t t +ichain-body + ichain +ichain-class + ichain +ichain-head + ichain +ichain-tail + ichain +ilayout-class + ilayout +ilayout-ichains + ilayout +inst-alt + if-inst +inst-ap + va-end-inst + va-start-inst +inst-arg + va-start-inst +inst-args + call-inst +inst-body + do-while-inst + while-inst + function-inst + block-inst +inst-chain-head + convert-to-ilayout-inst +inst-class + convert-to-ilayout-inst +inst-cond + do-while-inst + while-inst + if-inst +inst-conseq + if-inst +inst-decls + block-inst +inst-expr + convert-to-ilayout-inst + expr-inst + return-inst + update-inst + set-inst +inst-from + va-copy-inst +inst-func + call-inst +inst-init + var-inst +inst-metric + convert-to-ilayout-inst + call-inst + va-end-inst + va-copy-inst + va-start-inst + do-while-inst + while-inst + if-inst + function-inst + block-inst + expr-inst + continue-inst + break-inst + return-inst + update-inst + set-inst + var-inst + t + cl:null + cl:list +inst-name + function-inst + var-inst +inst-op + update-inst +inst-to + va-copy-inst +inst-type + function-inst + var-inst +inst-var + update-inst + set-inst +invoke-sequencer-items + sequencer +islots-class + islots +islots-slots + islots +islots-subclass + islots +kind-c-tagged-type + (eql :union) + (eql :struct) + (eql :enum) +make-base-offset + sod-class sod-class +make-class-pointer + sod-class sod-class sod-class sod-class +cl:make-load-form + c-fragment +make-method-entries + basic-effective-method sod-class sod-class +sod-parser:make-scanner-stream + sod-token-scanner +make-sod-class-initializer + sod-class t t t t t +make-sod-initializer-using-slot + sod-class sod-slot t t t t t +make-sod-instance-initializer + sod-class t t t t t +make-sod-message + sod-class t t t +make-sod-method + sod-class t t t t t +make-sod-method-using-message + sod-message sod-class t t t t +make-sod-slot + sod-class t t t +message-effective-method-class + aggregating-message + standard-message +method-entry-chain-head + method-entry +method-entry-chain-tail + method-entry +method-entry-effective-method + method-entry +method-entry-function-name + effective-method sod-class t +method-entry-function-type + method-entry +method-entry-slot-name + method-entry +module-dependencies + module +(setf module-dependencies) + t module +module-import + sod-class + type-item + module + t +module-items + module +(setf module-items) + t module +module-name + module +module-pset + module +pprint-c-type + c-function-type t t + c-array-type t t + c-pointer-type t t + tagged-c-type t t + simple-c-type t t + t t t +primary-method-class + standard-message + simple-message +print-c-type + t c-class-type + t c-function-type + t c-array-type + t c-pointer-type + t tagged-c-type + t simple-c-type +cl:print-object + vtable t + chain-offset t + base-offset t + class-pointer t + ilayout t + ichain t + vtable-pointer t + islots t + method-entry t + effective-method t + effective-slot t + convert-to-ilayout-inst t + sequencer-item t + c-fragment t + call-inst t + va-end-inst t + va-copy-inst t + va-start-inst t + do-while-inst t + while-inst t + if-inst t + temporary-name t + function-inst t + block-inst t + expr-inst t + continue-inst t + break-inst t + return-inst t + update-inst t + set-inst t + var-inst t + pset t + sod-method t + sod-message t + sod-initializer t + sod-slot t + sod-class t + c-type t +property-set + pset + cl:list +qualify-c-type + qualifiable-c-type t +sod-parser:scanner-token + sod-token-scanner +sequencer-constraints + sequencer +(setf sequencer-constraints) + t sequencer +sequencer-table + sequencer +cl:shared-initialize + aggregating-message t + method-codegen t + simple-effective-method t + basic-direct-method t + sod-class-slot t + sod-method t + sod-message t + sod-initializer t + sod-slot t + sod-class t + module t + c-function-type t + sod-token-scanner t +simple-method-body + aggregating-effective-method t t + standard-effective-method t t +cl:slot-unbound + t basic-effective-method (eql sod::functions) + t basic-effective-method (eql sod::basic-argument-names) + t delegating-direct-method (eql sod::function-type) + t delegating-direct-method (eql sod::next-method-type) + t basic-direct-method (eql sod::function-type) + t basic-message (eql sod::no-varargs-tail) + t basic-message (eql sod::argument-tail) + t sod-class (eql sod::vtables) + t sod-class (eql sod::effective-methods) + t sod-class (eql sod::%ilayout) +sod-class-chain + sod-class +(setf sod-class-chain) + t sod-class +sod-class-chain-head + sod-class +(setf sod-class-chain-head) + t sod-class +sod-class-chain-link + sod-class +sod-class-chains + sod-class +(setf sod-class-chains) + t sod-class +sod-class-class-initializers + sod-class +(setf sod-class-class-initializers) + t sod-class +sod-class-direct-superclasses + sod-class +sod-class-ilayout + sod-class +(setf sod-class-ilayout) + t sod-class +sod-class-instance-initializers + sod-class +(setf sod-class-instance-initializers) + t sod-class +sod-class-messages + sod-class +(setf sod-class-messages) + t sod-class +sod-class-metaclass + sod-class +sod-class-methods + sod-class +(setf sod-class-methods) + t sod-class +sod-class-name + sod-class +sod-class-nickname + sod-class +sod-class-precedence-list + sod-class +(setf sod-class-precedence-list) + t sod-class +sod-class-slots + sod-class +(setf sod-class-slots) + t sod-class +sod-class-state + sod-class +(setf sod-class-state) + t sod-class +sod-class-type + sod-class +(setf sod-class-type) + t sod-class +sod-class-vtables + sod-class +(setf sod-class-vtables) + t sod-class +sod-initializer-class + sod-initializer +sod-initializer-slot + sod-initializer +sod-initializer-value-form + sod-initializer +sod-initializer-value-kind + sod-initializer +sod-message-argument-tail + basic-message +sod-message-class + sod-message +sod-message-method-class + simple-message sod-class t + basic-message sod-class t + sod-message sod-class t +sod-message-name + sod-message +sod-message-no-varargs-tail + basic-message +sod-message-type + sod-message +sod-method-body + sod-method +sod-method-class + sod-method +sod-method-function-name + basic-direct-method +sod-method-function-type + basic-direct-method +sod-method-message + sod-method +sod-method-next-method-type + delegating-direct-method +sod-method-type + sod-method +sod-slot-class + sod-slot +sod-slot-name + sod-slot +sod-slot-type + sod-slot +temp-tag + temporary-name +temporary-var + sod::basic-codegen t +var-in-use-p + temporary-variable + t +(setf var-in-use-p) + t temporary-variable +vtable-body + vtable +vtable-chain-head + vtable +vtable-chain-tail + vtable +vtable-class + vtable +vtable-pointer-chain-head + vtable-pointer +vtable-pointer-chain-tail + vtable-pointer +vtable-pointer-class + vtable-pointer + +----------------------------------------------------------------------------- +Package `sod-frontend' + +frontend.lisp + main function + +Classes: +cl:t + +Methods: + +----------------------------------------------------------------------------- +Package `sod-parser' + +floc-proto.lisp + cerror* function + cerror*-with-location function + cerror-with-location function + condition-with-location class + count-and-report-errors macro + enclosed-condition generic + enclosing-condition class + enclosing-condition-with-location class + enclosing-error-with-location class + enclosing-warning-with-location class + error-with-location function class + file-location generic class + file-location-column function + file-location-filename function + file-location-line function + file-location-p function + make-condition-with-location function + make-file-location function + simple-condition-with-location class + simple-error-with-location class + simple-warning-with-location class + warn-with-location function + warning-with-location class + with-default-error-location macro + +parser-expr-proto.lisp + apply-operator generic + binop macro + close-parenthesis class + expr parser + lparen function + open-parenthesis class + operator-left-precedence generic + operator-push-action generic + operator-right-precedence generic + postop macro + prefix-operator class + preop macro + push-operator generic + push-value generic + rparen function + simple-binary-operator class + simple-operator class + simple-postfix-operator class + simple-prefix-operator class + simple-unary-operator class + +parser-impl.lisp + list-parser class + string-parser class + +parser-proto.lisp + ? parser + cl:and macro parser + call-pluggable-parser function + cl:char function setf c-type parser + character-parser-context class + combine-parser-failures function + cond-parse macro + define-pluggable-parser macro + defparse macro + expand-parser-form generic + expand-parser-spec generic + filter parser + if-char parser + if-parse macro + sod-utilities:it + label parser + lisp c-type parser + cl:list function class parser opthandler + many parser + cl:not function parser + cl:or macro parser + parse + parser macro + parser-at-eof-p generic + parser-capture-place generic + parser-current-char generic + parser-places-must-be-released-p generic + parser-release-place generic + parser-restore-place generic + parser-step generic + parser-token-type generic + parser-token-value generic + peek parser + plug parser + pluggable-parser-add function + cl:satisfies parser + seq parser + skip-many parser + token parser + token-parser-context class + when-parse macro + with-parser-context macro + with-parser-place macro + wrap-parser generic + +scanner-charbuf-impl.lisp + charbuf-scanner class + charbuf-scanner-map generic + charbuf-scanner-place-p function + charbuf-scanner-stream class + +scanner-impl.lisp + list-scanner class + list-scanner-p function + make-list-scanner function + make-string-scanner function + string-scanner class + string-scanner-p function + +scanner-proto.lisp + character-scanner class + character-scanner-context class + character-scanner-stream class + make-scanner-stream generic + parser-scanner generic + scanner-at-eof-p generic + scanner-capture-place generic + scanner-column generic setf + scanner-context class + scanner-current-char generic + scanner-filename generic + scanner-interval generic + scanner-line generic setf + scanner-release-place generic + scanner-restore-place generic + scanner-step generic + scanner-token generic + scanner-unread generic + token-scanner class + token-scanner-context class + token-scanner-place class + token-scanner-place-p function + token-type generic + token-value generic + with-scanner-place macro + +streams-impl.lisp + position-aware-input-stream class + position-aware-output-stream class + position-aware-stream class + position-aware-stream-column generic setf + position-aware-stream-line generic setf + +streams-proto.lisp + stream-pathname generic + +Classes: +cl:t + sb-pcl::slot-object + cl:standard-object + character-parser-context + character-scanner-context [scanner-context] + string-parser + character-scanner + charbuf-scanner + sb-gray:fundamental-stream [cl:stream] + sb-gray:fundamental-character-stream + sb-gray:fundamental-character-input-stream [sb-gray:fundamental-input-stream] + character-scanner-stream + charbuf-scanner-stream + sod-parser::proxy-character-input-stream [sod-parser::proxy-input-stream] + position-aware-input-stream [position-aware-stream] + sb-gray:fundamental-character-output-stream [sb-gray:fundamental-output-stream] + sod-parser::proxy-character-output-stream [sod-parser::proxy-stream] + position-aware-output-stream [position-aware-stream] + sb-gray:fundamental-input-stream + sb-gray:fundamental-character-input-stream [sb-gray:fundamental-character-stream] + character-scanner-stream + charbuf-scanner-stream + sod-parser::proxy-character-input-stream [sod-parser::proxy-input-stream] + position-aware-input-stream [position-aware-stream] + sod-parser::proxy-input-stream [sod-parser::proxy-stream] + sod-parser::proxy-character-input-stream [sb-gray:fundamental-character-input-stream] + position-aware-input-stream [position-aware-stream] + sb-gray:fundamental-output-stream + sb-gray:fundamental-character-output-stream [sb-gray:fundamental-character-stream] + sod-parser::proxy-character-output-stream [sod-parser::proxy-stream] + position-aware-output-stream [position-aware-stream] + sod-parser::proxy-stream + position-aware-stream + position-aware-input-stream [sod-parser::proxy-character-input-stream] + position-aware-output-stream [sod-parser::proxy-character-output-stream] + sod-parser::proxy-character-output-stream [sb-gray:fundamental-character-output-stream] + position-aware-output-stream [position-aware-stream] + sod-parser::proxy-input-stream [sb-gray:fundamental-input-stream] + sod-parser::proxy-character-input-stream [sb-gray:fundamental-character-input-stream] + position-aware-input-stream [position-aware-stream] + list-parser + sod-parser::parenthesis + close-parenthesis + open-parenthesis [prefix-operator] + prefix-operator + open-parenthesis [sod-parser::parenthesis] + simple-prefix-operator [simple-unary-operator] + scanner-context + character-scanner-context [character-parser-context] + token-scanner-context [token-parser-context] + simple-operator + simple-binary-operator + simple-unary-operator + simple-postfix-operator + simple-prefix-operator [prefix-operator] + token-parser-context + token-scanner-context [scanner-context] + token-scanner + cl:structure-object + file-location + list-scanner + string-scanner + token-scanner-place + cl:stream + sb-gray:fundamental-stream [cl:standard-object] + sb-gray:fundamental-character-stream + sb-gray:fundamental-character-input-stream [sb-gray:fundamental-input-stream] + character-scanner-stream + charbuf-scanner-stream + sod-parser::proxy-character-input-stream [sod-parser::proxy-input-stream] + position-aware-input-stream [position-aware-stream] + sb-gray:fundamental-character-output-stream [sb-gray:fundamental-output-stream] + sod-parser::proxy-character-output-stream [sod-parser::proxy-stream] + position-aware-output-stream [position-aware-stream] + sb-gray:fundamental-input-stream + sb-gray:fundamental-character-input-stream [sb-gray:fundamental-character-stream] + character-scanner-stream + charbuf-scanner-stream + sod-parser::proxy-character-input-stream [sod-parser::proxy-input-stream] + position-aware-input-stream [position-aware-stream] + sod-parser::proxy-input-stream [sod-parser::proxy-stream] + sod-parser::proxy-character-input-stream [sb-gray:fundamental-character-input-stream] + position-aware-input-stream [position-aware-stream] + sb-gray:fundamental-output-stream + sb-gray:fundamental-character-output-stream [sb-gray:fundamental-character-stream] + sod-parser::proxy-character-output-stream [sod-parser::proxy-stream] + position-aware-output-stream [position-aware-stream] + sod-parser::proxy-stream + position-aware-stream + position-aware-input-stream [sod-parser::proxy-character-input-stream] + position-aware-output-stream [sod-parser::proxy-character-output-stream] + sod-parser::proxy-character-output-stream [sb-gray:fundamental-character-output-stream] + position-aware-output-stream [position-aware-stream] + sod-parser::proxy-input-stream [sb-gray:fundamental-input-stream] + sod-parser::proxy-character-input-stream [sb-gray:fundamental-character-input-stream] + position-aware-input-stream [position-aware-stream] + +Methods: +apply-operator + open-parenthesis sod-parser::expression-parse-state + simple-binary-operator sod-parser::expression-parse-state + simple-unary-operator sod-parser::expression-parse-state +charbuf-scanner-map + charbuf-scanner t +enclosed-condition + enclosing-condition +expand-parser-form + token-scanner-context (eql cl:error) t + token-scanner-context (eql sod:skip-until) t + t (eql expr) t + list-parser (eql cl:type) t + list-parser (eql cl:quote) t + token-parser-context (eql token) t + character-parser-context (eql filter) t + character-parser-context (eql cl:not) t + character-parser-context (eql cl:satisfies) t + character-parser-context (eql cl:char) t + character-parser-context (eql if-char) t + t (eql peek) t + t (eql plug) t + t (eql ?) t + t (eql cl:or) t + t (eql skip-many) t + t (eql cl:list) t + t (eql many) t + t (eql lisp) t + t (eql cl:and) t + t (eql seq) t + t (eql cl:when) t + t (eql cl:nil) t + t (eql cl:t) t + t (eql label) t + t t t +expand-parser-spec + list-parser t + token-parser-context cl:string + token-parser-context t + character-parser-context cl:string + character-parser-context (eql :whitespace) + character-parser-context cl:character + character-parser-context (eql :any) + t (eql cl:nil) + t (eql cl:t) + t (eql :eof) + t cl:list +file-location + sod:property + sod:sod-method + sod:sod-message + sod:sod-initializer + sod:sod-slot + sod:sod-class + token-scanner-place + sod-parser::charbuf-scanner-place + token-scanner + character-scanner + position-aware-stream + cl:stream + t + condition-with-location + file-location +cl:make-load-form + file-location +make-scanner-stream + sod:sod-token-scanner + charbuf-scanner + string-scanner + character-scanner +operator-left-precedence + simple-postfix-operator + simple-binary-operator +operator-push-action + open-parenthesis t + t open-parenthesis + t t +operator-right-precedence + simple-prefix-operator + simple-postfix-operator + simple-binary-operator +parser-at-eof-p + scanner-context + string-parser + list-parser + token-parser-context +parser-capture-place + scanner-context + string-parser + list-parser + t +parser-current-char + character-scanner-context + string-parser +parser-places-must-be-released-p + sod-parser::list-scanner-context + sod-parser::string-scanner-context + string-parser + list-parser + t +parser-release-place + scanner-context t + t t +parser-restore-place + scanner-context t + string-parser t + list-parser t +parser-scanner + scanner-context +parser-step + scanner-context + string-parser +parser-token-type + token-scanner-context +parser-token-value + token-scanner-context +position-aware-stream-column + position-aware-stream +(setf position-aware-stream-column) + t position-aware-stream +position-aware-stream-line + position-aware-stream +(setf position-aware-stream-line) + t position-aware-stream +cl:print-object + simple-operator t + file-location t +push-operator + close-parenthesis sod-parser::expression-parse-state + open-parenthesis sod-parser::expression-parse-state + prefix-operator sod-parser::expression-parse-state + t sod-parser::expression-parse-state +push-value + t sod-parser::expression-parse-state +scanner-at-eof-p + token-scanner + charbuf-scanner + list-scanner + string-scanner +scanner-capture-place + token-scanner + charbuf-scanner + list-scanner + string-scanner + t +scanner-column + charbuf-scanner + token-scanner + t +(setf scanner-column) + t token-scanner +scanner-current-char + charbuf-scanner + string-scanner +scanner-filename + charbuf-scanner + token-scanner + t +scanner-interval + charbuf-scanner t + string-scanner t +scanner-line + charbuf-scanner + token-scanner + t +(setf scanner-line) + t token-scanner +scanner-release-place + token-scanner t + charbuf-scanner t + t t +scanner-restore-place + token-scanner t + charbuf-scanner t + list-scanner t + string-scanner t +scanner-step + token-scanner + charbuf-scanner + list-scanner + string-scanner +scanner-token + sod:sod-token-scanner +scanner-unread + charbuf-scanner t +cl:shared-initialize + simple-binary-operator t + token-scanner t + charbuf-scanner t +sb-gray:stream-line-column + position-aware-output-stream +stream-pathname + position-aware-stream + sod-parser::proxy-stream + cl:stream + cl:file-stream +sb-gray:stream-peek-char + character-scanner-stream +sb-gray:stream-read-char + character-scanner-stream + position-aware-input-stream +sb-gray:stream-read-line + charbuf-scanner-stream + position-aware-input-stream +sb-gray:stream-read-sequence + charbuf-scanner-stream cl:string + position-aware-input-stream t +sb-gray:stream-start-line-p + position-aware-output-stream +sb-gray:stream-terpri + position-aware-output-stream +sb-gray:stream-unread-char + character-scanner-stream t + position-aware-input-stream t +sb-gray:stream-write-char + position-aware-output-stream t +sb-gray:stream-write-sequence + position-aware-output-stream t +sb-gray:stream-write-string + position-aware-output-stream t +token-type + list-scanner + token-scanner +token-value + list-scanner + token-scanner +wrap-parser + string-parser t + t t + +----------------------------------------------------------------------------- +Package `optparse' + +optparse.lisp + *command-line* variable + *help* variable + *options* variable + *program-name* variable + *usage* variable + *version* variable + clear opthandler + dec opthandler + define-program function + defopthandler macro + defoptmacro macro + die function + die-usage function + do-options macro + do-usage function + exit function + help-options optmacro + inc opthandler + int opthandler + invoke-option-handler function + cl:keyword opthandler + cl:list function class parser opthandler + make-option function + make-option-parser function + moan function + op-long-only-p function setf + op-negated-numeric-p function setf + op-negated-p function setf + op-non-option function setf + op-numeric-p function setf + op-options function setf + opt-arg-name function setf + opt-arg-optional-p function setf + opt-documentation function setf + opt-long-name function setf + opt-negated-tag function setf + opt-short-name function setf + opt-tag function setf + option class + option-parse-error function class + option-parse-next function + option-parse-remainder function + option-parse-return function + option-parse-try macro + option-parser class + option-parser-p function + optionp function + options macro + parse-option-form function + cl:read function opthandler + sanity-check-option-list function + cl:set function opthandler + set-command-line-arguments function + show-help function + show-usage function + simple-usage function + cl:string function class c-type opthandler + with-unix-error-reporting macro + +Leaked slot names: cl:documentation, options + option: cl:documentation + option-parser: options + +Classes: +cl:t + sb-pcl::slot-object + cl:structure-object + option + option-parser + +Methods: +cl:print-object + option t + +----------------------------------------------------------------------------- +Package `sod-utilities' + +utilities.lisp + acase macro + acond macro + aecase macro + aetypecase macro + aif macro + asetf macro + atypecase macro + awhen macro + backtrack-position function + categorize macro + compose function + copy-instance function + copy-instance-using-class generic + default-slot macro + define-access-wrapper macro + define-on-demand-slot macro + dosequence macro + sb-mop:eql-specializer class + sb-mop:eql-specializer-object generic + frob-identifier function + sb-mop:generic-function-methods generic setf + inconsistent-merge-error class + instance-initargs generic + it + lbuild-add function + lbuild-add-list function + lbuild-list function + loc class + locf macro + locp function + make-list-builder function + mappend function + maybe-print-unreadable-object macro + merge-error-candidates generic + merge-lists function + sb-mop:method-specializers generic + once-only macro + parse-body function + ref function setf + symbolicate function + update-position function + whitespace-char-p function + with-gensyms macro + with-locatives macro + +Classes: +cl:t + sb-pcl::slot-object + cl:standard-object + sb-mop:metaobject + sb-mop:specializer + sb-pcl::exact-class-specializer + sb-mop:eql-specializer [sb-pcl::standard-specializer sb-pcl::specializer-with-object] + sb-pcl::specializer-with-object + sb-mop:eql-specializer [sb-pcl::standard-specializer sb-pcl::exact-class-specializer] + sb-pcl::standard-specializer + sb-mop:eql-specializer [sb-pcl::exact-class-specializer sb-pcl::specializer-with-object] + cl:structure-object + loc + +Methods: +copy-instance-using-class + cl:standard-class t +sb-mop:eql-specializer-object + sb-mop:eql-specializer +sb-mop:generic-function-methods + cl:standard-generic-function +(setf sb-mop:generic-function-methods) + t cl:standard-generic-function +instance-initargs + cl:standard-object +merge-error-candidates + inconsistent-merge-error +sb-mop:method-specializers + cl:standard-method + diff --git a/doc/sod-protocol.tex b/doc/clang.tex similarity index 52% rename from doc/sod-protocol.tex rename to doc/clang.tex index f0bd115..52e330d 100644 --- a/doc/sod-protocol.tex +++ b/doc/clang.tex @@ -1,13 +1,13 @@ %%% -*-latex-*- %%% -%%% Description of the internal class structure and protocol +%%% C language utilities %%% -%%% (c) 2009 Straylight/Edgeware +%%% (c) 2015 Straylight/Edgeware %%% %%%----- Licensing notice --------------------------------------------------- %%% -%%% This file is part of the Simple Object Definition system. +%%% This file is part of the Sensble Object Design, an object system for C. %%% %%% SOD is free software; you can redistribute it and/or modify %%% it under the terms of the GNU General Public License as published by @@ -23,167 +23,26 @@ %%% along with SOD; if not, write to the Free Software Foundation, %%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -\chapter{Protocol overview} \label{ch:proto} - -This chapter provides an overview of the Sod translator's internal object -model. It describes most of the important classes and generic functions, how -they are used to build a model of a Sod module and produce output code, and -how an extension might modify the translator's behaviour. - -I assume familiarity with the Common Lisp Object System (CLOS). Familiarity -with the CLOS Metaobject Protocol isn't necessary but may be instructive. - -%%%-------------------------------------------------------------------------- -\section{A tour through the translator} - -At the very highest level, the Sod translator works in two phases: it -\emph{parses} source files into an internal representation, and then it -\emph{generates} output files from the internal representation. - -The function @|read-module| is given a pathname for a file: it opens the -file, parses the program text, and returns a @|module| instance describing -the classes and other items found. - -At the other end, the main output function is @|output-module|, which is -given a module, an output stream and a - - -%%%-------------------------------------------------------------------------- -\section{Specification conventions} \label{sec:proto.conventions} - -Throughout this specification, the phrase `it is an error' indicates that a -particular circumstance is erroneous and results in unspecified and possibly -incorrect behaviour. In particular, the situation need not be immediately -diagnosed, and the consequences may be far-reaching. - -The following conventions apply throughout this specification. - -\begin{itemize} - -\item If a specification describes an argument as having a particular type or - syntax, then it is an error to provide an argument not having that - particular type or syntax. - -\item If a specification describes a function then that function might be - implemented as a generic function; it is an error to attempt to (re)define - it as a generic function, or to attempt to add methods to it. A function - specified as being a generic function will certainly be so; if user methods - are permitted on the generic function then this will be specified. - -\item Where a class precedence list is specified, either explicitly or - implicitly by a class hierarchy, the implementation may include additional - superclasses not specified here. Such additional superclasses will not - affect the order of specified classes in the class precedence lists either - of specified classes themselves or of user-defined subclasses of specified - classes. - -\item Unless otherwise specified, generic functions use the standard method - combination. - -\item The specifications for methods are frequently brief; they should be - read in conjunction with and in the context of the specification for the - generic function and specializing classes, if any. - -\item An object $o$ is a \emph{direct instance} of a class $c$ if @|(eq - (class-of $o$) $c$)|; $o$ is an \emph{instance} of $c$ if it is a direct - instance of any subclass of $c$. - -\item If a class is specified as being \emph{abstract} then it is an error to - construct direct instances of it, e.g., using @|make-instance|. - -\item If an object is specified as being \emph{immutable} then it is an error - to mutate it, e.g., using @|(setf (slot-value \ldots) \ldots)|. Programs - may rely on immutable objects retaining their state. - -\item A value is \emph{fresh} if it is guaranteed to be not @|eql| to any - previously existing value. - -\item Unless otherwise specified, it is an error to change the class of an - instance of any class described here; and it is an error to change the - class of an object to a class described here. - -\end{itemize} - -\subsection{Format of the entries} \label{sec:proto.conventions.format} - -Most symbols defined by the protocol have their own entries. An entry begins -with a header line, showing a synopsis of the symbol on the left, and the -category (function, class, macro, etc.) on the right. - -\begin{describe}{fun}{example-function @ - \&optional @ - \&rest @ - \&key :keyword} - The synopsis for a function, generic function or method describes the - function's lambda-list using the usual syntax. Note that keyword arguments - are shown by naming their keywords; in the description, the value passed - for the keyword argument @|keyword| is shown as @. - - For a method, specializers are shown using the usual @|defmethod| syntax, - e.g., - \begin{quote} - some-generic-function ((@ list) @) - \end{quote} -\end{describe} - -\begin{describe}{mac}{example-macro - ( @{ @ @! (@ @
) @}^* ) \\ \push - @[[ @^* @! @ @]] \\ - @^*} - The synopsis for a macro describes the acceptable syntax using the - following notation. - \begin{itemize} - \item Literal symbols, e.g., keywords and parenthesis, are shown in - @|monospace|. - \item Metasyntactic variables are shown in @. - \item Items are grouped together by braces `@{ $\dots$ @}'. The notation - `@{ $\dots$ @}^*' indicates that the enclosed items may be repeated zero - or more times; `@{ $\dots$ @}^+' indicates that the enclosed items may be - repeated one or more times. This notation may be applied to a single - item without the braces. - \item Optional items are shown enclosed in brackets `@[ $\dots$ @]'. - \item Alternatives are separated by vertical bars `@!'; the vertical bar - has low precedence, so alternatives extend as far as possible between - bars and up to the enclosing brackets if any. - \item A sequence of alternatives enclosed in double-brackets `@[[ $\ldots$ - @]]' indicates that the alternatives may occur in any order, but each may - appear at most once unless marked by a star. - \end{itemize} - For example, the notation at the head of this example describes syntax - for @|let|. -\end{describe} - - -\begin{describe}{cls}{example-class (direct-super other-direct-super) \&key - :initarg} - The synopsis for a class lists the class's direct superclasses, and the - acceptable initargs in the form of a lambda-list. The initargs may be - passed to @|make-instance| when constructing an instance of the class or a - subclass of it. If instances of the class may be reinitialized, or if - objects can be changed to be instances of the class, then these initargs - may also be passed to @|reinitialize-instance| and/or @|change-class| as - applicable; the class description will state explicitly when these - operations are allowed. -\end{describe} +\chapter{C language utilities} \label{ch:clang} %%%-------------------------------------------------------------------------- -\section{C type representation} \label{sec:proto.c-types} +\section{C type representation} \label{sec:clang.c-types} -\subsection{Overview} \label{sec:proto.c-types.over} +\subsection{Overview} \label{sec:clang.c-types.over} The Sod translator represents C types in a fairly simple and direct way. However, because it spends a fair amount of its time dealing with C types, it provides a number of useful operations and macros. -The class hierarchy is shown in~\xref{fig:proto.c-types}. +The class hierarchy is shown in~\xref{fig:codegen.c-types.classes}. \begin{figure} \centering \parbox{10pt}{\begin{tabbing} - @|c-type| \\ \push - @|qualifiable-c-type| \\ \push - @|simple-c-type| \\ \push + @|c-type| \\ \ind + @|qualifiable-c-type| \\ \ind + @|simple-c-type| \\ \ind @|c-class-type| \- \\ - @|tagged-c-type| \\ \push + @|tagged-c-type| \\ \ind @|c-struct-type| \\ @|c-union-type| \\ @|c-enum-type| \- \\ @@ -192,7 +51,7 @@ The class hierarchy is shown in~\xref{fig:proto.c-types}. @|c-function-type| \end{tabbing}} \caption{Classes representing C types} -\label{fig:proto.c-types} +\label{fig:codegen.c-types.classes} \end{figure} C type objects are immutable unless otherwise specified. @@ -229,7 +88,7 @@ similar names. Neither generic function defines a default primary method; subclasses of @|c-type| must define their own methods in order to print correctly. -\subsection{The C type root class} \label{sec:proto.c-types.root} +\subsection{The C type root class} \label{sec:clang.c-types.root} \begin{describe}{cls}{c-type ()} The class @|c-type| marks the root of the built-in C type hierarchy. @@ -241,7 +100,7 @@ Neither generic function defines a default primary method; subclasses of The class @|c-type| is abstract. \end{describe} -\subsection{C type S-expression notation} \label{sec:proto.c-types.sexp} +\subsection{C type S-expression notation} \label{sec:clang.c-types.sexp} The S-expression representation of a type is described syntactically as a type specifier. Type specifiers fit into two syntactic categories. @@ -255,13 +114,14 @@ type specifier. Type specifiers fit into two syntactic categories. arguments to the type operator. \end{itemize} -\begin{describe}{mac}{c-type @ @to @} +\begin{describe}{mac}{c-type @ @> @} Evaluates to a C type object, as described by the type specifier @. \end{describe} -\begin{describe}{mac}{ - defctype @{ @ @! (@^*) @} @ @to @} +\begin{describe}{mac} + {defctype @{ @ @! (@ @^*) @} @ + @> @} Defines a new symbolic type specifier @; if a list of @s is given, then all are defined in the same way. The type constructed by using any of the @s is as described by the type specifier @. @@ -271,16 +131,14 @@ type specifier. Type specifiers fit into two syntactic categories. @ is used in a type specifier. \end{describe} -\begin{describe}{mac}{c-type-alias @ @^* @to @} +\begin{describe}{mac}{c-type-alias @ @^* @> @} Defines each @ as being a type operator identical in behaviour to @. If @ is later redefined then the behaviour of the @es changes too. \end{describe} -\begin{describe}{mac}{% - define-c-type-syntax @ @ \\ \push - @^* \-\\ - @to @} +\begin{describe}{mac} + {define-c-type-syntax @ @ @^* @> @} Defines the symbol @ as a new type operator. When a list of the form @|(@ @^*)| is used as a type specifier, the @s are bound to fresh variables according to @ (a destructuring @@ -292,12 +150,12 @@ type specifier. Type specifiers fit into two syntactic categories. type specifiers among its arguments. \end{describe} -\begin{describe}{fun}{expand-c-type-spec @ @to @} +\begin{describe}{fun}{expand-c-type-spec @ @> @} Returns the Lisp form that @|(c-type @)| would expand into. \end{describe} -\begin{describe}{gf}{% - print-c-type @ @ \&optional @ @} +\begin{describe}{gf} + {print-c-type @ @ \&optional @ @} Print the C type object @ to @ in S-expression form. The @ and @ arguments may be interpreted in any way which seems appropriate: they are provided so that @|print-c-type| may be called via @@ -308,14 +166,15 @@ type specifier. Type specifiers fit into two syntactic categories. default method. \end{describe} -\subsection{Comparing C types} \label{sec:proto.c-types.cmp} +\subsection{Comparing C types} \label{sec:clang.c-types.cmp} It is necessary to compare C types for equality, for example when checking argument lists for methods. This is done by @|c-type-equal-p|. -\begin{describe}{gf}{c-type-equal-p @_1 @_2 @to @} - The generic function @|c-type-equal-p| compares two C types @_1 and - @_2 for equality; it returns true if the two types are equal and +\begin{describe}{gf} + {c-type-equal-p @_1 @_2 @> @} + The generic function @|c-type-equal-p| compares two C types @_1 and + @_2 for equality; it returns true if the two types are equal and false if they are not. Two types are equal if they are structurally similar, where this property @@ -324,24 +183,24 @@ argument lists for methods. This is done by @|c-type-equal-p|. The generic function @|c-type-equal-p| uses the @|and| method combination. - \begin{describe}{meth}{c-type-equal-p @_1 @_2} + \begin{describe}{meth}{c-type-equal-p @_1 @_2} A default primary method for @|c-type-equal-p| is defined. It simply returns @|nil|. This way, methods can specialize on both arguments without fear that a call will fail because no methods are applicable. \end{describe} - \begin{describe}{ar-meth}{c-type-equal-p @_1 @_2} + \begin{describe}{ar-meth}{c-type-equal-p @_1 @_2} A default around-method for @|c-type-equal-p| is defined. It returns - true if @_1 and @_2 are @|eql|; otherwise it delegates to the - primary methods. Since several common kinds of C types are interned, + true if @_1 and @_2 are @|eql|; otherwise it delegates to + the primary methods. Since several common kinds of C types are interned, this is a common case worth optimizing. \end{describe} \end{describe} -\subsection{Outputting C types} \label{sec:proto.c-types.output} +\subsection{Outputting C types} \label{sec:clang.c-types.output} -\begin{describe}{gf}{pprint-c-type @ @ @} +\begin{describe}{gf}{pprint-c-type @ @ @} The generic function @|pprint-c-type| pretty-prints to @ a C-syntax - declaration of an object or function of type @. The result is + declaration of an object or function of type @. The result is written to @. A C declaration has two parts: a sequence of \emph{declaration specifiers} @@ -386,7 +245,7 @@ argument lists for methods. This is done by @|c-type-equal-p|. Every concrete subclass of @|c-type| is expected to provide a primary method on this function. There is no default primary method. - \begin{describe}{ar-meth}{pprint-c-type @ @ @} + \begin{describe}{ar-meth}{pprint-c-type @ @ @} A default around method is defined on @|pprint-c-type| which `canonifies' non-function @ arguments. In particular: \begin{itemize} @@ -405,9 +264,8 @@ argument lists for methods. This is done by @|c-type-equal-p|. specifiers. The precise details are subject to change. \end{describe} -\begin{describe}{mac}{% - maybe-in-parens (@ @) \\ \push - @^*} +\begin{describe}{mac} + {maybe-in-parens (@ @) @^*} The @ is evaluated, and then the @s are evaluated in sequence within a pretty-printer logical block writing to the stream named by the symbol @. If the @ evaluates to nil, then @@ -420,7 +278,7 @@ argument lists for methods. This is done by @|c-type-equal-p|. \end{describe} \subsection{Type qualifiers and qualifiable types} -\label{sec:proto.ctypes.qual} +\label{sec:clang.ctypes.qual} \begin{describe}{cls}{qualifiable-c-type (c-type) \&key :qualifiers} The class @|qualifiable-c-type| describes C types which can bear @@ -438,18 +296,18 @@ argument lists for methods. This is done by @|c-type-equal-p|. The class @|qualifiable-c-type| is abstract. \end{describe} -\begin{describe}{gf}{c-type-qualifiers @ @to @} - Returns the qualifiers of the @|qualifiable-c-type| instance @ as an - immutable list. +\begin{describe}{gf}{c-type-qualifiers @ @> @} + Returns the qualifiers of the @|qualifiable-c-type| instance @ as + an immutable list. \end{describe} -\begin{describe}{fun}{qualify-type @ @} - The argument @ must be an instance of @|qualifiable-c-type|, +\begin{describe}{fun}{qualify-type @ @ @> @} + The argument @ must be an instance of @|qualifiable-c-type|, currently bearing no qualifiers, and @ a list of qualifier keywords. The result is a C type object like @ except that it bears the given @. - The @ is not modified. If @ is interned, then the returned + The @ is not modified. If @ is interned, then the returned type will be interned. \end{describe} @@ -459,7 +317,7 @@ argument lists for methods. This is done by @|c-type-equal-p|. non-null then the final character of the returned string will be a space. \end{describe} -\subsection{Leaf types} \label{sec:proto.c-types.leaf} +\subsection{Leaf types} \label{sec:clang.c-types.leaf} A \emph{leaf type} is a type which is not defined in terms of another type. In Sod, the leaf types are @@ -484,58 +342,59 @@ In Sod, the leaf types are and matching qualifiers. A number of symbolic type specifiers for builtin types are predefined as - shown in \xref{tab:proto.c-types.simple}. These are all defined as if by + shown in \xref{tab:codegen.c-types.simple}. These are all defined as if by @|define-simple-c-type|, so can be used to construct qualified types. \end{describe} \begin{table} - \begin{tabular}[C]{|l|l|} \hlx{hv} - \textbf{C type} & \textbf{Specifiers} \\ \hlx{vhv} - @|void| & @|void| \\ \hlx{vhv} + \begin{tabular}[C]{ll} \hlx*{hv} + \thd{C type} & \thd{Specifiers} \\ \hlx{vhv} + @|void| & @|void| \\ \hlx{v} @|char| & @|char| \\ \hlx{v} - @|unsigned char| & @|unsigned-char|, @|uchar| \\ \hlx{v} - @|signed char| & @|signed-char|, @|schar| \\ \hlx{vhv} + @|unsigned char| & @|unsigned-char|, @|uchar| \\ \hlx{} + @|signed char| & @|signed-char|, @|schar| \\ \hlx{v} @|short| & @|short|, @|signed-short|, @|short-int|, - @|signed-short-int| @|sshort| \\ \hlx{v} + @|signed-short-int| @|sshort| \\ \hlx{} @|unsigned short| & @|unsigned-short|, @|unsigned-short-int|, - @|ushort| \\ \hlx{vhv} + @|ushort| \\ \hlx{v} @|int| & @|int|, @|signed|, @|signed-int|, - @|sint| \\ \hlx{v} - @|unsigned int| & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{vhv} + @|sint| \\ \hlx{} + @|unsigned int| & @|unsigned|, @|unsigned-int|, @|uint| \\ \hlx{v} @|long| & @|long|, @|signed-long|, @|long-int|, - @|signed-long-int|, @|slong| \\ \hlx{v} + @|signed-long-int|, @|slong| \\ \hlx{} @|unsigned long| & @|unsigned-long|, @|unsigned-long-int|, - @|ulong| \\ \hlx{vhv} + @|ulong| \\ \hlx{v} @|long long| & @|long-long|, @|signed-long-long|, @|long-long-int|, \\ & \qquad @|signed-long-long-int|, @|llong|, @|sllong| \\ \hlx{v} @|unsigned long long| & @|unsigned-long-long|, @|unsigned-long-long-int|, - @|ullong| \\ \hlx{vhv} - @|float| & @|float| \\ \hlx{v} - @|double| & @|double| \\ \hlx{vhv} + @|ullong| \\ \hlx{v} + @|float| & @|float| \\ \hlx{} + @|double| & @|double| \\ \hlx{v} @|va_list| & @|va-list| \\ \hlx{v} @|size_t| & @|size-t| \\ \hlx{v} - @|ptrdiff_t| & @|ptrdiff-t| \\ \hlx{vh} + @|ptrdiff_t| & @|ptrdiff-t| \\ \hlx*{vh} \end{tabular} \caption{Builtin symbolic type specifiers for simple C types} - \label{tab:proto.c-types.simple} + \label{tab:codegen.c-types.simple} \end{table} -\begin{describe}{fun}{make-simple-type @ \&optional @} +\begin{describe}{fun} + {make-simple-type @ \&optional @ @> @} Return the (unique interned) simple C type object for the C type whose name is @ (a string) and which has the given @ (a list of keywords). \end{describe} -\begin{describe}{gf}{c-type-name @} - Returns the name of a @|simple-c-type| instance @ as an immutable +\begin{describe}{gf}{c-type-name @ @> @} + Returns the name of a @|simple-c-type| instance @ as an immutable string. \end{describe} -\begin{describe}{mac}{% - define-simple-c-type @{ @ @! (@^*) @} @} +\begin{describe}{mac} + {define-simple-c-type @{ @ @! (@^*) @} @ @> @} Define type specifiers for a new simple C type. Each symbol @ is defined as a symbolic type specifier for the (unique interned) simple C type whose name is the value of @. Further, each @ is @@ -560,13 +419,22 @@ In Sod, the leaf types are structs and unions. \end{boxy} -\begin{describe}{gf}{c-tagged-type-kind @} - Returns a symbol classifying the tagged @: one of @|enum|, @|struct| - or @|union|. User-defined subclasses of @|tagged-c-type| should return - their own classification symbols. It is intended that @|(string-downcase - (c-tagged-type-kind @))| be valid C syntax.\footnote{% +\begin{describe}{gf}{c-tagged-type-kind @ @> @} + Returns a keyword classifying the tagged @: one of @|:enum|, + @|:struct| or @|:union|. User-defined subclasses of @|tagged-c-type| + should return their own classification symbols. It is intended that + @|(string-downcase (c-tagged-type-kind @))| be valid C + syntax.\footnote{% Alas, C doesn't provide a syntactic category for these keywords; \Cplusplus\ calls them a @.} % + There is a method defined for each of the built-in tagged type classes + @|c-struct-type|, @|c-union-type| and @|c-enum-type|. +\end{describe} + +\begin{describe}{gf}{kind-c-tagged-type @ @> @} + This is not quite the inverse of @|c-tagged-type-kind|. Given a keyword + naming a kind of tagged type, return the name of the corresponding C + type class as a symbol. \end{describe} \begin{describe}{cls}{c-enum-type (tagged-c-type) \&key :qualifiers :tag} @@ -577,7 +445,8 @@ In Sod, the leaf types are interned) enumerated type with the given @ and @s (all evaluated). \end{describe} -\begin{describe}{fun}{make-enum-type @ \&optional @} +\begin{describe}{fun} + {make-enum-type @ \&optional @ @> @} Return the (unique interned) C type object for the enumerated C type whose tag is @ (a string) and which has the given @ (a list of keywords). @@ -591,7 +460,8 @@ In Sod, the leaf types are interned) structured type with the given @ and @s (all evaluated). \end{describe} -\begin{describe}{fun}{make-struct-type @ \&optional @} +\begin{describe}{fun} + {make-struct-type @ \&optional @ @> @} Return the (unique interned) C type object for the structured C type whose tag is @ (a string) and which has the given @ (a list of keywords). @@ -606,24 +476,31 @@ In Sod, the leaf types are interned) union type with the given @ and @s (all evaluated). \end{describe} -\begin{describe}{fun}{make-union-type @ \&optional @} +\begin{describe}{fun} + {make-union-type @ \&optional @ @> @} Return the (unique interned) C type object for the union C type whose tag is @ (a string) and which has the given @ (a list of keywords). \end{describe} -\subsection{Pointers and arrays} \label{sec:proto.c-types.ptr-array} +\subsection{Compound C types} \label{sec:code.c-types.compound} + +Some C types are \emph{compound types}: they're defined in terms of existing +types. The classes which represent compound types implement a common +protocol. -Pointers and arrays are \emph{compound types}: they're defined in terms of -existing types. A pointer describes the type of objects it points to; an -array describes the type of array element. -\begin{describe}{gf}{c-type-subtype @} - Returns the underlying type of a compound type @. Precisely what - this means depends on the class of @. +\begin{describe}{gf}{c-type-subtype @ @> @} + Returns the underlying type of a compound type @. Precisely what + this means depends on the class of @. \end{describe} -\begin{describe}{cls}{c-pointer-type (qualifiable-c-type) - \&key :qualifiers :subtype} +\subsection{Pointer types} \label{sec:clang.c-types.pointer} + +Pointers compound types. The subtype of a pointer type is the type it points +to. + +\begin{describe}{cls} + {c-pointer-type (qualifiable-c-type) \&key :qualifiers :subtype} Represents a C pointer type. An instance denotes the C type @ @|*|@. @@ -636,16 +513,24 @@ array describes the type of array element. evaluated). The synonyms @|ptr| and @|pointer| may be used in place of the star @`*'. - The symbol @|string| is a type specifier for the type of pointer to + The symbol @|string| is a type specifier for the type pointer to characters; the symbol @|const-string| is a type specifier for the type pointer to constant characters. \end{describe} -\begin{describe}{fun}{make-pointer-type @ \&optional @} - Return an object describing the type of qualified pointers to @. + +\begin{describe}{fun} + {make-pointer-type @ \&optional @ + @> @} + Return an object describing the type qualified pointer to @. If @ is interned, then the returned pointer type object is interned also. \end{describe} +\subsection{Array types} \label{sec:clang.c-types.array} + +Arrays implement the compound-type protocol. The subtype of an array type is +the array element type. + \begin{describe}{cls}{c-array-type (c-type) \&key :subtype :dimensions} Represents a multidimensional C array type. The @ are a list of dimension specifiers $d_0$, $d_1$, \ldots, $d_{n-1}$; an instance then @@ -669,23 +554,380 @@ array describes the type of array element. single-dimensional array with unspecified extent. The synonyms @|array| and @|vector| may be used in place of the brackets @`[]'. \end{describe} -\begin{describe}{fun}{make-array-type @ @} + +\begin{describe}{fun} + {make-array-type @ @ @> @} Return an object describing the type of arrays with given @ and with element type @ (an instance of @|c-type|). The @ argument is a list whose elements are strings or nil; see the description of the class @|c-array-type| above for details. \end{describe} -\begin{describe}{gf}{c-array-dimensions @} - Returns the dimensions of @, an array type, as an immutable list. + +\begin{describe}{gf}{c-array-dimensions @ @> @} + Returns the dimensions of @, an array type, as an immutable list. +\end{describe} + +\subsection{Function types} \label{sec:clang.c-types.fun} + +Function types implement the compound-type protocol. The subtype of a +function type is the type of the function's return value. + +\begin{describe}{cls}{argument} + Represents an ordinary function argument. +\end{describe} + +\begin{describe}{fun}{argumentp @ @> @} + Decide whether @ is an @ object: if so, return non-nil; if + not return nil. +\end{describe} + +\begin{describe}{fun}{make-argument @ @ @> @} + Construct and a return a new @ object. The argument has type + @, which must be a @|c-type| object, and is named @. + + The @ may be nil to indicate that the argument has no name: in this + case the argument will be formatted as an abstract declarator, which is not + suitable for function definitions. If @ is not nil, then the + @'s print representation, with @|*print-escape*| nil, is used as the + argument name. +\end{describe} + +\begin{describe}{fun}{argument-name @ @> @} + Return the name of the @, as it was supplied to @|make-argument|. +\end{describe} + +\begin{describe}{fun}{argument-type @ @> @} + Return the type of the @, as it was supplied to @|make-argument|. +\end{describe} + +\begin{describe}{gf} + {commentify-argument-name @ @> @} + Convert the argument name @ so that it's suitable to declare the + function in a header file. + + Robust header files shouldn't include literal argument names in + declarations of functions or function types, since this restricts the + including file from defining such names as macros. This generic function + is used to convert names into a safe form. + + \begin{describe}{meth}{commentify-argument-name (@ null) @> nil} + Returns nil: if the argument name is already omitted, it's safe for use + in a header file. + \end{describe} + \begin{describe}{meth}{commentify-argument-name (@ t) @> @} + Returns the print form of @ wrapped in a C comment, as + @`/*@*/'. + \end{describe} \end{describe} -\subsection{Function types} \label{sec:proto.c-types.fun} +\begin{describe}{fun} + {commentify-argument-names @ @> @} + Convert the @ list so that it's suitable for use in a header + file. + + The @ list should be a list whose items are @|argument| objects + or the keyword @|:ellipsis|. The return value is a list constructed as + follows. For each @|argument| object in the input list, there is a + corresponding @|argument| object in the returned list, with the same type, + and whose name is the result of @|commentify-argument-name| applied to the + input argument name; an @|:ellipsis| in the input list is passed through + unchanged. +\end{describe} \begin{describe}{cls}{c-function-type (c-type) \&key :subtype :arguments} - Represents C function types. An instance denotes the C type of a C - function which + Represents C function types. An instance denotes the type of a C + function which accepts the @ and returns @. + + The @ are a possibly empty list. All but the last element of + the list must be @|argument| objects; the final element may instead be the + keyword @|:ellipsis|, which denotes a variable argument list. + + An @ list consisting of a single argument with type @|void| is + converted into an empty list. On output as C code, an empty argument list + is written as @|void|. It is not possible to represent a pre-ANSI C + function without prototypes. + + Two function types are considered to be the same if their return types are + the same, and their argument lists consist of arguments with the same type, + in the same order, and either both or neither argument list ends with + @|:ellipsis|; argument names are not compared. + + The type specifier @|(fun @ @{ (@ @) @}^* + @[:ellipsis @! . @ @])| constructs a function type. The function has + the subtype @. The remaining items in the type-specifier list + are used to construct the argument list. The argument items are a possibly + improper list, beginning with zero or more \emph{explicit arguments}: + two-item @/@ lists. For each such list, an @|argument| + object is constructed with the given name (evaluated) and type. Following + the explicit arguments, there may be + \begin{itemize} + \item nothing, in which case the function's argument list consists only of + the explicit arguments; + \item the keyword @|:ellipsis|, as the final item in the type-specifier + list, indicating a variable argument list may follow the explicit + arguments; or + \item a possibly-improper list tail, beginning with an atom either as a + list item or as the final list cdr, indicating that the entire list tail + is Lisp expression which is to be evaluated to compute the remaining + arguments. + \end{itemize} + A tail expression may return a list of @|argument| objects, optionally + followed by an @|:ellipsis|. + + For example, + \begin{prog} + (c-type (fun \=(lisp (c-type-subtype other-func)) \+ \\ + ("first" int) . (c-function-arguments other-func)) + \end{prog} + evaluates to a function type like @|other-func|, only with an additional + argument of type @|int| added to the front of its argument list. This + could also have been written + \begin{prog} + (let (\=(args (c-function-arguments other-func)) \+ \\ + (ret (c-type-subtype other-func))) \- \\ \ind + (c-type (fun \=(lisp ret) ("first" int) . args) + \end{prog} +\end{describe} + +\begin{describe}{fun} + {make-function-type @ @ @> @} + Construct and return a new function type, returning @ and + accepting the @. +\end{describe} + +\begin{describe}{gf} + {c-function-arguments @ @> @} + Return the arguments list of the @. +\end{describe} + +\begin{describe}{fun} + {commentify-function-type @ @> @} + Return a commentified version of the @. + + The returned type has the same subtype as the given type, and the argument + list of the returned type is the result of applying + @|commentify-argument-names| to the argument list of the given type. +\end{describe} + +\subsection{Parsing C types} \label{sec:clang.c-types.parsing} + +%%%-------------------------------------------------------------------------- +\section{Generating C code} \label{sec:clang.codegen} + +This section deals with Sod's facilities for constructing and manipulating C +expressions, declarations, instructions and definitions. + +\subsection{Temporary names} \label{sec:clang.codegen.temporaries} + +Many C-level objects, especially ones with external linkage or inclusion in a +header file, are assigned names which are simple strings, perhaps fixed ones, +perhaps constructed. Other objects don't need meaningful names, and +suitably unique constructed names would be tedious and most likely rather +opaque. Therefore Sod has an ability to construct \emph{temporary names}. + +These aren't temporary in the sense that they name C objects which have +limited lifetimes at runtime. Rather, the idea is that the names be +significant only to small pieces of Lisp code, which will soon forget about +them. + +\subsubsection{The temporary name protocol} +Temporary names are represented by objects which implement a simple protocol. + +\begin{describe}{gf}{format-temporary-name @ @} +\end{describe} + +\begin{describe*} + {\dhead{gf}{var-in-use-p @ @> @} + \dhead[setf var-in-use-p] + {gf}{setf (var-in-use-p @) @}} +\end{describe*} + +\subsubsection{Temporary name objects} + +\begin{describe}{cls}{temporary-name () \&key :tag} + A temporary name object. This is the root of a small collection of + subclasses, but is also usable on its own. +\end{describe} + +\begin{describe}{meth} + {commentify-argument-name (@ temporary-name) @> nil} +\end{describe} + +\begin{table} + \begin{tabular}[C]{*2{>{\codeface}l}} \hlx*{hv} + \thd{\textbf{Class}} & \thd{\textbf{Name format}} \\ \hlx{vhv} + temporary-name & @ \\ + temporary-argument & sod__a@ \\ + temporary-function & sod__f@ \\ + temporary-variable & sod__v@ \\ \hlx*{vh} + \end{tabular} + \caption{Temporary name formats} + \label{tab:codegen.codegen.temps-format} +\end{table} + +\begin{describe}{cls}{temporary-argument (temporary-name) \&key :tag} +\end{describe} + +\begin{describe}{cls}{temporary-function (temporary-name) \&key :tag} +\end{describe} + +\begin{describe}{fun}{temporary-function @> @} +\end{describe} + +\begin{describe}{cls} + {temporary-variable (temporary-name) \&key :tag :in-use-p} +\end{describe} + +\subsubsection{Well-known `temporary' names} + +\begin{table} + \begin{tabular}[C]{*2{>{\codeface}l}} \hlx*{hv} + \thd{\textbf{Variable}} & \thd{\textbf{Name format}} \\ \hlx{vhv} + {}*sod-ap* & sod__ap \\ + {}*sod-master-ap* & sod__master_ap \\ + {}*sod-tmp-ap* & sod__tmp_ap \\ \hlx*{vh} + \end{tabular} + \caption{Well-known temporary names} + \label{tab:codegen.codegen.well-known-temps} +\end{table} + +\subsection{Instructions} \label{sec:clang.codegen.insts} + +\begin{describe}{cls}{inst () \&key} +\end{describe} + +\begin{describe}{gf}{inst-metric @} +\end{describe} + +\begin{describe}{mac} + {definst @ (@ \&key @) (@^*) + @^*} +\end{describe} + +\begin{describe}{mac} + {format-compound-statement (@ @ \&optional @) + @^*} +\end{describe} + +\begin{table} + \begin{tabular}[C]{ll>{\codeface}l} \hlx*{hv} + \thd{Class name} & + \thd{Arguments} & + \thd{Output format} \\ \hlx{vhv} + @|var| & @ @ @ & @ @ @[= @@]; + \\ \hlx{v} + @|set| & @ @ & @ = @; \\ \hlx{v} + @|update| & @ @ @ & @ @= @; + \\ \hlx{v} + @|return| & @ & return @[@@]; + \\ \hlx{v} + @|break| & --- & break; \\ \hlx{v} + @|continue| & --- & continue; \\ \hlx{v} + @|expr| & @ & @; \\ \hlx{v} + @|call| & @ @ & @(@_1, + $\ldots$, + @_n) \\ \hlx{v} + @|va-start| & @ @ & va_start(@, @); + \\ \hlx{v} + @|va-copy| & @ @ & va_copy(@, @); + \\ \hlx{v} + @|va-end| & @ & va_end(@); \\ \hlx{vhv} + @|block| & @ @ & \{ @[@@] @ \} + \\ \hlx{v} + @|if| & @ @ @ & if (@) @ + @[else @@] \\ \hlx{v} + @|while| & @ @ & while (@) @ + \\ \hlx{v} + @|do-while| & @ @ & do @ while (@); + \\ \hlx{v} + @|function| & @ @ @ & + @_0 @(@_1 @_1, $\ldots$, + @_n @_n @[, \dots@]) + @ \\ \hlx*{vh} + \end{tabular} + \caption{Instruction classes} + \label{tab:codegen.codegen.insts} +\end{table} + +\subsection{Code generation} \label{sec:clang.codegen.codegen} + +\begin{describe}{gf}{codegen-functions @ @> @} +\end{describe} + +\begin{describe}{gf} + {ensure-var @ @ @ \&optional @} +\end{describe} + +\begin{describe}{gf}{emit-inst @ @} +\end{describe} + +\begin{describe}{gf}{emit-insts @ @} +\end{describe} + +\begin{describe}{gf}{emit-decl @ @} +\end{describe} + +\begin{describe}{gf}{emit-declss @ @} +\end{describe} + +\begin{describe}{gf}{codegen-push @} +\end{describe} + +\begin{describe}{gf}{codegen-pop @ @> @ @} +\end{describe} + +\begin{describe}{gf}{codegen-pop-block @ @> @} +\end{describe} + +\begin{describe}{gf} + {codegen-pop-function @ @ @ @> @} +\end{describe} + +\begin{describe}{gf}{codegen-add-function @ @} +\end{describe} + +\begin{describe}{fun} + {codegen-build-function @ @ @ @ @ + @> @} +\end{describe} + +\begin{describe}{gf}{temporary-var @ @ @> @} +\end{describe} + +\begin{describe}{mac} + {with-temporary-var (@ @ @) @^* + @> @^*} +\end{describe} + +\begin{describe}{fun}{deliver-expr @ @ @} +\end{describe} + +\begin{describe}{fun}{convert-stmts @ @ @ @} +\end{describe} + +\begin{describe}{cls}{codegen () \&key :vars :insts (:temp-index 0)} +\end{describe} + +%%%-------------------------------------------------------------------------- +\section{Literal C code fragments} \label{sec:clang.fragment} + +\begin{describe}{cls}{c-fragment () \&key :location :text} +\end{describe} + +\begin{describe}{gf}{c-fragment-text @ @> @} +\end{describe} + +\begin{describe}{fun} + {scan-c-fragment @ @ + @> @ @ @} +\end{describe} + +\begin{describe}{fun} + {parse-delimited-fragment @ @ @ \&key :keep-end + \nlret @ @ @} \end{describe} +\relax %%%----- That's all, folks -------------------------------------------------- %%% Local variables: diff --git a/doc/concepts.tex b/doc/concepts.tex new file mode 100644 index 0000000..d554b51 --- /dev/null +++ b/doc/concepts.tex @@ -0,0 +1,42 @@ +%%% -*-latex-*- +%%% +%%% Conceptual background +%%% +%%% (c) 2015 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Sensble Object Design, an object system for C. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with SOD; if not, write to the Free Software Foundation, +%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +\chapter{Concepts} + +\section{Classes and slots} + +\section{Messages and methods} + +\section{Metaclasses} + +\section{Modules} + +%%%----- That's all, folks -------------------------------------------------- + +%%% Local variables: +%%% mode: LaTeX +%%% TeX-master: "sod.tex" +%%% TeX-PDF-mode: t +%%% End: diff --git a/doc/cutting-room-floor.tex b/doc/cutting-room-floor.tex new file mode 100644 index 0000000..c8f241b --- /dev/null +++ b/doc/cutting-room-floor.tex @@ -0,0 +1,489 @@ +%%% -*-latex-*- +%%% +%%% Conceptual background +%%% +%%% (c) 2015 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Sensble Object Design, an object system for C. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with SOD; if not, write to the Free Software Foundation, +%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +\chapter{Cutting-room floor} + +%%%-------------------------------------------------------------------------- +\section{Generated names} + +The generated names for functions and objects related to a class are +constructed systematically so as not to interfere with each other. The rules +on class, slot and message naming exist so as to ensure that the generated +names don't collide with each other. + +The following notation is used in this section. +\begin{description} +\item[@] The full name of the `focus' class: the one for which we are + generating name. +\item[@] The nickname of a superclass. +\item[@] The nickname of the chain-head class of the chain + in question. +\end{description} + +\subsection{Instance layout} + +%%%-------------------------------------------------------------------------- +\section{Class objects} + +\begin{listing} +typedef struct SodClass__ichain_obj SodClass; + +struct sod_chain { + size_t n_classes; /* Number of classes in chain */ + const SodClass *const *classes; /* Vector of classes, head first */ + size_t off_ichain; /* Offset of ichain from instance base */ + const struct sod_vtable *vt; /* Vtable pointer for chain */ + size_t ichainsz; /* Size of the ichain structure */ +}; + +struct sod_vtable { + SodClass *_class; /* Pointer to instance's class */ + size_t _base; /* Offset to instance base */ +}; + +struct SodClass__islots { + + /* Basic information */ + const char *name; /* The class's name as a string */ + const char *nick; /* The nickname as a string */ + + /* Instance allocation and initialization */ + size_t instsz; /* Instance layout size in bytes */ + void *(*imprint)(void *); /* Stamp instance with vtable ptrs */ + void *(*init)(void *); /* Initialize instance */ + + /* Superclass structure */ + size_t n_supers; /* Number of direct superclasses */ + const SodClass *const *supers; /* Vector of direct superclasses */ + size_t n_cpl; /* Length of class precedence list */ + const SodClass *const *cpl; /* Vector for class precedence list */ + + /* Chain structure */ + const SodClass *link; /* Link to next class in chain */ + const SodClass *head; /* Pointer to head of chain */ + size_t level; /* Index of class in its chain */ + size_t n_chains; /* Number of superclass chains */ + const sod_chain *chains; /* Vector of chain structures */ + + /* Layout */ + size_t off_islots; /* Offset of islots from ichain base */ + size_t islotsz; /* Size of instance slots */ +}; + +struct SodClass__ichain_obj { + const SodClass__vt_obj *_vt; + struct SodClass__islots cls; +}; + +struct sod_instance { + struct sod_vtable *_vt; +}; +\end{listing} + +\begin{listing} +void *sod_convert(const SodClass *cls, const void *obj) +{ + const struct sod_instance *inst = obj; + const SodClass *real = inst->_vt->_cls; + const struct sod_chain *chain; + size_t i, index; + + for (i = 0; i < real->cls.n_chains; i++) { + chain = &real->cls.chains[i]; + if (chain->classes[0] == cls->cls.head) { + index = cls->cls.index; + if (index < chain->n_classes && chain->classes[index] == cls) + return ((char *)cls - inst->_vt._base + chain->off_ichain); + else + return (0); + } + } + return (0); +} +\end{listing} + +%%%-------------------------------------------------------------------------- +\section{Classes} +\label{sec:class} + +\subsection{Classes and superclasses} \label{sec:class.defs} + +A @ must list one or more existing classes to be the +\emph{direct superclasses} for the new class being defined. We make the +following definitions. +\begin{itemize} +\item The \emph{superclasses} of a class consist of the class itself together + with the superclasses of its direct superclasses. +\item The \emph{proper superclasses} of a class are its superclasses other + than itself. +\item If $C$ is a (proper) superclass of $D$ then $D$ is a (\emph{proper}) + \emph{subclass} of $C$. +\end{itemize} +The predefined class @|SodObject| has no direct superclasses; it is unique in +this respect. All classes are subclasses of @|SodObject|. + +\subsection{The class precedence list} \label{sec:class.cpl} + +Let $C$ be a class. The superclasses of $C$ form a directed graph, with an +edge from each class to each of its direct superclasses. This is the +\emph{superclass graph of $C$}. + +In order to resolve inheritance of items, we define a \emph{class precedence + list} (or CPL) for each class, which imposes a total order on that class's +superclasses. The default algorithm for computing the CPL is the \emph{C3} +algorithm \cite{fixme-c3}, though extensions may implement other algorithms. + +The default algorithm works as follows. Let $C$ be the class whose CPL we +are to compute. Let $X$ and $Y$ be two of $C$'s superclasses. +\begin{itemize} +\item $C$ must appear first in the CPL. +\item If $X$ appears before $Y$ in the CPL of one of $C$'s direct + superclasses, then $X$ appears before $Y$ in the $C$'s CPL. +\item If the above rules don't suffice to order $X$ and $Y$, then whichever + of $X$ and $Y$ has a subclass which appears further left in the list of + $C$'s direct superclasses will appear earlier in the CPL. +\end{itemize} +This last rule is sufficient to disambiguate because if both $X$ and $Y$ are +superclasses of the same direct superclass of $C$ then that direct +superclass's CPL will order $X$ and $Y$. + +We say that \emph{$X$ is more specific than $Y$ as a superclass of $C$} if +$X$ is earlier than $Y$ in $C$'s class precedence list. If $C$ is clear from +context then we omit it, saying simply that $X$ is more specific than $Y$. + +\subsection{Instances and metaclasses} \label{sec:class.meta} + +A class defines the structure and behaviour of its \emph{instances}: run-time +objects created (possibly) dynamically. An instance is an instance of only +one class, though structurally it may be used in place of an instance of any +of that class's superclasses. It is possible, with care, to change the class +of an instance at run-time. + +Classes are themselves represented as instances -- called \emph{class + objects} -- in the running program. Being instances, they have a class, +called the \emph{metaclass}. The metaclass defines the structure and +behaviour of the class object. + +The predefined class @|SodClass| is the default metaclass for new classes. +@|SodClass| has @|SodObject| as its only direct superclass. @|SodClass| is +its own metaclass. + +To make matters more complicated, Sod has \emph{two} distinct metalevels: as +well as the runtime metalevel, as discussed above, there's a compile-time +metalevel hosted in the Sod translator. Since Sod is written in Common Lisp, +a Sod class's compile-time metaclass is a CLOS class. The usual compile-time +metaclass is @|sod-class|. The compile-time metalevel is the subject of +\xref{ch:api}. + +\subsection{Items and inheritance} \label{sec:class.inherit} + +A class definition also declares \emph{slots}, \emph{messages}, +\emph{initializers} and \emph{methods} -- collectively referred to as +\emph{items}. In addition to the items declared in the class definition -- +the class's \emph{direct items} -- a class also \emph{inherits} items from +its superclasses. + +The precise rules for item inheritance vary according to the kinds of items +involved. + +Some object systems have a notion of `repeated inheritance': if there are +multiple paths in the superclass graph from a class to one of its +superclasses then items defined in that superclass may appear duplicated in +the subclass. Sod does not have this notion. + +\subsubsection{Slots} \label{sec:class.inherit.slots} +A \emph{slot} is a unit of state. In other object systems, slots may be +called `fields', `member variables', or `instance variables'. + +A slot has a \emph{name} and a \emph{type}. The name serves only to +distinguish the slot from other direct slots defined by the same class. A +class inherits all of its proper superclasses' slots. Slots inherited from +superclasses do not conflict with each other or with direct slots, even if +they have the same names. + +At run-time, each instance of the class holds a separate value for each slot, +whether direct or inherited. Changing the value of an instance's slot +doesn't affect other instances. + +\subsubsection{Initializers} \label{sec:class.inherit.init} +Mumble. + +\subsubsection{Messages} \label{sec:class.inherit.messages} +A \emph{message} is the stimulus for behaviour. In Sod, a class must define, +statically, the name and format of the messages it is able to receive and the +values it will return in reply. In this respect, a message is similar to +`abstract member functions' or `interface member functions' in other object +systems. + +Like slots, a message has a \emph{name} and a \emph{type}. Again, the name +serves only to distinguish the message from other direct messages defined by +the same class. Messages inherited from superclasses do not conflict with +each other or with direct messages, even if they have the same name. + +At run-time, one sends a message to an instance by invoking a function +obtained from the instance's \emph{vtable}: \xref{sec:fixme-vtable}. + +\subsubsection{Methods} \label{sec:class.inherit.methods} +A \emph{method} is a unit of behaviour. In other object systems, methods may +be called `member functions'. + +A method is associated with a message. When a message is received by an +instance, all of the methods associated with that message on the instance's +class or any of its superclasses are \emph{applicable}. The details of how +the applicable methods are invoked are described fully in +\xref{sec:fixme-method-combination}. + +\subsection{Chains and instance layout} \label{sec:class.layout} + +C is a rather low-level language, and in particular it exposes details of the +way data is laid out in memory. Since an instance of a class~$C$ should be +(at least in principle) usable anywhere an instance of some superclass $B +\succeq C$ is expected, this implies that an instance of the subclass $C$ +needs to contain within it a complete instance of each superclass $B$, laid +out according to the rules of instances of $B$, so that if we have (the +address of) an instance of $C$, we can easily construct a pointer to a thing +which looks like an instance of $B$ contained within it. + +Specifically, the information we need to retain for an instance of a +class~$C$ is: +\begin{itemize} +\item the values of each of the slots defined by $C$, including those defined + by superclasses; +\item information which will let us convert a pointer to $C$ into a pointer + to any superclass $B \succeq C$; +\item information which will let us call the appropriate effective method for + each message defined by $C$, including those defined by superclasses; and +\item some additional meta-level information, such as how to find the class + object for $C$ given (the address of) one of its instances. +\end{itemize} + +Observe that, while each distinct instance must clearly have its own storage +for slots, all instances of $C$ can share a single copy of the remaining +information. The individual instance only needs to keep a pointer to this +shared table, which, inspired by the similar structure in many \Cplusplus\ +ABIs, are called a \emph{vtable}. + +The easiest approach would be to decide that instances of $C$ are exactly +like instances of $B$, only with extra space at the end for the extra slots +which $C$ defines over and above those already existing in $B$. Conversion +is then trivial: a pointer to an instance of $C$ can be converted to a +pointer to an instance of some superclass $B$ simply by casting. Even though +the root class @|SodObject| doesn't have any slots at all, its instances will +still need a vtable so that you can find its class object: the address of the +vtable therefore needs to be at the very start of the instance structure. +Again, a vtable for a superclass would have a vtable for each of its +superclasses as a prefix, with new items added afterwards. + +This appealing approach works well for an object system which only permits +single inheritance of both state and behaviour. Alas, it breaks down when +multiple inheritance is allowed: $C$ can be a subclass of both $B$ and $B'$, +even though $B$ is not a subclass of $B'$, nor \emph{vice versa}; so, in +general, $B$'s instance structure will not be a prefix of $B'$'s, nor will +$B'$'s be a prefix of $B$'s, and therefore $C$ cannot have both $B$ and $B'$ +as a prefix. + +A (non-root) class may -- though need not -- have a distinguished \emph{link} +superclass, which need not be a direct superclass. Furthermore, each +class~$C$ must satisfy the \emph{chain condition}: for any superclass $A$ of +$C$, there can be at most one other superclass of $C$ whose link superclass +is $A$.\footnote{% + That is, it's permitted for two classes $B$ and $B'$ to have the same link + superclass $A$, but $B$ and $B'$ can't then both be superclasses of the + same class $C$.} % +Therefore, the links partition the superclasses of~$C$ into nice linear +\emph{chains}, such that each superclass is a member of exactly one chain. +If a class~$B$ has a link superclass~$A$, then $B$'s \emph{level} is one more +than that of $A$; otherwise $B$ is called a \emph{chain head} and its level +is zero. If the classes in a chain are written in a list, chain head first, +then the level of each class gives its index in the list. + +Chains therefore allow us to recover some of the linearity properties which +made layout simple in the case of single inheritance. The instance structure +for a class $C$ contains a substructure for each of $C$'s superclass chains; +a pointer to an object of class $C$ actually points to the substructure for +the chain containing $C$. The order of these substructures is unimportant +for now.\footnote{% + The chains appear in the order in which their most specific classes appear + in $C$'s class precedence list. This guarantees that the chain containing + $C$ itself appears first, so that a pointer to $C$'s instance structure is + actually a pointer to $C$'s chain substructure. Apart from that, it's a + simple, stable, but basically arbitrary choice which can't be changed + without breaking the ABI.} % +The substructure for each chain begins with a pointer to a vtable, followed +by a structure for each superclass in the chain containing the slots defined +by that superclass, with the chain head (least specific class) first. + +Suppose we have a pointer to (static) type $C$, and want to convert it into a +pointer to some superclass $B$ of $C$ -- an \emph{upcast}.\footnote{% + In the more general case, we have a pointer to static type $C$, which + actually points to an object of some subclass $D$ of $C$, and want to + convert it into a pointer to type $B$. Such a conversion is called a + \emph{downcast} if $B$ is a subclass of $C$, or a \emph{cross-cast} + otherwise. Downcasts and cross-casts require complicated run-time + checking, and can will fail unless $B$ is a superclass of $D$.} % +If $B$ is in the same chain as $C$ -- an \emph{in-chain upcast} -- then the +pointer value is already correct and it's only necessary to cast it +appropriately. Otherwise -- a \emph{cross-chain upcast} -- the pointer needs +to be adjusted to point to a different chain substructure. Since the lengths +and relative positions of the chain substructures vary between classes, the +adjustments are stored in the vtable. Cross-chain upcasts are therefore a +bit slower than in-chain upcasts. + +Each chain has its own separate vtable, because much of the metadata stored +in the vtable is specific to a particular chain. For example: +\begin{itemize} +\item offsets to other chains' substructures will vary depending on which + chain we start from; and +\item entry points to methods +\end{itemize} +%%%-------------------------------------------------------------------------- +\section{Superclass linearization} + +Before making any decisions about relationships between superclasses, Sod +\emph{linearizes} them, i.e., imposes a total order consistent with the +direct-subclass/superclass partial order. + +In the vague hope that we don't be completely bogged down in formalism by the +end of this, let's introduce some notation. We'll fix some class $z$ and +consider its set of superclasses $S(z) = \{ a, b, \dots \}$. We can define a +relation $c \prec_1 d$ if $c$ is a direct subclass of $d$, and extend it by +taking the reflexive, transitive closure: $c \preceq d$ if and only if +\begin{itemize} +\item $c = d$, or +\item there exists some class $x$ such that $c \prec_1 x$ and $x \preceq d$. +\end{itemize} +This is the `is-subclass-of' relation we've been using so far.\footnote{% + In some object systems, notably Flavors, this relation is allowed to fail + to be a partial order because of cycles in the class graph. I haven't + given a great deal of thought to how well Sod would cope with a cyclic + class graph.} % +We write $d \succeq c$ and say that $d$ is a superclass of $c$ if and only if +$c \preceq d$. + +The problem comes when we try to resolve inheritance questions. A class +should inherit behaviour from its superclasses; but, in a world of multiple +inheritance, which one do we choose? We get a simple version of this problem +when we try to resolve inheritance of slot initializers: only one initializer +can be inherited. + +We start by collecting into a set~$I$ the classes which define an initializer +for the slot. If $I$ contains both a class $x$ and one of $x$'s superclasses +then we should prefer $x$ and consider the superclass to be overridden. So +we should confine our attention to \emph{least} classes: a member $x$ of a +set $I$ is least, with respect to a particular partial order, if $y \preceq +x$ only when $x = y$. If there is a single least class in our set the we +have a winner. Otherwise we want some way to choose among them. + +This is not uncontroversial. Languages such as \Cplusplus\ refuse to choose +among least classes; instead, any program in which such a choice must be made +is simply declared erroneous. + +Simply throwing up our hands in horror at this situation is satisfactory when +we only wanted to pick one `winner', as we do for slot initializers. +However, method combination is a much more complicated business. We don't +want to pick just one winner: we want to order all of the applicable methods +in some way. Insisting that there is a clear winner at every step along the +chain is too much of an imposition. Instead, we \emph{linearize} the +classes. + +%%%-------------------------------------------------------------------------- +\section{Invariance, covariance, contravariance} + +In Sod, at least with regard to the existing method combinations, method +types are \emph{invariant}. This is not an accident, and it's not due to +ignorance. + +The \emph{signature} of a function, method or message describes its argument +and return-value types. If a method's arguments are an integer and a string, +and it returns a character, we might write its signature as +\[ (@|int|, @|string|) \to @|char| \] +In Sod, a method's arguments have to match its message's arguments precisely, +and the return type must either be @|void| -- for a dæmon method -- or again +match the message's return type. This is argument and return-type +\emph{invariance}. + +Some object systems allow methods with subtly different signatures to be +defined on a single message. In particular, since the idea is that instances +of a subclass ought to be broadly compatible~(see \xref{sec:phil.lsp}) with +existing code which expects instances of a superclass, we might be able to +get away with bending method signatures one way or another to permit this. + +\Cplusplus\ permits \emph{return-type covariance}, where a method's return +type can be a subclass of the return type specified by a less-specific +method. Eiffel allows \emph{argument covariance}, where a method's arguments +can be subclasses of the arguments specified by a less-specific +method.\footnote{% + Attentive readers will note that I ought to be talking about pointers to + instances throughout. I'm trying to limit the weight of the notation. + Besides, I prefer data models as found in Lisp and Python where all values + are held by reference.} % + +Eiffel's argument covariance is unsafe.\footnote{% + Argument covariance is correct if you're doing runtime dispatch based on + argument types. Eiffel isn't: it's single dispatch, like Sod is.} % +Suppose that we have two pairs of classes, $a \prec_1 b$ and $c \prec_1 d$. +Class $b$ defines a message $m$ with signature $d \to @|int|$; class $a$ +defines a method with signature $c \to @|int|$. This means that it's wrong +to send $m$ to an instance $a$ carrying an argument of type $d$. But of +course, we can treat an instance of $a$ as if it's an instance of $b$, +whereupon it appears that we are permitted to pass a~$c$ in our message. The +result is a well-known hole in the type system. Oops. + +\Cplusplus's return-type covariance is fine. Also fine is argument +\emph{contravariance}. If $b$ defined its message to have signature $c \to +@|int|$, and $a$ were to broaden its method to $d \to @|int|$, there'd be no +problem. All $c$s are $d$s, so viewing an $a$ as a $b$ does no harm. + +All of this fiddling with types is fine as long as method inheritance or +overriding is an all-or-nothing thing. But Sod has method combinations, +where applicable methods are taken from the instance's class and all its +superclasses and combined. And this makes everything very messy. + +It's possible to sort all of the mess out in the generated effective method +-- we'd just have to convert the arguments to the types that were expected by +the direct methods. This would require expensive run-time conversions of all +of the non-invariant arguments and return values. And we'd need some +complicated rule so that we could choose sensible types for the method +entries in our vtables. Something like this: +\begin{quote} \itshape + For each named argument of a message, there must be a unique greatest type + among the types given for that argument by the applicable methods; and + there must be a unique least type among all of the return types of the + applicable methods. +\end{quote} +I have visions of people wanting to write special no-effect methods whose +only purpose is to guide the translator around the class graph properly. +Let's not. + +%% things to talk about: +%% Liskov substitution principle and why it's mad + +%%%----- That's all, folks -------------------------------------------------- + +%%% Local variables: +%%% mode: LaTeX +%%% TeX-master: "sod.tex" +%%% TeX-PDF-mode: t +%%% End: diff --git a/doc/lispintro.tex b/doc/lispintro.tex new file mode 100644 index 0000000..5f1043f --- /dev/null +++ b/doc/lispintro.tex @@ -0,0 +1,207 @@ +%%% -*-latex-*- +%%% +%%% Description of the internal class structure and protocol +%%% +%%% (c) 2009 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Simple Object Definition system. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with SOD; if not, write to the Free Software Foundation, +%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +\chapter{Protocol overview} \label{ch:proto} + +This chapter provides an overview of the Sod translator's internal object +model. It describes most of the important classes and generic functions, how +they are used to build a model of a Sod module and produce output code, and +how an extension might modify the translator's behaviour. + +I assume familiarity with the Common Lisp Object System (CLOS). Familiarity +with the CLOS Metaobject Protocol isn't necessary but may be instructive. + +%%%-------------------------------------------------------------------------- +\section{A tour through the translator} + +At the very highest level, the Sod translator works in two phases: it +\emph{parses} source files into an internal representation, and then it +\emph{generates} output files from the internal representation. + +The function @|read-module| is given a pathname for a file: it opens the +file, parses the program text, and returns a @|module| instance describing +the classes and other items found. Parsing has a number of extension points +which allow extensions to add their own module syntax. Properties can be +attached to modules and the items defined within them, which select which +internal classes are used to represent them, and possibly provide additional +parameters to them. + +Modules contain a variety of objects, but the most important objects are +classes, which are associated with a menagerie of other objects representing +the slots, messages, methods and so on defined in the module. These various +objects engage in a (fairly complicated) protocol to construct another +collection of \emph{layout objects} describing the low-level data structures +and tables which need to be creates. + +At the far end, the main output function is @|output-module|, which is given +a module, an output stream and a \emph{reason}, which describes what kind of +output is wanted. The module items and the layout objects then engage in +another protocol to work out what output needs to be produced, and which +order it needs to be written in. + +%%%-------------------------------------------------------------------------- +\section{Specification conventions} \label{sec:proto.conventions} + +Throughout this specification, the phrase `it is an error' indicates that a +particular circumstance is erroneous and results in unspecified and possibly +incorrect behaviour. In particular, the situation need not be immediately +diagnosed, and the consequences may be far-reaching. + +The following conventions apply throughout this specification. + +\begin{itemize} + +\item If a specification describes an argument as having a particular type or + syntax, then it is an error to provide an argument not having that + particular type or syntax. + +\item If a specification describes a function then that function might be + implemented as a generic function; it is an error to attempt to (re)define + it as a generic function, or to attempt to add methods to it. A function + specified as being a generic function will certainly be so; if user methods + are permitted on the generic function then this will be specified. + +\item Where a class precedence list is specified, either explicitly or + implicitly by a class hierarchy, the implementation may include additional + superclasses not specified here. Such additional superclasses will not + affect the order of specified classes in the class precedence lists either + of specified classes themselves or of user-defined subclasses of specified + classes. + +\item Unless otherwise specified, generic functions use the standard method + combination. + +\item The specifications for methods are frequently brief; they should be + read in conjunction with and in the context of the specification for the + generic function and specializing classes, if any. + +\item An object $o$ is a \emph{direct instance} of a class $c$ if @|(eq + (class-of $o$) $c$)|; $o$ is an \emph{instance} of $c$ if it is a direct + instance of any subclass of $c$. + +\item If a class is specified as being \emph{abstract} then it is an error to + construct direct instances of it, e.g., using @|make-instance|. + +\item If an object is specified as being \emph{immutable} then it is an error + to mutate it, e.g., using @|(setf (slot-value \ldots) \ldots)|. Programs + may rely on immutable objects retaining their state. + +\item A value is \emph{fresh} if it is guaranteed to be not @|eql| to any + previously existing value. A list is \emph{fresh} if it is guaranteed that + none of the cons cells in its main cdr chain (i.e., the list head, its cdr, + and so on) are @|eql| to any previously existing value. + +\item Unless otherwise specified, it is an error to mutate any part of value + passed as an argument to, or a non-fresh part of a value returned by, a + function specified in this document. + +\item Unless otherwise specified, it is an error to change the class of an + instance of any class described here; and it is an error to change the + class of an object to a class described here. + +\end{itemize} + +\subsection{Format of the entries} \label{sec:proto.conventions.format} + +Most symbols defined by the protocol have their own entries. An entry begins +with a header line, showing a synopsis of the symbol on the left, and the +category (function, class, macro, etc.) on the right. + +\begin{describe}{fun}{example-function @ + \&optional @ + \&rest @ + \&key :keyword + @> @} + The synopsis for a function, generic function or method describes the + function's lambda-list using the usual syntax. Note that keyword arguments + are shown by naming their keywords; in the description, the value passed + for the keyword argument @|:keyword| is shown as @. + + If no results are shown, then the return values (if any) are not + specified. Functions may return more than one result, e.g., + \begin{quote} \sffamily + floor @ \&optional (@ 1) @> @ @ + \end{quote} + or possibly multiple results, e.g., + \begin{quote} \sffamily + values \&rest @ @> @^* + \end{quote} + + For a method, specializers are shown using the usual @|defmethod| syntax, + e.g., + \begin{quote} \sffamily + some-generic-function ((@ list) @) + @> @ + \end{quote} +\end{describe} + +\begin{describe}{mac}{example-macro + ( @{ @ @! (@ @) @}^* ) \\ \ind + @[[ @^* @! @ @]] \\ + @^* + \nlret @^*} + The synopsis for a macro describes the acceptable syntax using the + following notation. + \begin{itemize} + \item Literal symbols, e.g., keywords and parenthesis, are shown in + @|sans|. + \item Metasyntactic variables are shown in (roman) @. + \item Items are grouped together by braces `@{ $\dots$ @}'. The notation + `@{ $\dots$ @}^*' indicates that the enclosed items may be repeated zero + or more times; `@{ $\dots$ @}^+' indicates that the enclosed items may be + repeated one or more times. This notation may be applied to a single + item without the braces. + \item Optional items are shown enclosed in brackets `@[ $\dots$ @]'. + \item Alternatives are separated by vertical bars `@!'; the vertical bar + has low precedence, so alternatives extend as far as possible between + bars and up to the enclosing brackets if any. + \item A sequence of alternatives enclosed in double-brackets `@[[ $\ldots$ + @]]' indicates that the alternatives may occur in any order, but each may + appear at most once unless marked by a star. + \item The notation for results is the same as for functions. + \end{itemize} + For example, the notation at the head of this example describes syntax + for @|let|. +\end{describe} + +\begin{describe}{cls}{example-class (direct-super other-direct-super) \&key + :initarg} + The synopsis for a class lists the class's direct superclasses, and the + acceptable initargs in the form of a lambda-list. The initargs may be + passed to @|make-instance| when constructing an instance of the class or a + subclass of it. If instances of the class may be reinitialized, or if + objects can be changed to be instances of the class, then these initargs + may also be passed to @|reinitialize-instance| and/or @|change-class| as + applicable; the class description will state explicitly when these + operations are allowed. +\end{describe} + +%%%----- That's all, folks -------------------------------------------------- + +%%% Local variables: +%%% mode: LaTeX +%%% TeX-master: "sod.tex" +%%% TeX-PDF-mode: t +%%% End: diff --git a/doc/list-exports.lisp b/doc/list-exports.lisp index abbf94a..93ee8be 100644 --- a/doc/list-exports.lisp +++ b/doc/list-exports.lisp @@ -123,6 +123,10 @@ (when (or (specialized-on-p #'sod-parser:expand-parser-spec 1 symbol) (specialized-on-p #'sod-parser:expand-parser-form 1 symbol)) (push :parser things)) + (when (get symbol 'optparse::opthandler) + (push :opthandler things)) + (when (get symbol 'optparse::optmacro) + (push :optmacro things)) (nreverse things))) (defun categorize-symbols (paths package) @@ -340,7 +344,12 @@ (let* ((sod (asdf:find-system "sod")) (parser-files (files (by-name sod "parser"))) (utilities (by-name sod "utilities")) - (sod-files (remove utilities (files sod)))) + (sod-frontend (asdf:find-system "sod-frontend")) + (optparse (by-name sod-frontend "optparse")) + (frontend (by-name sod-frontend "frontend")) + (sod-files (set-difference (files sod) (list utilities)))) (report-symbols (mapcar #'file-name sod-files) "SOD") + (report-symbols (mapcar #'file-name (list frontend)) "SOD-FRONTEND") (report-symbols (mapcar #'file-name parser-files) "SOD-PARSER") + (report-symbols (mapcar #'file-name (list optparse)) "OPTPARSE") (report-symbols (mapcar #'file-name (list utilities)) "SOD-UTILITIES")))) diff --git a/doc/misc.tex b/doc/misc.tex new file mode 100644 index 0000000..de62c8e --- /dev/null +++ b/doc/misc.tex @@ -0,0 +1,534 @@ +%%% -*-latex-*- +%%% +%%% Miscellaneous functionality +%%% +%%% (c) 2015 Straylight/Edgeware +%%% + +%%%----- Licensing notice --------------------------------------------------- +%%% +%%% This file is part of the Sensble Object Design, an object system for C. +%%% +%%% SOD is free software; you can redistribute it and/or modify +%%% it under the terms of the GNU General Public License as published by +%%% the Free Software Foundation; either version 2 of the License, or +%%% (at your option) any later version. +%%% +%%% SOD is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +%%% GNU General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with SOD; if not, write to the Free Software Foundation, +%%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +\chapter{Miscellaneous functionality} \label{ch:misc} + +%%%-------------------------------------------------------------------------- +\section{Utilities} \label{sec:misc.utilities} + +These symbols are defined in the @|sod-utilities| package. + +\begin{describe}{mac} + {with-gensyms (@{ @ @! (@ @[@@]) @}^*) \\ \ind + @^*} +\end{describe} + +\begin{describe}{mac} + {once-only (@[[ :environment @ @]] + @{ @ @! (@ @[@@]) @}^*) \\ \ind + @^*} +\end{describe} + +\begin{describe}{mac} + {parse-body @ @> @ @ @} +\end{describe} + +\begin{describe}{cls}{loc} +\end{describe} + +\begin{describe}{fun}{locp @ @> @} +\end{describe} + +\begin{describe}{macro}{locf @ @> @} +\end{describe} + +\begin{describe*} + {\dhead{fun}{ref @ @> @} + \dhead{fun}{setf (ref @) @}} +\end{describe*} + +\begin{describe}{mac} + {with-locatives + @{ @ @! (@{ @ @! + (@ @[@@]) @}^*) @} \\ \ind + @^*} +\end{describe} + +\begin{describe}{sym}{it} +\end{describe} + +\begin{describe}{mac}{aif @ @ @[@@]} +\end{describe} + +\begin{describe}{mac}{awhen @ @^*} +\end{describe} + +\begin{describe}{mac}{acond @{ (@ @^*) @}^*} +\end{describe} + +\begin{describe*} + {\dhead{mac} + {acase @ @{ (@{ @ @! (@^*) @} @^*) @}^*} + \dhead{mac} + {aecase @ @{ (@{ @ @! (@^*) @} @^*) @}^*} + \dhead{mac}{atypecase @ @{ (@ @^*) @}^*} + \dhead{mac}{aetypecase @ @{ (@ @^*) @}^*}} +\end{describe*} + +\begin{describe}{mac}{asetf @{ @ @ @}^*} +\end{describe} + +\begin{describe}{gf}{instance-initargs @} +\end{describe} + +\begin{describe*} + {\dhead{fun}{copy-instance @ \&rest @} + \dhead{gf}{copy-instance-using-class @ @ + \&rest @}} +\end{describe*} + +\begin{describe*} + {\dhead{gf}{generic-function-methods @ @> @} + \dhead{gf}{method-specializers @ @> @} + \dhead{cls}{eql-specializer} + \dhead{gf}{eql-specializer-object @ @> @}} +\end{describe*} + +\begin{describe}{fun}{make-list-builder \&optional @ @> @} +\end{describe} + +\begin{describe}{fun}{lbuild-add @ @ @> @} +\end{describe} + +\begin{describe}{fun}{lbuild-add-list @ @ @> @} +\end{describe} + +\begin{describe}{fun}{lbuild-list @ @> @} +\end{describe} + +\begin{describe}{fun} + {mappend @ @ \&rest @ @> @} +\end{describe} + +\begin{describe}{cls}{inconsistent-merge-error (error) \&key :candidates} +\end{describe} + +\begin{describe}{gf}{merge-error-candidates @ @> @} +\end{describe} + +\begin{describe}{fun} + {merge-lists @ \&key :pick (:test \#'eql) @> @} +\end{describe} + +\begin{describe}{mac} + {categorize (\=@ @ + @[[ :bind (@{ @ @! (@ @[@@]) @}^*) @]]) + \\ \ind\ind + (@{ @ @ @}^*) \- \\ + @^* \- + \nlret @^*} +\end{describe} + +\begin{describe}{fun} + {frob-identifier @ \&key :swap-case :swap-hyphen + @> @} +\end{describe} + +\begin{describe}{fun}{whitespace-char-p @ @> @} +\end{describe} + +\begin{describe}{fun} + {update-position @ @ @ + @> @ @} +\end{describe} + +\begin{describe}{fun} + {backtrack-position @ @ @ + @> @ @} +\end{describe} + +\begin{describe}{fun} + {compose @ \&rest @ @> @} +\end{describe} + +\begin{describe}{fun}{symbolicate \&rest @ @> @} +\end{describe} + +\begin{describe}{mac} + {maybe-print-unreadable-object (@ @ + @[[ :type @ @! + :identity @ @]]) \\ \ind + @^*} +\end{describe} + +\begin{describe}{mac} + {dosequence (@ @ + @[[ :start @ @! :end @ @! + :indexvar @ @]]) \\ \ind + @{ @ @! @ @}^*} +\end{describe} + +\begin{describe}{mac} + {define-access-wrapper @ @ + @[[ :read-only @ @]]} +\end{describe} + +\begin{describe}{mac} + {default-slot (@ @ @[@@]) \\ \ind + @^*} +\end{describe} + +\begin{describe}{mac} + {define-on-demand-slot @ @ (@) \\ \ind + @^*} +\end{describe} + +%%%-------------------------------------------------------------------------- +\section{Condition utilities} \label{sec:misc.condition} + +These symbols are defined in the @|sod-parser| package. + +\begin{describe}{cls}{enclosing-condition (condition) \&key :condition} +\end{describe} + +\begin{describe}{gf} + {enclosed-condition @ @> @} +\end{describe} + +\begin{describe}{fun}{cerror* @ \&rest @} +\end{describe} + +%%%-------------------------------------------------------------------------- +\section{Option parser} \label{sec:misc.optparse} + +These symbols are defined in the @!optparse| package. + +\begin{describe}{fun}{exit \&optional (@ 0) \&key :abrupt} +\end{describe} + +\begin{describe}{var}{*program-name*} +\end{describe} + +\begin{describe}{var}{*command-line*} +\end{describe} + +\begin{describe}{fun}{set-command-line-arguments} +\end{describe} + +\begin{describe}{fun}{moan @ \&rest @} +\end{describe} + +\begin{describe}{fun}{die @ \&rest @} +\end{describe} + +\begin{describe}{var}{*options*} +\end{describe} + +\begin{describe}{cls}{option} +\end{describe} + +\begin{describe}{fun}{optionp @ @> @} +\end{describe} + +\begin{describe}{fun} + {make-option \=@ @ \+ \\ + \&optional @ \\ + \&key :tag :negated-tag :arg-optional-p :documentation \- + \nlret @