Merge branch 'master' into doc
authorMark Wooding <mdw@distorted.org.uk>
Sun, 30 Aug 2015 09:58:38 +0000 (10:58 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 20 Sep 2015 13:16:23 +0000 (14:16 +0100)
* 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.

17 files changed:
.gitignore
doc/SYMBOLS [new file with mode: 0644]
doc/clang.tex [moved from doc/sod-protocol.tex with 52% similarity]
doc/concepts.tex [new file with mode: 0644]
doc/cutting-room-floor.tex [new file with mode: 0644]
doc/lispintro.tex [new file with mode: 0644]
doc/list-exports.lisp
doc/misc.tex [new file with mode: 0644]
doc/output.tex [new file with mode: 0644]
doc/parsing.tex [new file with mode: 0644]
doc/runtime.tex [new file with mode: 0644]
doc/sod-backg.tex [deleted file]
doc/sod.sty [new file with mode: 0644]
doc/sod.tex
doc/structures.tex [new file with mode: 0644]
doc/syntax.tex [new file with mode: 0644]
doc/tutorial.tex [moved from doc/sod-tut.tex with 86% similarity]

index 0bf9e54..b841037 100644 (file)
@@ -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 (file)
index 0000000..a6ae09d
--- /dev/null
@@ -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
+
similarity index 52%
rename from doc/sod-protocol.tex
rename to doc/clang.tex
index f0bd115..52e330d 100644 (file)
@@ -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
 %%% 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 @<required>
-    \&optional @<optional>
-    \&rest @<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 @<keyword>.
-
-  For a method, specializers are shown using the usual @|defmethod| syntax,
-  e.g.,
-  \begin{quote}
-    some-generic-function ((@<specialized> list) @<unspecialized>)
-  \end{quote}
-\end{describe}
-
-\begin{describe}{mac}{example-macro
-  ( @{ @<symbol> @! (@<symbol> @<form>) @}^* ) \\ \push
-    @[[ @<declaration>^* @! @<documentation-string> @]] \\
-    @<body-form>^*}
-  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 @<italics>.
-  \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 @<type-spec> @to @<type>}
+\begin{describe}{mac}{c-type @<type-spec> @> @<c-type>}
   Evaluates to a C type object, as described by the type specifier
   @<type-spec>.
 \end{describe}
 
-\begin{describe}{mac}{
-    defctype @{ @<name> @! (@<name>^*) @} @<type-spec> @to @<names>}
+\begin{describe}{mac}
+    {defctype @{ @<name> @! (@<name> @<nickname>^*) @} @<type-spec>
+      @> @<names>}
   Defines a new symbolic type specifier @<name>; if a list of @<name>s is
   given, then all are defined in the same way.  The type constructed by using
   any of the @<name>s is as described by the type specifier @<type-spec>.
@@ -271,16 +131,14 @@ type specifier.  Type specifiers fit into two syntactic categories.
   @<name> is used in a type specifier.
 \end{describe}
 
-\begin{describe}{mac}{c-type-alias @<original> @<alias>^* @to @<aliases>}
+\begin{describe}{mac}{c-type-alias @<original> @<alias>^* @> @<aliases>}
   Defines each @<alias> as being a type operator identical in behaviour to
   @<original>.  If @<original> is later redefined then the behaviour of the
   @<alias>es changes too.
 \end{describe}
 
-\begin{describe}{mac}{%
-  define-c-type-syntax @<name> @<lambda-list> \\ \push
-    @<form>^* \-\\
-  @to @<name>}
+\begin{describe}{mac}
+    {define-c-type-syntax @<name> @<lambda-list> @<form>^* @> @<name>}
   Defines the symbol @<name> as a new type operator.  When a list of the form
   @|(@<name> @<argument>^*)| is used as a type specifier, the @<argument>s
   are bound to fresh variables according to @<lambda-list> (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 @<type-spec> @to @<form>}
+\begin{describe}{fun}{expand-c-type-spec @<type-spec> @> @<form>}
   Returns the Lisp form that @|(c-type @<type-spec>)| would expand into.
 \end{describe}
 
-\begin{describe}{gf}{%
-    print-c-type @<stream> @<type> \&optional @<colon> @<atsign>}
+\begin{describe}{gf}
+    {print-c-type @<stream> @<type> \&optional @<colon> @<atsign>}
   Print the C type object @<type> to @<stream> in S-expression form.  The
   @<colon> and @<atsign> 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 @<type>_1 @<type>_2 @to @<boolean>}
-  The generic function @|c-type-equal-p| compares two C types @<type>_1 and
-  @<type>_2 for equality; it returns true if the two types are equal and
+\begin{describe}{gf}
+    {c-type-equal-p @<c-type>_1 @<c-type>_2 @> @<generalized-boolean>}
+  The generic function @|c-type-equal-p| compares two C types @<c-type>_1 and
+  @<c-type>_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 @<type>_1 @<type>_2}
+  \begin{describe}{meth}{c-type-equal-p @<c-type>_1 @<c-type>_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 @<type>_1 @<type>_2}
+  \begin{describe}{ar-meth}{c-type-equal-p @<c-type>_1 @<c-type>_2}
     A default around-method for @|c-type-equal-p| is defined.  It returns
-    true if @<type>_1 and @<type>_2 are @|eql|; otherwise it delegates to the
-    primary methods.  Since several common kinds of C types are interned,
+    true if @<c-type>_1 and @<c-type>_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 @<type> @<stream> @<kernel>}
+\begin{describe}{gf}{pprint-c-type @<c-type> @<stream> @<kernel>}
   The generic function @|pprint-c-type| pretty-prints to @<stream> a C-syntax
-  declaration of an object or function of type @<type>.  The result is
+  declaration of an object or function of type @<c-type>.  The result is
   written to @<stream>.
 
   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 @<type> @<stream> @<kernel>}
+  \begin{describe}{ar-meth}{pprint-c-type @<c-type> @<stream> @<kernel>}
     A default around method is defined on @|pprint-c-type| which `canonifies'
     non-function @<kernel> 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 (@<stream-var> @<guard-form>) \\ \push
-    @<form>^*}
+\begin{describe}{mac}
+    {maybe-in-parens (@<stream-var> @<guard-form>) @<form>^*}
   The @<guard-form> is evaluated, and then the @<form>s are evaluated in
   sequence within a pretty-printer logical block writing to the stream named
   by the symbol @<stream-var>.  If the @<guard-form> 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 @<type> @to @<list>}
-  Returns the qualifiers of the @|qualifiable-c-type| instance @<type> as an
-  immutable list.
+\begin{describe}{gf}{c-type-qualifiers @<c-type> @> @<list>}
+  Returns the qualifiers of the @|qualifiable-c-type| instance @<c-type> as
+  an immutable list.
 \end{describe}
 
-\begin{describe}{fun}{qualify-type @<type> @<qualifiers>}
-  The argument @<type> must be an instance of @|qualifiable-c-type|,
+\begin{describe}{fun}{qualify-type @<c-type> @<qualifiers> @> @<c-type>}
+  The argument @<c-type> must be an instance of @|qualifiable-c-type|,
   currently bearing no qualifiers, and @<qualifiers> a list of qualifier
   keywords.  The result is a C type object like @<c-type> except that it
   bears the given @<qualifiers>.
 
-  The @<type> is not modified.  If @<type> is interned, then the returned
+  The @<c-type> is not modified.  If @<c-type> 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 @<name> \&optional @<qualifiers>}
+\begin{describe}{fun}
+    {make-simple-type @<name> \&optional @<qualifiers> @> @<c-type>}
   Return the (unique interned) simple C type object for the C type whose name
   is @<name> (a string) and which has the given @<qualifiers> (a list of
   keywords).
 \end{describe}
 
-\begin{describe}{gf}{c-type-name @<type>}
-  Returns the name of a @|simple-c-type| instance @<type> as an immutable
+\begin{describe}{gf}{c-type-name @<c-type> @> @<string>}
+  Returns the name of a @|simple-c-type| instance @<c-type> as an immutable
   string.
 \end{describe}
 
-\begin{describe}{mac}{%
-    define-simple-c-type @{ @<name> @! (@<name>^*) @} @<string>}
+\begin{describe}{mac}
+    {define-simple-c-type @{ @<name> @! (@<name>^*) @} @<string> @> @<name>}
   Define type specifiers for a new simple C type.  Each symbol @<name> is
   defined as a symbolic type specifier for the (unique interned) simple C
   type whose name is the value of @<string>.  Further, each @<name> is
@@ -560,13 +419,22 @@ In Sod, the leaf types are
   structs and unions.
 \end{boxy}
 
-\begin{describe}{gf}{c-tagged-type-kind @<type>}
-  Returns a symbol classifying the tagged @<type>: 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 @<type>))| be valid C syntax.\footnote{%
+\begin{describe}{gf}{c-tagged-type-kind @<c-type> @> @<keyword>}
+  Returns a keyword classifying the tagged @<c-type>: 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 @<c-type>))| be valid C
+  syntax.\footnote{%
     Alas, C doesn't provide a syntactic category for these keywords;
     \Cplusplus\ calls them a @<class-key>.} %
+  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 @<keyword> @> @<symbol>}
+  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 @<tag> and @<qualifier>s (all
   evaluated).
 \end{describe}
-\begin{describe}{fun}{make-enum-type @<tag> \&optional @<qualifiers>}
+\begin{describe}{fun}
+    {make-enum-type @<tag> \&optional @<qualifiers> @> @<c-enum-type>}
   Return the (unique interned) C type object for the enumerated C type whose
   tag is @<tag> (a string) and which has the given @<qualifiers> (a list of
   keywords).
@@ -591,7 +460,8 @@ In Sod, the leaf types are
   interned) structured type with the given @<tag> and @<qualifier>s (all
   evaluated).
 \end{describe}
-\begin{describe}{fun}{make-struct-type @<tag> \&optional @<qualifiers>}
+\begin{describe}{fun}
+    {make-struct-type @<tag> \&optional @<qualifiers> @> @<c-struct-type>}
   Return the (unique interned) C type object for the structured C type whose
   tag is @<tag> (a string) and which has the given @<qualifiers> (a list of
   keywords).
@@ -606,24 +476,31 @@ In Sod, the leaf types are
   interned) union type with the given @<tag> and @<qualifier>s (all
   evaluated).
 \end{describe}
-\begin{describe}{fun}{make-union-type @<tag> \&optional @<qualifiers>}
+\begin{describe}{fun}
+    {make-union-type @<tag> \&optional @<qualifiers> @> @<c-union-type>}
   Return the (unique interned) C type object for the union C type whose tag
   is @<tag> (a string) and which has the given @<qualifiers> (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 @<type>}
-  Returns the underlying type of a compound type @<type>.  Precisely what
-  this means depends on the class of @<type>.
+\begin{describe}{gf}{c-type-subtype @<c-type> @> @<subtype>}
+  Returns the underlying type of a compound type @<c-type>.  Precisely what
+  this means depends on the class of @<c-type>.
 \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 @<subtype>
   @|*|@<qualifiers>.
 
@@ -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 @<subtype> \&optional @<qualifiers>}
-  Return an object describing the type of qualified pointers to @<subtype>.
+
+\begin{describe}{fun}
+    {make-pointer-type @<c-type> \&optional @<qualifiers>
+      @> @<c-pointer-type>}
+  Return an object describing the type qualified pointer to @<subtype>.
   If @<subtype> 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 @<dimensions> 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 @<subtype> @<dimensions>}
+
+\begin{describe}{fun}
+    {make-array-type @<subtype> @<dimensions> @> @<c-array-type>}
   Return an object describing the type of arrays with given @<dimensions> and
   with element type @<subtype> (an instance of @|c-type|).  The @<dimensions>
   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 @<type>}
-  Returns the dimensions of @<type>, an array type, as an immutable list.
+
+\begin{describe}{gf}{c-array-dimensions @<c-type> @> @<list>}
+  Returns the dimensions of @<c-type>, 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 @<value> @> @<generalized-boolean>}
+  Decide whether @<value> is an @<argument> object: if so, return non-nil; if
+  not return nil.
+\end{describe}
+
+\begin{describe}{fun}{make-argument @<name> @<c-type> @> @<argument>}
+  Construct and a return a new @<argument> object.  The argument has type
+  @<c-type>, which must be a @|c-type| object, and is named @<name>.
+
+  The @<name> 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 @<name> is not nil, then the
+  @<name>'s print representation, with @|*print-escape*| nil, is used as the
+  argument name.
+\end{describe}
+
+\begin{describe}{fun}{argument-name @<argument> @> @<name>}
+  Return the name of the @<argument>, as it was supplied to @|make-argument|.
+\end{describe}
+
+\begin{describe}{fun}{argument-type @<argument> @> @<c-type>}
+  Return the type of the @<argument>, as it was supplied to @|make-argument|.
+\end{describe}
+
+\begin{describe}{gf}
+    {commentify-argument-name @<name> @> @<commentified-name>}
+  Convert the argument name @<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 (@<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 (@<name> t) @> @<string>}
+    Returns the print form of @<name> wrapped in a C comment, as
+    @`/*@<name>*/'.
+  \end{describe}
 \end{describe}
 
-\subsection{Function types} \label{sec:proto.c-types.fun}
+\begin{describe}{fun}
+    {commentify-argument-names @<arguments> @> @<commentified-arguments>}
+  Convert the @<arguments> list so that it's suitable for use in a header
+  file.
+
+  The @<arguments> 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 @<arguments> and returns @<subtype>.
+
+  The @<arguments> 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 @<arguments> 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 @<return-type> @{ (@<arg-name> @<arg-type>) @}^*
+  @[:ellipsis @! . @<form> @])| constructs a function type.  The function has
+  the subtype @<return-type>.  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 @<arg-name>/@<arg-type> 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 @<subtype> @<arguments> @> @<c-function-type>}
+  Construct and return a new function type, returning @<subtype> and
+  accepting the @<arguments>.
+\end{describe}
+
+\begin{describe}{gf}
+    {c-function-arguments @<c-function-type> @> @<arguments>}
+  Return the arguments list of the @<c-function-type>.
+\end{describe}
+
+\begin{describe}{fun}
+    {commentify-function-type @<c-function-type> @> @<commentified-c-type>}
+  Return a commentified version of the @<c-function-type>.
+
+  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 @<var> @<stream>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{gf}{var-in-use-p @<var> @> @<generalized-boolean>}
+     \dhead[setf var-in-use-p]
+       {gf}{setf (var-in-use-p @<var>) @<generalized-boolean>}}
+\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 (@<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              & @<tag>                        \\
+    temporary-argument          & sod__a@<tag>                  \\
+    temporary-function          & sod__f@<tag>                  \\
+    temporary-variable          & sod__v@<tag>                  \\ \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 @> @<name>}
+\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 @<inst>}
+\end{describe}
+
+\begin{describe}{mac}
+    {definst @<code> (@<streamvar> \&key @<export>) (@<arg>^*)
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {format-compound-statement (@<stream> @<child> \&optional @<morep>)
+      @<body-form>^*}
+\end{describe}
+
+\begin{table}
+  \begin{tabular}[C]{ll>{\codeface}l}                              \hlx*{hv}
+    \thd{Class name} &
+    \thd{Arguments} &
+    \thd{Output format}                                         \\ \hlx{vhv}
+    @|var|      & @<name> @<type> @<init>  & @<type> @<name> @[= @<init>@];
+                                                                \\ \hlx{v}
+    @|set|      & @<var> @<expr>           & @<var> = @<expr>;  \\ \hlx{v}
+    @|update|   & @<var> @<op> @<expr>     & @<var> @<op>= @<expr>;
+                                                                \\ \hlx{v}
+    @|return|   & @<expr>                  & return @[@<expr>@];
+                                                                \\ \hlx{v}
+    @|break|    & ---                      & break;             \\ \hlx{v}
+    @|continue| & ---                      & continue;          \\ \hlx{v}
+    @|expr|     & @<expr>                  & @<expr>;           \\ \hlx{v}
+    @|call|     & @<func> @<args>          & @<func>(@<arg>_1,
+                                                     $\ldots$,
+                                                     @<arg>_n)  \\ \hlx{v}
+    @|va-start| & @<ap> @<arg>             & va_start(@<ap>, @<arg>);
+                                                                \\ \hlx{v}
+    @|va-copy|  & @<to> @<from>            & va_copy(@<to>, @<from>);
+                                                                \\ \hlx{v}
+    @|va-end|   & @<ap>                    & va_end(@<ap>);     \\ \hlx{vhv}
+    @|block|    & @<decls> @<body>         & \{ @[@<decls>@] @<body> \}
+                                                                \\ \hlx{v}
+    @|if|       & @<cond> @<conseq> @<alt> & if (@<cond>) @<conseq>
+                                             @[else @<alt>@]    \\ \hlx{v}
+    @|while|    & @<cond> @<body>          & while (@<cond>) @<body>
+                                                                \\ \hlx{v}
+    @|do-while| & @<body> @<cond>          & do @<body> while (@<cond>);
+                                                                \\ \hlx{v}
+    @|function| & @<name> @<type> @<body>  &
+      @<type>_0 @<name>(@<type>_1 @<arg>_1, $\ldots$,
+                             @<type>_n @<arg>_n @[, \dots@])
+        @<body>                                                 \\ \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 @<codegen> @> @<list>}
+\end{describe}
+
+\begin{describe}{gf}
+    {ensure-var @<codegen> @<name> @<type> \&optional @<init>}
+\end{describe}
+
+\begin{describe}{gf}{emit-inst @<codegen> @<inst>}
+\end{describe}
+
+\begin{describe}{gf}{emit-insts @<codegen> @<insts>}
+\end{describe}
+
+\begin{describe}{gf}{emit-decl @<codegen> @<decl>}
+\end{describe}
+
+\begin{describe}{gf}{emit-declss @<codegen> @<decls>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-push @<codegen>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-pop @<codegen> @> @<decls> @<insts>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-pop-block @<codegen> @> @<block-inst>}
+\end{describe}
+
+\begin{describe}{gf}
+    {codegen-pop-function @<codegen> @<name> @<type> @> @<name>}
+\end{describe}
+
+\begin{describe}{gf}{codegen-add-function @<codegen> @<function>}
+\end{describe}
+
+\begin{describe}{fun}
+    {codegen-build-function @<codegen> @<name> @<type> @<vars> @<insts>
+      @> @<name>}
+\end{describe}
+
+\begin{describe}{gf}{temporary-var @<codegen> @<type> @> @<name>}
+\end{describe}
+
+\begin{describe}{mac}
+    {with-temporary-var (@<codegen> @<var> @<type>) @<body-form>^*
+      @> @<value>^*}
+\end{describe}
+
+\begin{describe}{fun}{deliver-expr @<codegen> @<target> @<expr>}
+\end{describe}
+
+\begin{describe}{fun}{convert-stmts @<codegen> @<target> @<type> @<func>}
+\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 @<fragment> @> @<string>}
+\end{describe}
+
+\begin{describe}{fun}
+    {scan-c-fragment @<scanner> @<end-chars>
+      @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{fun}
+    {parse-delimited-fragment @<scanner> @<begin> @<end> \&key :keep-end
+      \nlret @<result> @<success-flag> @<consumed-flag>}
 \end{describe}
 
+\relax
 %%%----- That's all, folks --------------------------------------------------
 
 %%% Local variables:
diff --git a/doc/concepts.tex b/doc/concepts.tex
new file mode 100644 (file)
index 0000000..d554b51
--- /dev/null
@@ -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 (file)
index 0000000..c8f241b
--- /dev/null
@@ -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[@<class>] The full name of the `focus' class: the one for which we are
+  generating name.
+\item[@<super-nick>] The nickname of a superclass.
+\item[@<head-nick>] 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 @<full-class-definition> 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 (file)
index 0000000..5f1043f
--- /dev/null
@@ -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 @<required>
+    \&optional @<optional>
+    \&rest @<rest>
+    \&key :keyword
+    @> @<result>}
+  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 @<keyword>.
+
+  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 @<dividend> \&optional (@<divisor> 1) @> @<quotient> @<remainder>
+  \end{quote}
+  or possibly multiple results, e.g.,
+  \begin{quote} \sffamily
+    values \&rest @<values> @> @<value>^*
+  \end{quote}
+
+  For a method, specializers are shown using the usual @|defmethod| syntax,
+  e.g.,
+  \begin{quote} \sffamily
+    some-generic-function ((@<specialized> list) @<unspecialized>)
+      @> @<result>
+  \end{quote}
+\end{describe}
+
+\begin{describe}{mac}{example-macro
+  ( @{ @<symbol> @! (@<symbol> @<form>) @}^* ) \\ \ind
+    @[[ @<declaration>^* @! @<documentation-string> @]] \\
+    @<body-form>^*
+      \nlret @<value>^*}
+  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) @<italics>.
+  \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:
index abbf94a..93ee8be 100644 (file)
     (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)
   (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 (file)
index 0000000..de62c8e
--- /dev/null
@@ -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 (@{ @<var> @! (@<var> @[@<name>@]) @}^*) \\ \ind
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {once-only (@[[ :environment @<env> @]]
+                @{ @<var> @! (@<var> @[@<value-form>@]) @}^*) \\ \ind
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {parse-body @<body> @> @<doc-string> @<declarations> @<body-forms>}
+\end{describe}
+
+\begin{describe}{cls}{loc}
+\end{describe}
+
+\begin{describe}{fun}{locp @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{macro}{locf @<place> @> @<locative>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{ref @<locative> @> @<value>}
+     \dhead{fun}{setf (ref @<locative>) @<value>}}
+\end{describe*}
+
+\begin{describe}{mac}
+    {with-locatives
+        @{ @<var> @! (@{ @<var> @!
+                         (@<var> @[@<locative>@]) @}^*) @} \\ \ind
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{sym}{it}
+\end{describe}
+
+\begin{describe}{mac}{aif @<condition> @<consequent> @[@<alt>@]}
+\end{describe}
+
+\begin{describe}{mac}{awhen @<condition> @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}{acond @{ (@<condition> @<form>^*) @}^*}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{mac}
+      {acase @<scrutinee> @{ (@{ @<case> @! (@<case>^*) @} @<form>^*) @}^*}
+     \dhead{mac}
+      {aecase @<scrutinee> @{ (@{ @<case> @! (@<case>^*) @} @<form>^*) @}^*}
+     \dhead{mac}{atypecase @<scrutinee> @{ (@<type> @<form>^*) @}^*}
+     \dhead{mac}{aetypecase @<scrutinee> @{ (@<type> @<form>^*) @}^*}}
+\end{describe*}
+
+\begin{describe}{mac}{asetf @{ @<place> @<value> @}^*}
+\end{describe}
+
+\begin{describe}{gf}{instance-initargs @<instance>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{copy-instance @<instance> \&rest @<initargs>}
+     \dhead{gf}{copy-instance-using-class @<class> @<instance>
+                                          \&rest @<initargs>}}
+\end{describe*}
+
+\begin{describe*}
+    {\dhead{gf}{generic-function-methods @<generic-function> @> @<list>}
+     \dhead{gf}{method-specializers @<method> @> @<list>}
+     \dhead{cls}{eql-specializer}
+     \dhead{gf}{eql-specializer-object @<specializer> @> @<value>}}
+\end{describe*}
+
+\begin{describe}{fun}{make-list-builder \&optional @<initial> @> @<builder>}
+\end{describe}
+
+\begin{describe}{fun}{lbuild-add @<builder> @<item> @> @<builder>}
+\end{describe}
+
+\begin{describe}{fun}{lbuild-add-list @<builder> @<list> @> @<builder>}
+\end{describe}
+
+\begin{describe}{fun}{lbuild-list @<builder> @> @<list>}
+\end{describe}
+
+\begin{describe}{fun}
+    {mappend @<function> @<list> \&rest @<more-lists> @> @<result-list>}
+\end{describe}
+
+\begin{describe}{cls}{inconsistent-merge-error (error) \&key :candidates}
+\end{describe}
+
+\begin{describe}{gf}{merge-error-candidates @<error> @> @<list>}
+\end{describe}
+
+\begin{describe}{fun}
+    {merge-lists @<lists> \&key :pick (:test \#'eql) @> @<list>}
+\end{describe}
+
+\begin{describe}{mac}
+    {categorize (\=@<item-var> @<items>
+                   @[[ :bind (@{ @<var> @! (@<var> @[@<value>@]) @}^*) @]])
+                                                                 \\ \ind\ind
+        (@{ @<cat-var> @<cat-predicate> @}^*) \- \\
+      @<body-form>^* \-
+     \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {frob-identifier @<string> \&key :swap-case :swap-hyphen
+      @> @<frobbed-string>}
+\end{describe}
+
+\begin{describe}{fun}{whitespace-char-p @<character> @> @<generic-function>}
+\end{describe}
+
+\begin{describe}{fun}
+    {update-position @<character> @<line> @<column>
+      @> @<new-line> @<new-column>}
+\end{describe}
+
+\begin{describe}{fun}
+    {backtrack-position @<character> @<line> @<column>
+      @> @<old-line> @<old-column>}
+\end{describe}
+
+\begin{describe}{fun}
+    {compose @<function> \&rest @<more-functions> @> @<function>}
+\end{describe}
+
+\begin{describe}{fun}{symbolicate \&rest @<symbols> @> @<symbol>}
+\end{describe}
+
+\begin{describe}{mac}
+    {maybe-print-unreadable-object (@<object> @<stream>
+                                    @[[ :type @<type> @!
+                                        :identity @<identity> @]]) \\ \ind
+       @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {dosequence (@<var> @<sequence>
+                 @[[ :start @<start> @! :end @<end> @!
+                     :indexvar @<var> @]]) \\ \ind
+      @{ @<tag> @! @<body-form> @}^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {define-access-wrapper @<from> @<to>
+                           @[[ :read-only @<read-only-flag> @]]}
+\end{describe}
+
+\begin{describe}{mac}
+    {default-slot (@<instance> @<slot> @[@<slot-names>@]) \\ \ind
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {define-on-demand-slot @<class> @<slot> (@<instance>) \\ \ind
+      @<body-form>^*}
+\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 @<enclosing-condition> @> @<condition>}
+\end{describe}
+
+\begin{describe}{fun}{cerror* @<datum> \&rest @<arguments>}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Option parser} \label{sec:misc.optparse}
+
+These symbols are defined in the @!optparse| package.
+
+\begin{describe}{fun}{exit \&optional (@<code> 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 @<format-string> \&rest @<format-args>}
+\end{describe}
+
+\begin{describe}{fun}{die @<format-string> \&rest @<format-args>}
+\end{describe}
+
+\begin{describe}{var}{*options*}
+\end{describe}
+
+\begin{describe}{cls}{option}
+\end{describe}
+
+\begin{describe}{fun}{optionp @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-option \=@<long-name> @<short-name> \+ \\
+                   \&optional @<arg-name> \\
+                   \&key :tag :negated-tag :arg-optional-p :documentation \-
+      \nlret @<option>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{opt-short-name @<option> @> @<character-or-null>}
+     \dhead{fun}{setf (opt-short-name @<option>) @<character-or-null>}
+     \dhead{fun}{opt-long-name @<option> @> @<string-or-null>}
+     \dhead{fun}{setf (opt-long-name @<option>) @<string-or-null>}
+     \dhead{fun}{opt-tag @<option> @> @<tag>}
+     \dhead{fun}{setf (opt-tag @<option>) @<tag>}
+     \dhead{fun}{opt-negated-tag @<option> @> @<tag>}
+     \dhead{fun}{setf (opt-negated-tag @<option>) @<tag>}
+     \dhead{fun}{opt-arg-name @<option> @> @<string-or-null>}
+     \dhead{fun}{setf (opt-arg-name @<option>) @<string-or-null>}
+     \dhead{fun}{opt-optional-p @<option> @> @<generalized-boolean>}
+     \dhead{fun}{setf (opt-optional-p @<option>) @<generalized-boolean>}
+     \dhead{fun}{opt-documentation @<option> @> @<string-or-null>}
+     \dhead{fun}{setf (opt-documentation @<option>) @<string-or-null>}}
+\end{describe*}
+
+\begin{describe}{cls}{option-parser}
+\end{describe}
+
+\begin{describe}{fun}{option-parser-p @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-option-parser \&key \=:args :options :non-option :numericp \+ \\
+                              :negated-numeric-p long-only-p \-
+      \nlret @<option-parser>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{op-options @<option-parser> @> @<list>}
+     \dhead{fun}{setf (op-options @<option-parser>) @<list>}
+     \dhead{fun}{op-non-option @<option-parser> @> @<action>}
+     \dhead{fun}{setf (op-non-option @<option-parser>) @<action>}
+     \dhead{fun}{op-long-only-p @<option-parser> @> @<generalized-boolean>}
+     \dhead{fun}{setf (op-long-only-p @<option-parser>) @<generalized-boolean>}
+     \dhead{fun}{op-numeric-p @<option-parser> @> @<generalized-boolean>}
+     \dhead{fun}{setf (op-numeric-p @<option-parser>) @<generalized-boolean>}
+     \dhead{fun}{op-negated-numeric-p @<option-parser> @<generalized-boolean>}
+     \dhead{fun}{setf (op-negated-numeric-p @<option-parser>) @<generalized-boolean>}
+     \dhead{fun}{op-negated-p @<option-parser> @> @<generalized-boolean>}
+     \dhead{fun}{setf (op-negated-p @<option-parser>) @<generalized-boolean>}}
+\end{describe*}
+
+\begin{describe}{cls}
+    {option-parse-error (error simple-condition)
+      \&key :format-control :format-arguments}
+\end{describe}
+
+\begin{describe}{fun}{option-parse-remainder @<option-parser>}
+\end{describe}
+
+\begin{describe}{fun}{option-parse-return @<tag> \&optional @<argument>}
+\end{describe}
+
+\begin{describe}{fun}{option-parse-next @<option-parser>}
+\end{describe}
+
+\begin{describe}{mac}{option-parse-try @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}{with-unix-error-reporting () @<body-form>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {defopthandler @<name> (@<var> @[@<arg>@]) @<lambda-list> \\ \ind
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {invoke-option-handler @<handler> @<locative> @<arg> @<arguments>}
+\end{describe}
+
+\begin{describe}{opt}{set \&optional @<value>}
+\end{describe}
+
+\begin{describe}{opt}{clear \&optional @<value>}
+\end{describe}
+
+\begin{describe}{opt}{inc \&optional @<maximum> @<step>}
+\end{describe}
+
+\begin{describe}{opt}{dec \&optional <minimum> <step>}
+\end{describe}
+
+\begin{describe}{opt}{read}
+\end{describe}
+
+\begin{describe}{opt}{int \&key :radix :min :max}
+\end{describe}
+
+\begin{describe}{opt}{string}
+\end{describe}
+
+\begin{describe}{opt}{keyword \&optional @<valid>}
+\end{describe}
+
+\begin{describe}{opt}{list \&optional @<handler> \&rest @<handler-args>}
+\end{describe}
+
+\begin{describe}{mac}{defoptmacro @<name> @<lambda-list> @<body-form>^*}
+\end{describe}
+
+\begin{describe}{fun}{parse-option-form @<form>}
+\end{describe}
+
+\begin{describe}{mac}
+    {options @{ \=@<string> @! \+ \\
+                  @<option-macro> @! (@<option-macro> @<macro-arg>^*) @! \\
+                  (@[[ \=@<character> @! (:short-name @<character>) @! \+ \\
+                         @<string>^* @! @<symbol> @! @<rational> @!
+                         (:long-name @<string>) @! \\
+                         (@<string> @<format-arg>^+) @!
+                         (:doc @<string> @<format-arg>^*) @! \\
+                         (:opt-arg @<arg-name>) @! \\
+                         @<keyword> @! (:tag @<tag>) @!
+                                       (:negated-tag @<tag>) @! \\
+                         @{ (@<handler> @<var> @<handler-arg>^*) @}^* @]]) @}^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {simple-usage @<option-list> \&optional @<mandatory-args> @> @<list>}
+\end{describe}
+
+\begin{describe}{fun}{show-usage @<prog> @<usage> \&optional @<stream>}
+\end{describe}
+
+\begin{describe}{fun}
+    {show-help @<prog> @<usage> @<option-list> \&optional @<stream>}
+\end{describe}
+
+\begin{describe}{fun}{sanity-check-option-list @<option-list>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{var}{*help*}
+     \dhead{var}{*version*}
+     \dhead{var}{*usage*}}
+\end{describe*}
+
+\begin{describe}{fun}{do-usage \&optional @<stream>}
+\end{describe}
+
+\begin{describe}{fun}{die-usage}
+\end{describe}
+
+\begin{describe}{optmac}
+    {help-options \&key :short-help :short-version :short-usage}
+\end{describe}
+
+\begin{describe}{fun}
+    {define-program \&key \=:program-name \+ \\
+                            :help :version :usage :full-usage \\
+                            :options}
+\end{describe}
+
+\begin{describe}{mac}
+    {do-options (@[[ :parser @<option-parser> @]]) \\ \ind
+      @{ (@{ @<case> @! (@<case>^*)@} (@[@[@<opt-var>@] @<arg-var>@])
+          @<form>^*) @}^*}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Property sets} \label{sec:misc.pset}
+
+\begin{describe}{fun}{property-key @<name> @> @<keyword>}
+\end{describe}
+
+\begin{describe}{gf}{decode-property @<raw-value> @> @<type> @<value>}
+\end{describe}
+
+\begin{describe}{cls}{property}
+\end{describe}
+
+\begin{describe}{fun}{propertyp @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-property @<name> @<raw-value> \&key :type :location :seenp}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{p-name @<property> @> @<name>}
+     \dhead{fun}{setf (p-name @<property>) @<name>}
+     \dhead{fun}{p-value @<property> @> @<value>}
+     \dhead{fun}{setf (p-value @<property>) @<value>}
+     \dhead{fun}{p-type @<property> @> @<type>}
+     \dhead{fun}{setf (p-type @<property>) @<type>}
+     \dhead{fun}{p-key @<property> @> @<symbol>}
+     \dhead{fun}{setf (p-key @<property>) @<symbol>}
+     \dhead{fun}{p-seenp @<property> @> @<boolean>}
+     \dhead{fun}{setf (p-seenp @<property>) @<boolean>}}
+\end{describe*}
+
+\begin{describe}{gf}{decode-property @<raw-value> @> @<type> @<value>}
+\end{describe}
+
+\begin{describe}{gf}
+    {coerce-property-value @<value> @<type> @<wanted> @> @<coerced-value>}
+\end{describe}
+
+\begin{describe}{cls}{pset}
+\end{describe}
+
+\begin{describe}{fun}{psetp @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}{make-pset @> @<pset>}
+\end{describe}
+
+\begin{describe}{fun}{pset-get @<pset> @<key> @> @<property-or-nil>}
+\end{describe}
+
+\begin{describe}{fun}{pset-store @<pset> @<property> @> @<property>}
+\end{describe}
+
+\begin{describe}{fun}{pset-map @<func> @<pset>}
+\end{describe}
+
+\begin{describe}{mac}{with-pset-iterator (@<iter> @<pset>) @<body-form>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {store-property @<pset> @<name> @<value> \&key :type :location
+      @> @<property>}
+\end{describe}
+
+\begin{describe}{fun}
+    {get-property @<pset> @<name> @<type> \&optional @<default>
+      @> @<value> @<floc-or-nil>}
+\end{describe}
+
+\begin{describe}{fun}
+    {add-property @<pset> @<name> @<value> \&key :type :location
+      @> @<property>}
+\end{describe}
+
+\begin{describe}{fun}{make-property-set \&rest @<plist> @> @<pset>}
+\end{describe}
+
+\begin{describe}{gf}{property-set @<thing> @> @<pset>}
+\end{describe}
+
+\begin{describe}{fun}{check-unused-properties @<pset>}
+\end{describe}
+
+\begin{describe}{mac}
+    {default-slot-from-property
+        (@<instance> @<slot> @[@<slot-names>@]) \\ \ind\ind
+        (@<pset> @<property> @<type> @[@<prop-var> @<convert-form>^*@]) \- \\
+      @<default-form>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {parse-property-set @<scanner>
+      @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Miscellaneous translator features} \label{sec:misc.pset}
+
+\begin{describe}{var}{*sod-version*}
+\end{describe}
+
+\begin{describe}{var}{*debugout-pathname*}
+\end{describe}
+
+\begin{describe}{fun}{test-module @<path> @<reason>}
+\end{describe}
+
+\begin{describe}{fun}{exercise}
+\end{describe}
+
+\begin{describe}{fun}{sod-frontend:main}
+\end{describe}
+
+%%%----- That's all, folks --------------------------------------------------
+
+%%% Local variables:
+%%% mode: LaTeX
+%%% TeX-master: "sod.tex"
+%%% TeX-PDF-mode: t
+%%% End:
diff --git a/doc/output.tex b/doc/output.tex
new file mode 100644 (file)
index 0000000..29a8b4d
--- /dev/null
@@ -0,0 +1,116 @@
+%%% -*-latex-*-
+%%%
+%%% Output machinery
+%%%
+%%% (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{The output system} \label{ch:output}
+
+%%%--------------------------------------------------------------------------
+
+%% output for `h' files
+%%
+%% prologue
+%% guard start
+%% typedefs start
+%% typedefs
+%% typedefs end
+%% includes start
+%% includes
+%% includes end
+%% classes start
+%% CLASS banner
+%% CLASS islots start
+%% CLASS islots slots
+%% CLASS islots end
+%% CLASS vtmsgs start
+%% CLASS vtmsgs CLASS start
+%% CLASS vtmsgs CLASS slots
+%% CLASS vtmsgs CLASS end
+%% CLASS vtmsgs end
+%% CLASS vtables start
+%% CLASS vtables CHAIN-HEAD start
+%% CLASS vtables CHAIN-HEAD slots
+%% CLASS vtables CHAIN-HEAD end
+%% CLASS vtables end
+%% CLASS vtable-externs
+%% CLASS vtable-externs-after
+%% CLASS methods start
+%% CLASS methods
+%% CLASS methods end
+%% CLASS ichains start
+%% CLASS ichains CHAIN-HEAD start
+%% CLASS ichains CHAIN-HEAD slots
+%% CLASS ichains CHAIN-HEAD end
+%% CLASS ichains end
+%% CLASS ilayout start
+%% CLASS ilayout slots
+%% CLASS ilayout end
+%% CLASS conversions
+%% CLASS object
+%% classes end
+%% guard end
+%% epilogue
+
+%% output for `c' files
+%%
+%% prologue
+%% includes start
+%% includes
+%% includes end
+%% classes start
+%% CLASS banner
+%% CLASS direct-methods start
+%% CLASS direct-methods METHOD start
+%% CLASS direct-methods METHOD body
+%% CLASS direct-methods METHOD end
+%% CLASS direct-methods end
+%% CLASS effective-methods
+%% CLASS vtables start
+%% CLASS vtables CHAIN-HEAD start
+%% CLASS vtables CHAIN-HEAD class-pointer METACLASS
+%% CLASS vtables CHAIN-HEAD base-offset
+%% CLASS vtables CHAIN-HEAD chain-offset TARGET-HEAD
+%% CLASS vtables CHAIN-HEAD vtmsgs CLASS start
+%% CLASS vtables CHAIN-HEAD vtmsgs CLASS slots
+%% CLASS vtables CHAIN-HEAD vtmsgs CLASS end
+%% CLASS vtables CHAIN-HEAD end
+%% CLASS vtables end
+%% CLASS object prepare
+%% CLASS object start
+%% CLASS object CHAIN-HEAD ichain start
+%% CLASS object SUPER slots start
+%% CLASS object SUPER slots
+%% CLASS object SUPER vtable
+%% CLASS object SUPER slots end
+%% CLASS object CHAIN-HEAD ichain end
+%% CLASS object end
+%% classes end
+%% epilogue
+
+%%%----- That's all, folks --------------------------------------------------
+
+%%% Local variables:
+%%% mode: LaTeX
+%%% TeX-master: "sod.tex"
+%%% TeX-PDF-mode: t
+%%% End:
diff --git a/doc/parsing.tex b/doc/parsing.tex
new file mode 100644 (file)
index 0000000..58959c0
--- /dev/null
@@ -0,0 +1,765 @@
+%%% -*-latex-*-
+%%%
+%%% Description of the parsing machinery
+%%%
+%%% (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{Parsing} \label{ch:parsing}
+
+%%%--------------------------------------------------------------------------
+\section{The parser protocol} \label{sec:parsing.proto}
+
+For the purpose of Sod's parsing library, \emph{parsing} is the process of
+reading a sequence of input items, in order, and computing an output value.
+
+A \emph{parser} is an expression which consumes zero or more input items and
+returns three values: a \emph{result}, a \emph{success flag}, and a
+\emph{consumed flag}.  The two flags are (generalized) booleans.  If the
+success flag is non-nil, then the parser is said to have \emph{succeeded},
+and the result is the parser's output.  If the success flag is nil then the
+parser is said to have \emph{failed}, and the result is a list of
+\emph{indicators}.  Finally, the consumed flag is non-nil if the parser
+consumed any input items.
+
+\begin{describe}{fun}{combine-parser-failures @<failures> @> @<list>}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{File locations} \label{sec:parsing.floc}
+
+\begin{describe}{cls}{file-location}
+\end{describe}
+
+\begin{describe}{fun}{file-location-p @<object> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}
+    {make-file-location @<filename> \&optional @<line> @<column>
+      @> @<file-location>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{file-location-filename @<floc> @> @<string-or-nil>}
+     \dhead{fun}{file-location-line @<floc> @> @<fixnum-or-nil>}
+     \dhead{fun}{file-location-column @<floc> @> @<fixnum-or-nil>}}
+\end{describe*}
+
+\begin{describe}{gf}{file-location @<object> @> @<floc>}
+  \begin{describe}{meth}{file-location (@<floc> file-location) @> @<floc>}
+  \end{describe}
+  \begin{describe}{meth}{file-location (@<stream> stream) @> @<floc>}
+  \end{describe}
+  \begin{describe}{meth}{file-location (@<any> t) @> @<floc>}
+  \end{describe}
+\end{describe}
+
+\begin{describe}{cls}{condition-with-location (condition) \&key :location}
+\end{describe}
+
+\begin{describe}{meth}
+    {file-location (@<condition> condition-with-location) @> @<floc>}
+\end{describe}
+
+\begin{describe*}
+    {\quad\=\quad\=\kill
+     \dhead{cls}
+      {error-with-location (condition-with-location error) \\ \>
+        \&key :location}
+    \dhead{cls}
+      {warning-with-location (condition-with-location warning) \\ \>
+        \&key :location}
+    \dhead{cls}
+      {enclosing-error-with-location
+          (enclosing-error-with-location error) \\ \>
+        \&key :condition :location}
+    \dhead{cls}
+      {enclosing-warning-with-location
+          (enclosing-condition-with-location warning) \\ \>
+        \&key :condition :location}
+     \dhead{cls}
+      {simple-condition-with-location
+          (condition-with-location simple-condition) \\ \>
+        \&key :format-control :format-arguments :location}
+     \dhead{cls}
+      {simple-error-with-location
+          (error-with-location simple-error) \\ \>
+        \&key :format-control :format-arguments :location}
+    \dhead{cls}
+      {simple-warning-with-location
+          (warning-with-location simple-warning) \\ \>
+        \&key :format-control :format-arguments :location}}
+\end{describe*}
+
+\begin{describe}{fun}
+    {make-condition-with-location @<default-type> @<floc>
+                                  @<datum> \&rest @<arguments>
+       \nlret @<condition-with-location>}
+\end{describe}
+
+\begin{describe*}
+    {\dhead{fun}{error-with-location @<floc> @<datum> \&rest @<arguments>}
+     \dhead{fun}{cerror-with-location @<floc> @<continue-string>
+                                      @<datum> \&rest @<arguments>}
+     \dhead{fun}{cerror*-with-location @<floc> @<datum> \&rest @<arguments>}
+     \dhead{fun}{warn-with-location @<floc> @<datum> \&rest @<arguments>}}
+\end{describe*}
+
+\begin{describe}{mac}
+    {with-default-error-location (@<floc>) @<body-form>^* @> @<value>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {count-and-report-errors () @<body-form>^*
+      @> @<value> @<n-errors> @<n-warnings>}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Scanners} \label{sec:parsing.scanner}
+
+A \emph{scanner} is an object which keeps track of a parser's progress as it
+works through its input.  There's no common base class for scanners: a
+scanner is simply any object which implements the scanner protocol described
+here.
+
+A scanner maintains a sequence of items to read.  It can step forwards
+through the items, one at a time, until it reaches the end (if, indeed, the
+sequence is finite, which it needn't be).  Until that point, there is a
+current item, though there's no protocol for accessing it at this level
+because the nature of the items is left unspecified.
+
+Some scanners support an additional \emph{place-capture} protocol which
+allows rewinding the scanner to an earlier point in the input so that it can
+be scanned again.
+
+\subsection{Basic scanner protocol} \label{sec:parsing.scanner.basic}
+
+The basic protocol supports stepping the scanner forward through its input
+sequence, and detecting the end of the sequence.
+
+\begin{describe}{gf}{scanner-step @<scanner>}
+  Advance the @<scanner> to the next item, which becomes current.
+
+  It is an error to step the scanner if the scanner is at end-of-file.
+\end{describe}
+
+\begin{describe}{gf}{scanner-at-eof-p @<scanner> @> @<generalized-boolean>}
+  Return non-nil if the scanner is at end-of-file, i.e., there are no more
+  items to read.
+
+  If nil is returned, there is a current item, and it is safe to step the
+  scanner again; otherwise, it is an error to query the current item or to
+  step the scanner.
+\end{describe}
+
+\subsection{Place-capture scanner protocol} \label{sec:parsing.scanner.place}
+
+The place-capture protocol allows rewinding to an earlier point in the
+sequence.  Not all scanners support the place-capture protocol.
+
+To rewind a scanner to a particular point, that point must be \emph{captured}
+as a \emph{place} when it's current -- so you must know in advance that this
+is an interesting place that's worth capturing.  The type of place returned
+depends on the type of scanner.  Given a captured place, the scanner can be
+rewound to the position held in it.
+
+Depending on how the scanner works, holding onto a captured place might
+consume a lot of memory or case poor performance.  For example, if the
+scanner is reading from an input stream, having a captured place means that
+data from that point on must be buffered in case the program needs to rewind
+the scanner and read that data again.  Therefore it's possible to
+\emph{release} a place when it turns out not to be needed any more.
+
+\begin{describe}{gf}{scanner-capture-place @<scanner> @> @<place>}
+  Capture the @<scanner>'s current position as a place, and return the place.
+\end{describe}
+
+\begin{describe}{gf}{scanner-restore-place @<scanner> @<place>}
+  Rewind the @<scanner> to the state it was in when @<place> was captured.
+  In particular, the item that was current when the @<place> was captured
+  becomes current again.
+
+  It is an error to restore a @<place> that has been released, or if the
+  @<place> wasn't captured from the @<scanner>.
+\end{describe}
+
+\begin{describe}{gf}{scanner-release-place @<scanner> @<place>}
+  Release the @<place>, to avoid having to maintaining the ability to restore
+  it after it's not needed any more..
+
+  It is an error if the @<place> wasn't captured from the @<scanner>.
+\end{describe}
+
+\begin{describe}{mac}
+    {with-scanner-place (@<place> @<scanner>) @<body-form>^* @> @<value>^*}
+  Capture the @<scanner>'s current position as a place, evaluate the
+  @<body-form>s as an implicit progn with the variable @<place> bound to the captured
+  place.  When control leaves the @<body-form>s, the place is released.  The return
+  values are the values of the final @<body-form>.
+\end{describe}
+
+\subsection{Scanner file-location protocol} \label{sec:parsing.scanner.floc}
+
+Some scanners participate in the file-location protocol
+(\xref{sec:parsing.floc}).  They implement a method on @|file-location| which
+collects the necessary information using scanner-specific functions described
+here.
+
+\begin{describe}{fun}{scanner-file-location @<scanner> @> @<file-location>}
+  Return a @|file-location| object describing the current position of the
+  @<scanner>.
+
+  This calls the @|scanner-filename|, @|scanner-line| and @|scanner-column|
+  generic functions on the scanner, and uses these to fill in an appropriate
+  @|file-location|.
+
+  Since there are default methods on these generic functions, it is not an
+  error to call @|scanner-file-location| on any kind of value, but it might
+  not be very useful.  This function exists to do the work of appropriately
+  specialized methods on @|file-location|.
+\end{describe}
+
+\begin{describe*}
+    {\dhead{gf}{scanner-filename @<scanner> @> @<string>}
+     \dhead{gf}{scanner-line @<scanner> @> @<integer>}
+     \dhead{gf}{scanner-column @<scanner> @> @<integer>}}
+  Return the filename, line and column components of the @<scanner>'s current
+  position, for use in assembling a @<file-location>: see the
+  @|scanner-file-location| function.
+
+  There are default methods on all three generic functions which simply
+  return nil.
+\end{describe*}
+
+\subsection{Character scanners} \label{sec:parsing.scanner.char}
+
+Character scanners are scanners which read sequences of characters.
+
+\begin{describe}{cls}{character-scanner () \&key}
+  Base class for character scanners.  This provides some very basic
+  functionality.
+
+  Not all character scanners are subclasses of @|character-scanner|.
+\end{describe}
+
+\begin{describe}{gf}{scanner-current-char @<scanner> @> @<character>}
+  Returns the current character.
+\end{describe}
+
+\begin{describe}{gf}{scanner-unread @<scanner> @<character>}
+  Rewind the @<scanner> by one step.  The @<chararacter> must be the previous
+  current character, and becomes the current character again.  It is an error
+  if: the @<scanner> has reached end-of-file; the @<scanner> is never been
+  stepped; or @<character> was not the previous current character.
+\end{describe}
+
+\begin{describe}{gf}
+    {scanner-interval @<scanner> @<place-a> \&optional @<place-b>
+        @> @<string>}
+  Return the characters in the @<scanner>'s input from @<place-a> up to (but
+  not including) @<place-b>.
+
+  The characters are returned as a string.  If @<place-b> is omitted, return
+  the characters up to (but not including) the current position.  It is an
+  error if @<place-b> precedes @<place-a> or they are from different
+  scanners.
+
+  This function is a character-scanner-specific extension to the
+  place-capture protocol; not all character scanners implement the
+  place-capture protocol, and some that do may not implement this function.
+\end{describe}
+
+\subsubsection{Stream access to character scanners}
+Sometimes it can be useful to apply the standard Lisp character input
+operations to the sequence of characters held by a character scanner.
+
+\begin{describe}{gf}{make-scanner-stream @<scanner> @> @<stream>}
+  Returns a fresh input @|stream| object which fetches input characters from
+  the character scanner object @<scanner>.  Reading characters from the
+  stream steps the scanner.  The stream will reach end-of-file when the
+  scanner reports end-of-file.  If the scanner implements the file-location
+  protocol then reading from the stream will change the file location in an
+  appropriate manner.
+
+  This is mostly useful for applying standard Lisp stream functions, most
+  particularly the @|read| function, in the middle of a parsing operation.
+\end{describe}
+
+\begin{describe}{cls}{character-scanner-stream (stream) \&key :scanner}
+  A Common Lisp input @|stream| object which works using the character
+  scanner protocol.  Any @<scanner> which implements the base scanner and
+  character scanner protocols is suitable.  See @|make-scanner-stream|.
+\end{describe}
+
+\subsection{String scanners} \label{sec:parsing.scanner.string}
+
+A \emph{string scanner} is a simple kind of character scanner which reads
+input from a string object.  String scanners implement the character scanner
+and place-capture protocols.
+
+\begin{describe}{cls}{string-scanner}
+  The class of string scanners.  The @|string-scanner| class is not a
+  subclass of @|character-scanner|.
+\end{describe}
+
+\begin{describe}{fun}{string-scanner-p @<value> @> @<generalized-boolean>}
+  Return non-nil if @<value> is a @|string-scanner| object; otherwise return
+  nil.
+\end{describe}
+
+\begin{describe}{fun}
+    {make-string-scanner @<string> \&key :start :end @> @<string-scanner>}
+  Construct and return a fresh @|string-scanner| object.  The new scanner
+  will read characters from @<string>, starting at index @<start> (which
+  defaults to zero), and continuing until it reaches index @<end> (defaults
+  to the end of the @<string>).
+\end{describe}
+
+\subsection{Character buffer scanners} \label{sec:parsing.scanner.charbuf}
+
+A \emph{character buffer scanner}, or \emph{charbuf scanner} for short, is an
+efficient scanner for reading characters from an input stream.  Charbuf
+scanners implements the basic scanner, character buffer, place-capture, and
+file-location protocols.
+
+\begin{describe}{cls}
+    {charbuf-scanner (character-scanner)
+        \&key :stream :filename :line :column}
+  The class of charbuf scanners.  The scanner will read characters from
+  @<stream>.  Charbuf scanners implement the file-location protocol: the
+  initial location is set from the given @<filename>, @<line> and @<column>;
+  the scanner will update the location as it reads its input.
+\end{describe}
+
+\begin{describe}{cls}{charbuf-scanner-place}
+  The class of place objects captured by a charbuf scanner.
+\end{describe}
+
+\begin{describe}{fun}
+    {charbuf-scanner-place-p @<value> @> @<generalized-boolean>}
+  Type predicate for charbuf scanner places: returns non-nil if @<value> is a
+  place captured by a charbuf scanner, and nil otherwise.
+\end{describe}
+
+\begin{describe}{gf}
+    {charbuf-scanner-map @<scanner> @<func> \&optional @<fail>
+      \nlret @<result> @<successp> @<consumedp>}
+  Read characters from the @<scanner>'s buffers.
+
+  This is intended to be an efficient and versatile interface for reading
+  characters from a scanner in bulk.  The function @<func> is invoked
+  repeatedly, as if by
+  \begin{prog}
+    (multiple-value-bind (@<donep> @<used>) \\ \ind\ind
+        (funcall @<func> @<buf> @<start> @<end>) \- \\
+      \textrm\ldots)
+  \end{prog}
+  The argument @<buf> is a simple string; @<start> and @<end> are two
+  nonnegative fixnums, indicating that the subsequence of @<buf> between
+  @<start> (inclusive) and @<end> (exclusive) should be processed.  If
+  @<func>'s return value @<donep> is nil then @<used> is ignored: the
+  function has consumed the entire buffer and wishes to read more.  If
+  @<donep> is non-nil, then it must be a fixnum such that $@<start> \le
+  @<used> \le @<end>$: the function has consumed the buffer as far as @<used>
+  (exclusive) and has completed successfully.
+
+  If end-of-file is encountered before @<func> completes successfully then it
+  fails: the @<fail> function is called with no arguments, and is expected to
+  return two values.  If omitted, @<fail> defaults to
+  \begin{prog}
+    (lambda () \\ \ind
+      (values nil nil))%
+  \end{prog}
+
+  The @|charbuf-scanner-map| function returns three values.  The first value
+  is the non-nil @<donep> value returned by @<func> if @|charbuf-scanner-map|
+  succeeded, or the first value returned by @<fail>; the second value is @|t|
+  on success, or the second value returned by @<fail>; the third value is
+  non-nil if @<func> consumed any input, i.e., it returned with @<donep> nil
+  at least once, or with $@<used> > @<start>$.
+\end{describe}
+
+\subsection{Token scanners} \label{sec:parsing.scanner.token}
+
+\begin{describe}{cls}
+    {token-scanner () \&key :filename (:line 1) (:column 0)}
+\end{describe}
+
+\begin{describe}{gf}{token-type @<scanner> @> @<type>}
+\end{describe}
+
+\begin{describe}{gf}{token-value @<scanner> @> @<value>}
+\end{describe}
+
+\begin{describe}{gf}{scanner-token @<scanner> @> @<type> @<value>}
+\end{describe}
+
+\begin{describe}{ty}{token-scanner-place}
+\end{describe}
+
+\begin{describe}{fun}
+    {token-scanner-place-p @<value> @> @<generalized-boolean>}
+\end{describe}
+
+\subsection{List scanners}
+
+\begin{describe}{ty}{list-scanner}
+\end{describe}
+
+\begin{describe}{fun}{list-scanner-p @<value> @> @<generalized-boolean>}
+\end{describe}
+
+\begin{describe}{fun}{make-list-scanner @<list> @> @<list-scanner>}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Parsing syntax}
+
+\begin{describe}{gf}{expand-parser-spec @<context> @<spec> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}
+    {expand-parser-form @<context> @<head> @<tail> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{wrap-parser @<context> @<form> @> @<wrapped-form>}
+\end{describe}
+
+\begin{describe}{mac}
+    {defparse @<name> (@[[ :context (@<var> @<context-class>) @]]
+                       @<destructuring-lambda-list-item>^*) \\ \ind
+      @<body-form>^* \-
+     \nlret @<name>}
+\end{describe}
+
+\begin{describe}{mac}
+    {with-parser-context
+        (@<context-class> @{ @<init-keyword> @<value> @}^*) \\ \ind
+      @<body-form>^* \-
+     \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{lmac}
+    {parse @<parser> @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{gf}{parser-at-eof-p @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-step @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{sym}{it}
+\end{describe}
+
+\begin{describe}{mac}
+    {if-parse (@[[ \=:result @<result-var> @!
+                     :expected @<expected-var> @! \+ \\
+                     :consumedp @<consumed-var> @]]) \- \\ \ind\ind
+        @<parser> \- \\
+      @<consequent> \\
+      @[@<alternatve>@] \-
+     \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {when-parse (@[@<result-var>@]) @<parser> \\ \ind
+      @<body-form>^* \-
+     \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{mac}
+    {cond-parse (@[[ \=:result @<result-var> @!
+                       :expected @<expected-var> @! \+ \\
+                       :consumedp @<consumed-var> @]]) \- \\ \ind
+      @{ (@<parser> @<form>^*) @}^* \-
+     \nlret @<value>^*}
+\end{describe}
+
+\begin{describe}{parse}{:eof}
+\end{describe}
+
+\begin{describe}{parseform}{lisp @<form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{label @<parser>}
+\end{describe}
+
+\begin{describe}{parse}{t}
+\end{describe}
+
+\begin{describe}{parseform}{t @<value>}
+\end{describe}
+
+\begin{describe}{parse}{nil}
+\end{describe}
+
+\begin{describe}{parseform}{nil @<indicator>}
+\end{describe}
+
+\begin{describe}{parseform}{when @<cond> @<parser>}
+\end{describe}
+
+\begin{describe}{parseform}
+    {seq (@{ @<atomic-parser-spec> @! (@[@<var>@] @<parser>) @}^*) \\ \ind
+      @<body-form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{and @<parser>^*}
+\end{describe}
+
+\begin{describe}{parseform}{or @<parser>^*}
+\end{describe}
+
+\begin{describe}{parseform}{? @<parser> @[@<default>@]}
+\end{describe}
+
+\begin{describe}{parseform}
+    {many (\=@<accumulator-var> @<init-form> @<update-form> \+ \\
+           @[[ \=:new @<new-var> @! :final @<final-form> @! \+ \\
+                 :min @<minimum> @! :max @<maximum> @! \\
+                 :commitp @<commitp> @]]) \-\- \\ \ind
+      @<item-parser> @[@<sep-parser>@]}
+\end{describe}
+
+\begin{describe}{parseform}
+    {list (@[[ :min @<minimum> @! :max @<maximum> @!
+               :commitp @<commitp> @]])\\ \ind
+      @<item-parser> @[@<sep-parser>@]}
+\end{describe}
+
+\begin{describe}{parseform}
+    {skip-many (@[[ :min @<minimum> @! :max @<maximum> @!
+                    :commitp @<commitp> @]])\\ \ind
+      @<item-parser> @[@<sep-parser>@]}
+\end{describe}
+
+\begin{describe}{fun}{call-pluggable-parser @<symbol> \&rest @<args>}
+\end{describe}
+
+\begin{describe}{parseform}{plug @<symbol> @<arg>^*}
+\end{describe}
+
+\begin{describe}{fun}
+    {pluggable-parser-add @<symbol> @<tag> @<parser-function>}
+\end{describe}
+
+\begin{describe}{mac}
+    {define-pluggable-parser @<symbol> @<tag> @<lambda-list> @<body-form>^*}
+\end{describe}
+
+\begin{describe}{gf}{parser-capture-place @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-restore-place @<context> @<place> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-release-place @<context> @<place> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}
+    {parser-places-must-be-released-p @<context> @> @<generalized-boolean>>}
+\end{describe}
+
+\begin{describe}{mac}
+    {with-parser-place (@<place-var> @<context>) @<body-form>^*}
+\end{describe}
+
+\begin{describe}{parseform}{peek @<parser>}
+\end{describe}
+
+\begin{describe}{cls}{character-parser-context () \&key}
+\end{describe}
+
+\begin{describe}{gf}{parser-current-char @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{parseform}
+    {if-char (@[@<result-var>@]) @<condition> @<consequent> @<alternative>}
+\end{describe}
+
+\begin{describe}{parseform}{char @<character>}
+\end{describe}
+
+\begin{describe}[char]{parse}{@<character>}
+\end{describe}
+
+\begin{describe}[string]{parse}{@<string>}
+\end{describe}
+
+\begin{describe}{parse}{:any}
+\end{describe}
+
+\begin{describe}{parseform}{satisfies @<predicate>}
+\end{describe}
+
+\begin{describe}{parseform}{not @<character>}
+\end{describe}
+
+\begin{describe}{parseform}{filter @<predicate>}
+\end{describe}
+
+\begin{describe}{parse}{:whitespace}
+\end{describe}
+
+\begin{describe}{cls}{token-parser-context () \&key}
+\end{describe}
+
+\begin{describe}{gf}{parser-token-type @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{gf}{parser-token-value @<context> @> @<form>}
+\end{describe}
+
+\begin{describe}{parseform}{token @<type> @[@<value>@] @[:peekp @<peek>@]}
+\end{describe}
+
+\begin{describe}[atom]{parse}{@<atom>}
+\end{describe}
+
+\begin{describe}[string]{parse}{@<string>}
+\end{describe}
+
+\begin{describe}{cls}{scanner-context () \&key :scanner}
+\end{describe}
+
+\begin{describe}{gf}{parse-scanner @<context> @> @<symbol>}
+\end{describe}
+
+\begin{describe}{cls}
+    {character-scanner-context (scanner-context character-parser-context)
+      \&key :scanner}
+\end{describe}
+
+\begin{describe}{cls}
+    {token-scanner-context (scanner-context token-parser-context)
+      \&key :scanner}
+\end{describe}
+
+\begin{describe}{gf}{push-operator @<operator> @<state>}
+\end{describe}
+
+\begin{describe}{gf}{push-value @<value> @<state>}
+\end{describe}
+
+\begin{describe}{gf}{apply-operator @<operator> @<state>}
+\end{describe}
+
+\begin{describe}{gf}{operator-push-action @<left> @<right>}
+\end{describe}
+
+\begin{describe}{parseform}
+    {expr \=(@[[ :nestedp @<nestedp-var> @]]) \+ \\
+            @<operand-parser> @<binop-parser>
+            @<preop-parser> @<postop-parser>}
+\end{describe}
+
+\begin{describe}{gf}{operator-left-precedence @<operator> @> @<prec>}
+\end{describe}
+
+\begin{describe}{gf}{operator-right-precedence @<operator> @> @<prec>}
+\end{describe}
+
+\begin{describe}{gf}{operator-associativity @<operator> @> @<assoc>}
+\end{describe}
+
+\begin{describe}{cls}{prefix-operator () \&key}
+\end{describe}
+
+\begin{describe}{cls}{simple-operator () \&key :name :function}
+\end{describe}
+
+\begin{describe}{cls}
+    {simple-unary-operator (simple-operator) \&key :name :function}
+\end{describe}
+
+\begin{describe*}
+    {\quad\=\kill
+     \dhead{cls}{simple-binary-operator (simple-operator) \\ \>
+                  \&key :name :function :lprec :rprec :associativity}
+     \dhead{cls}{simple-postfix-operator (simple-unary-operator) \\ \>
+                  \&key :name :function :lprec :rprec}
+     \dhead{cls}{simple-prefix-operator
+                    (prefix-operator simple-unary-operator) \\ \>
+                  \&key :name :function :rprec}}
+\end{describe*}
+
+\begin{describe*}
+    {\dhead{mac}{preop @<name> (@<operand-var> @<lprec>)
+                  @<body-form>^*
+                  @> @<prefix-operator>}
+     \dhead{mac}{postop @<name>
+                     (@<operand-var> @<lprec> @[[ :rprec @<rprec> @]])
+                  @<body-form>^*
+                  @> @<postfix-operator>}
+     \dhead{mac}{binop @<name> (@<operand-var> @<lprec> @<rprec> @<assoc>)
+                  @<body-form>^*
+                  @> @<binary-operator>}}
+\end{describe*}
+
+\begin{describe*}
+    {\dhead{cls}{parenthesis () \&key :tag}
+     \dhead{cls}{open-parenthesis (parenthesis prefix-operator) \&key :tag}
+     \dhead{cls}{close-parenthesis (parenthesis) \&key :tag}}
+\end{describe*}
+
+\begin{describe*}
+    {\dhead{fun}{lparen @<tag> @> @<open-paren>}
+     \dhead{fun}{rparen @<tag> @> @<close-paren>}}
+\end{describe*}
+
+%%%-------------------------------------------------------------------------
+\section{Lexical analyser}
+
+\begin{describe}{cls}
+    {sod-token-scanner (token-scanner)
+      \&key :filename (:line 1) (:column 0) :char-scanner}
+\end{describe}
+
+\begin{describe}{fun}{define-indicator @<indicator> @<description>}
+\end{describe}
+
+\begin{describe}{fun}{syntax-error @<scanner> @<expected> \&key :continuep}
+\end{describe}
+
+\begin{describe}{fun}
+    {lexer-error @<char-scanner> @<expected> @<consumed-flag>}
+\end{describe}
+
+\begin{describe}{parseform}
+    {skip-until (@[[ :keep-end @<keep-end-flag> @]]) @<token-type>^*}
+\end{describe}
+
+\begin{describe}{parseform}{error () @<sub-parser> @<recover-parser>}
+\end{describe}
+
+\begin{describe}{fun}
+    {scan-comment @<char-scanner>
+      @> @<result> @<success-flag> @<consumed-flag>}
+\end{describe}
+
+%%%----- That's all, folks --------------------------------------------------
+
+%%% Local variables:
+%%% mode: LaTeX
+%%% TeX-master: "sod.tex"
+%%% TeX-PDF-mode: t
+%%% End:
diff --git a/doc/runtime.tex b/doc/runtime.tex
new file mode 100644 (file)
index 0000000..487bcee
--- /dev/null
@@ -0,0 +1,201 @@
+%%% -*-latex-*-
+%%%
+%%% The runtime library
+%%%
+%%% (c) 2015 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{The runtime library} \label{ch:runtime}
+
+This chapter describes the runtime support macros and functions defined in
+the @|<sod/sod.h>| header file.  The corresponding types are defined in
+\xref{ch:structures}.
+
+The runtime support functionality defined here generally expects that
+instances and classes inherit from the standard @|SodObject| root object.
+While the translator can (at some effort) support alternative roots, they
+will require different run-time support machinery.
+
+%%%--------------------------------------------------------------------------
+\section{Infrastructure macros} \label{ch:runtime.infra}
+
+These macros are mostly intended for use in code generated by the Sod
+translator.  Others may find them useful for special effects, but they can be
+tricky to understand and use correctly and can't really be recommended for
+general use.
+
+\begin{describe}[SOD_XCHAIN]{mac}
+    {void *SOD_CHAIN(@<chead>, const @<cls> *@<obj>);}
+  Performs a `cross-chain upcast'.
+
+  Given a pointer @<obj> to an instance of a class of type @<cls> and the
+  nickname @<chead> of the least specific class in one of @<cls>'s superclass
+  chains which does not contain @<cls> itself, @|SOD_XCHAIN| returns the
+  address of that chain's storage within the instance layout as a raw
+  @|void~*| pointer.  (Note that @<cls> is not mentioned explicitly.)
+
+  This macro is used by the generated @|@<CLASS>{}__CONV_@<CLS>| conversion
+  macros, which you are encouraged to use instead where possible.
+\end{describe}
+
+\begin{describe}[SOD_OFFSETDIFF]{mac}
+    {ptrdiff_t SOD_OFFSETDIFF(@<type>, @<member>_1, @<member>_2);}
+  Returns the signed offset between two members of a structure or union type.
+
+  Given a structure or union type @<type>, and two member names @<member>_1
+  and @<member>_2, then @|SOD_OFFSETDIFF| gives the difference, in bytes,
+  between the addresses of objects @|$x$.@<member>_1| and @|$x$.@<member>_2|
+  for any object $x$ of type @<type>.
+
+  This macro is used internally when generating vtables and is not expected
+  to be very useful elsewhere.
+\end{describe}
+
+\begin{describe}[SOD_ILAYOUT]{mac}
+    {@<cls>{}__ilayout *SOD_ILAYOUT(@<cls>, @<chead>, const void *@<obj>);}
+  Recovers the instance layout base address from a pointer to one of its
+  instance chains.
+
+  Specifically, given a class name @<cls>, the nickname @<chead> of the least
+  specific class in one of @<cls>'s superclass chains, and a pointer @<obj>
+  to the instance storage for the chain containing @<chead> within a direct
+  instance of @<cls> (i.e., not an instance of any proper subclass),
+  @|SOD_ILAYOUT| returns the a pointer to the layout structure containing
+  @<obj>.
+
+  This macro is used internally in effective method bodies and is not
+  expected to be very useful elsewhere since it's unusual to have such
+  specific knowledge about the dynamic type of an instance.  The
+  @|SOD_INSTBASE| macro (described below) is more suited to general use.
+\end{describe}
+
+\begin{describe}[SOD_CAR]{mac} {@<arg> SOD_CAR(@<arg>, @<other-arg>^*);}
+  Accepts one or more arguments and expands to just its first argument,
+  discarding the others.
+
+  It is only defined if the C implementation advertises support for C99.  It
+  is used in the definitions of message convenience macros for messages which
+  accept a variable number of arguments but no required arguments, and is
+  exported because the author has found such a thing useful in other
+  contexts.
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Utility macros} \label{sec:runtime.utility}
+
+The following macros are expected to be useful in Sod method definitions and
+client code.
+
+\begin{describe}[SOD_CLASSOF]{mac}
+    {const void *SOD_CLASSOF(const @<cls> *@<obj>);}
+  Returns the class object describing an instance's dynamic class.
+
+  Given a pointer @<obj> to an instance, @|SOD_CLASSOF| returns a pointer to
+  @<obj>'s dynamic class, which (assuming @<obj> is typed correctly in the
+  first place) will be a subclass of @<cls>.  (If you wanted the class object
+  for @<cls> itself, it's called @|@<cls>{}__class|.)
+\end{describe}
+
+\begin{describe}[SOD_INSTBASE]{mac}{void *SOD_INSTBASE(const @<cls> *@<obj>)}
+  Finds the base address of an instance's layout.
+
+  Given a pointer @<obj> to an instance, @|SOD_INSTBASE| returns the base
+  address of the storage allocated to @<obj>.  This is useful if you want to
+  free a dynamically allocated instance, for example.
+
+  This macro needs to look up an offset in @<obj>'s vtable to do its work.
+  Compare @|SOD_ILAYOUT| above, which is faster but requires precise
+  knowledge of the instance's dynamic class.
+\end{describe}
+
+\begin{describe}[SOD_CONVERT]{mac}
+    {@<cls> *SOD_CONVERT(@<cls>, const void *@<obj>);}
+
+  Perform general conversions (up-, down-, and cross-casts) on instance
+  pointers.
+
+  Given a class name @<cls> and a pointer @<obj> to an instance,
+  @|SOD_CONVERT| returns an appropriately converted pointer to @<obj> if
+  @<obj> is indeed an instance of (some subclass of) @<cls>; otherwise it
+  returns a null pointer.
+
+  This macro is a simple wrapper around the @|sod_convert| function described
+  below, which is useful in the common case that the target class is known
+  statically.
+\end{describe}
+
+\begin{describe}[SOD_DECL]{mac}{SOD_DECL(@<cls>, @<var>);}
+  Declares and initializes an instance with automatic storage duration.
+
+  Given a class name @<cls> and an identifier @<var>, @|SOD_DECL| declares
+  @<var> to be a pointer to an instance of @<cls>.  The instance is
+  initialized in the sense that its vtable and class pointers have been set
+  up, and slots for which initializers are defined are set to the appropriate
+  initial values.
+
+  The instance has automatic storage duration: pointers to it will become
+  invalid when control exits the scope of the declaration.
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Functions} \label{sec:runtime.functions}
+
+The following functions are provided in @|libsod|.
+
+\begin{describe}[sod_subclassp]{fun}
+    {int sod_subclassp(const SodClass *sub, const SodClass *super);}
+
+  Decide whether one class @<sub> is actually a subclass of another class
+  @<super>.
+
+  The @<sod_subclassp> function returns nonzero if and only if
+  @<sub> is a subclass of @<super>.
+
+  This involves a run-time trawl through the class structures: while some
+  effort has been made to make it perform well it's still not very fast.
+\end{describe}
+
+\begin{describe}[sod_convert]{fun}
+    {void *sod_convert(const SodClass *cls, const void *obj);}
+  Performs general conversions (up-, down-, and cross-casts) on instance
+  pointers.
+
+  Given a class pointer @<cls> and an instance pointer @<obj>, @|sod_convert|
+  returns an appropriately converted pointer to @<obj> in the case that
+  @<obj> is an instance of (some subclass of) @<cls>; otherwise it returns
+  null.
+
+  This involves a run-time trawl through the class structures: while some
+  effort has been made to make it perform well it's still not very fast.  For
+  upcasts (where @<cls> is a superclass of the static type of @<obj>) the
+  automatically defined conversion macros should be used instead, because
+  they're much faster and can't fail.  When the target class is known
+  statically, it's slightly more convenient to use the @|SOD_CONVERT| macro
+  instead.
+\end{describe}
+
+%%%----- That's all, folks --------------------------------------------------
+
+%%% Local variables:
+%%% mode: LaTeX
+%%% TeX-master: "sod.tex"
+%%% TeX-PDF-mode: t
+%%% End:
diff --git a/doc/sod-backg.tex b/doc/sod-backg.tex
deleted file mode 100644 (file)
index 0f19c7d..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-%%% -*-latex-*-
-%%%
-%%% Background philosophy
-%%%
-%%% (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{Philosophical background}
-
-%%%--------------------------------------------------------------------------
-\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.} %
-
-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/sod.sty b/doc/sod.sty
new file mode 100644 (file)
index 0000000..56fc726
--- /dev/null
@@ -0,0 +1,205 @@
+%%% -*-latex-*-
+%%%
+%%% Styles and other hacking for the Sod manual
+%%%
+%%% (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.
+
+\ProvidesPackage{sod}
+
+%% More reference types.
+\defxref{p}{part}
+
+%% Other languages with special typesetting.
+\def\Cplusplus{C\kern-\p@++}
+\def\Csharp{C\#}
+
+%% Special maths notation.
+\def\chain#1#2{\mathsf{ch}_{#1}(#2)}
+\def\chainhead#1#2{\mathsf{hd}_{#1}(#2)}
+\def\chaintail#1#2{\mathsf{tl}_{#1}(#2)}
+
+%% Other mathematical tweaks.
+\let\implies\Rightarrow
+\let\epsilon\varepsilon
+
+%% A table heading cell.  Clone and hack \multicolumn.
+\def\thd{\omit\@ifnextchar[\thd@{\thd@[l]}}
+\def\thd@[#1]#2{%
+  \begingroup
+    \tab@multicol \tab@initread \let\tab@looped\tab@err@multi
+    \tab@preamble{}\def\tab@midtext{\bfseries#2}\tab@readpreamble{#1}%
+    \the\tab@preamble
+  \endgroup \ignorespaces
+}
+
+%% Unix manpage references.
+\def\man#1#2{\textbf{#1}(#2)}
+
+%% Listings don't need to be small.
+\let\listingsize\relax
+
+%% Metavariables are italics without decoration.
+\def\syntleft{\normalfont\itshape}
+\let\syntright\empty
+
+%% Literal code is in sans face.
+\let\codeface\sffamily
+\def\code#1{\ifmmode\hbox\fi{\normalfont\codeface\/#1\/}}
+\def\ulitleft{\normalfont\codeface}
+\let\ulitright\empty
+
+%% Conditionally enter maths mode.  Can't use \ensuremath here because we
+%% aren't necessarily sure where the maths will actually end.
+\let\m@maybe@end\relax
+\def\m@maybe{\ifmmode\else$\let\m@maybe@end$\fi}
+
+%% Standard syntax shortcuts.
+\atdef <#1>{\synt{#1}\@scripts}
+\atdef "#1"{\lit*{#1}\@scripts}
+\atdef `#1'{\lit{#1}\@scripts}
+\atdef |#1|{\textsf{#1}\@scripts}
+
+%% A handy abbreviation; `\\' itself is too good to steal.
+\atdef \\{\textbackslash}
+
+%% Intercept grammar typesetting and replace the vertical bar with the
+%% maths-font version.
+\let\@@grammar\grammar
+\def\grammar{\def\textbar{\hbox{$|$}}\@@grammar}
+
+%% Collect super- and subscripts.  (Note that underscores are active for the
+%% most part.)  When we're done, end maths mode if we entered it
+%% conditionally.
+\def\@scripts{\futurelet\@ch\@scripts@i}
+\begingroup\lccode`\~=`\_\lowercase{\endgroup
+\def\@scripts@i{\if1\ifx\@ch~1\else\ifx\@ch^1\else0\fi\fi%
+  \expandafter\@scripts@ii\else\expandafter\m@maybe@end\fi}}
+\def\@scripts@ii#1#2{\m@maybe#1{#2}\@scripts}
+
+%% Doubling characters, maybe.  Either way, chain onto \@scripts.
+\def\dbl@maybe#1{\let\@tempa#1\futurelet\@ch\dbl@maybe@i}
+\def\dbl@maybe@i{\m@maybe\ifx\@ch\@tempa\@tempa\!\@tempa%
+  \expandafter\@firstoftwo\expandafter\@scripts%
+  \else\@tempa\expandafter\@scripts\fi}
+
+%% Extra syntax for Lisp templates.  These produce the maths-font versions of
+%% characters, which should contrast well against the sans face used for
+%% literals.
+\atdef [{\dbl@maybe[}
+\atdef ]{\dbl@maybe]}
+\atdef {{\m@maybe\{\@scripts}
+\atdef }{\m@maybe\}\@scripts}
+\atdef ({\m@maybe(\@scripts}
+\atdef ){\m@maybe)\@scripts}
+\atdef !{\m@maybe|\@scripts}
+\def\returns{\m@maybe\longrightarrow\m@maybe@end\hspace{0.5em}\ignorespaces}
+\atdef >{\leavevmode\unskip\hspace{0.5em}\returns}
+\atdef -#1{\if>#1{\ensuremath\rightarrow}\fi}
+
+%% Comment setting.
+\atdef ;#1\\{\normalfont\itshape;#1\\}
+
+%% Environment for setting programs.  Newlines are explicit, because
+%% otherwise I need comments in weird places to make the vertical spacing
+%% come out properly.  You can write `\obeylines' if you really want to.
+\def\prog{\codeface\quote\tabbing}
+\def\endprog{\endtabbing\endquote}
+\def\ind{\quad\=\+\kill}
+
+%% Put a chunk of text in a box.
+\newenvironment{boxy}[1][\q@]{%
+  \savenotes
+  \dimen@\linewidth\advance\dimen@-1.2pt\advance\dimen@-2ex%
+  \medskip%
+  \vbox\bgroup\hrule\hbox\bgroup\vrule%
+  \vbox\bgroup\vskip1ex\hbox\bgroup\hskip1ex\minipage\dimen@%
+  \def\@temp{#1}\ifx\@temp\q@\else\leavevmode{\headfam\bfseries#1\quad}\fi%
+}{%
+  \endminipage\hskip1ex\egroup\vskip1ex\egroup%
+  \vrule\egroup\hrule\egroup%
+  \medskip%
+  \spewnotes%
+}
+
+%% Lisp documentation machinery.
+\def\definedescribecategory#1#2{\@namedef{cat!#1}{#2}}
+\def\describecategoryname#1{%
+  \expandafter\let\expandafter\@tempa\csname cat!#1\endcsname%
+  \ifx\@tempa\relax#1\else\@tempa\fi}
+\definedescribecategory{sym}{symbol}
+\definedescribecategory{fun}{function}
+\definedescribecategory{gf}{generic function}
+\definedescribecategory{var}{variable}
+\definedescribecategory{const}{constant}
+\definedescribecategory{meth}{primary method}
+\definedescribecategory{ar-meth}{around method}
+\definedescribecategory{be-meth}{before method}
+\definedescribecategory{af-meth}{after method}
+\definedescribecategory{cls}{class}
+\definedescribecategory{ty}{type}
+\definedescribecategory{mac}{macro}
+\definedescribecategory{lmac}{local macro}
+\definedescribecategory{parse}{parser spec}
+\definedescribecategory{parseform}{parser form}
+\definedescribecategory{opt}{option handler}
+\definedescribecategory{optmac}{option macro}
+\def\nlret{\\\hspace{4em}\returns}
+
+\def\q@{\q@}
+\def\parse@dhd#1{\@ifnextchar[{\parse@dhd@a{#1}}{\parse@dhd@c{#1}}}
+\def\parse@dhd@a#1[#2]{#1{#2}}
+\def\parse@dhd@c#1#2#3{\parse@dhd@cc{#1}{#2}{#3}#3 \q@}
+\def\parse@dhd@cc#1#2#3#4 #5\q@{#1{#4}{#2}{#3}}
+
+\newif\if@dheadfirst
+\def\dhead{\parse@dhd\dhead@}
+\def\dhead@#1#2#3{%
+  \if@dheadfirst\global\@dheadfirstfalse\else\relax\\[\smallskipamount]\fi%
+  {\let\protect\@empty\def\@uscore{_\@gobble}\message{#2:#1}%
+   \def\@uscore{-\@gobble}\edef\@tempa{\noexpand\label{#2:#1}}\@tempa}%
+  \rlap{\rightline{\normalfont\bfseries[\describecategoryname{#2}]}}%
+  #3%
+}
+
+\def\desc@begin#1{%
+  \normalfont%
+  \if@nobreak\else\par\goodbreak\fi%
+  \global\@dheadfirsttrue%
+  \begingroup%
+    \codeface%
+    \let\@endparenv\relax%
+    \clubpenalty\@M \widowpenalty\@M \interlinepenalty50%
+    \tabbing#1\endtabbing%
+  \endgroup%
+  \penalty\@M\@afterheading%
+  \list{}{\rightmargin\z@\topsep\z@}\item%
+}
+\let\desc@end\endlist
+
+\@namedef{describe*}#1{\desc@begin{#1}}
+\expandafter\let\csname enddescribe*\endcsname\desc@end
+\def\describe{\parse@dhd\desc@}
+\def\desc@#1#2#3{\desc@begin{\dhead@{#1}{#2}{#3}}}
+\let\enddescribe\desc@end
+
+%%%----- That's all, folks --------------------------------------------------
+\endinput
index 8a46735..3ee1a5d 100644 (file)
-\documentclass[noarticle]{strayman}
+%%% -*-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.
+
+\documentclass[noarticle, titlepage]{strayman}
+
+\errorcontextlines=999
 
 \usepackage[T1]{fontenc}
 \usepackage[utf8]{inputenc}
 \usepackage[palatino, helvetica, courier, maths=cmr]{mdwfonts}
+\usepackage{tikz}
 \usepackage{syntax}
 \usepackage{sverb}
 \usepackage{mdwtab}
+\usepackage[mdwmargin]{mdwthm}
+\usepackage{amssymb}
 \usepackage{footnote}
 \usepackage{at}
 \usepackage{mdwref}
 
+\usepackage{sod}
+
 \title{A Sensible Object Design for C}
 \author{Mark Wooding}
 
-\makeatletter
-
-\errorcontextlines999
-
-\def\syntleft{\normalfont\itshape}
-\let\syntright\empty
-
-\let\codeface\sffamily
-
-\def\ulitleft{\normalfont\codeface}
-\let\ulitright\empty
-
-\let\listingsize\relax
-
-\let\epsilon\varepsilon
-
-\atdef <#1>{\synt{#1}\@scripts}
-\atdef "#1"{\lit*{#1}\@scripts}
-\atdef `#1'{\lit{#1}\@scripts}
-\atdef |#1|{\textsf{#1}\@scripts}
-\def\dbl@maybe#1{\let\@tempa#1\futurelet\@ch\dbl@maybe@i}
-\def\dbl@maybe@i{\m@maybe\ifx\@ch\@tempa\@tempa\!\@tempa%
-  \expandafter\@firstoftwo\expandafter\@scripts%
-  \else\@tempa\expandafter\@scripts\fi}
-\atdef [{\dbl@maybe[}
-\atdef ]{\dbl@maybe]}
-\atdef {{\m@maybe\{\@scripts}
-\atdef }{\m@maybe\}\@scripts}
-\atdef ({\m@maybe(\@scripts}
-\atdef ){\m@maybe)\@scripts}
-\atdef !{\m@maybe|\@scripts}
-\atdef to{\leavevmode\unskip\quad\m@maybe\longrightarrow\m@maybe@end\quad}
-\let\m@maybe@end\relax
-\def\m@maybe{\ifmmode\else$\let\m@maybe@end$\fi}
-\def\@scripts{\futurelet\@ch\@scripts@i}
-
-\atdef ;#1\\{\normalfont\itshape;#1\\}
-\let\@@grammar\grammar
-\def\grammar{\def\textbar{\hbox{$|$}}\@@grammar}
-
-\begingroup\lccode`\~=`\_\lowercase{\endgroup
-\def\@scripts@i{\if1\ifx\@ch~1\else\ifx\@ch^1\else0\fi\fi%
-  \expandafter\@scripts@ii\else\expandafter\m@maybe@end\fi}}
-\def\@scripts@ii#1#2{\m@maybe#1{#2}\@scripts}
-
-\def\Cplusplus{C\kern-\p@++}
-\def\Csharp{C\#}
-\def\man#1#2{\textbf{#1}(#2)}
-
-\begingroup\lccode`\~=`\
-\lowercase{
-\endgroup
-\def\prog{%
-  \codeface%
-  \quote%
-  \let\old@nl\\%
-  \obeylines%
-  \tabbing%
-  \global\let~\\%
-  \global\let\\\textbackslash%
-}
-\def\endprog{%
-  \endtabbing%
-  \global\let\\\old@nl%
-  \endquote%
-}}
-
-\newenvironment{boxy}[1][\q@]{%
-  \dimen@\linewidth\advance\dimen@-1.2pt\advance\dimen@-2ex%
-  \medskip%
-  \vbox\bgroup\hrule\hbox\bgroup\vrule%
-  \vbox\bgroup\vskip1ex\hbox\bgroup\hskip1ex\minipage\dimen@%
-  \def\@temp{#1}\ifx\@temp\q@\else\leavevmode{\headfam\bfseries#1\quad}\fi%
-}{%
-  \endminipage\hskip1ex\egroup\vskip1ex\egroup%
-  \vrule\egroup\hrule\egroup%
-  \medskip%
-}
-
-\def\definedescribecategory#1#2{\@namedef{cat!#1}{#2}}
-\def\describecategoryname#1{%
-  \expandafter\let\expandafter\@tempa\csname cat!#1\endcsname%
-  \ifx\@tempa\relax#1\else\@tempa\fi}
-\definedescribecategory{fun}{function}
-\definedescribecategory{gf}{generic function}
-\definedescribecategory{var}{variable}
-\definedescribecategory{const}{constant}
-\definedescribecategory{meth}{primary method}
-\definedescribecategory{ar-meth}{around-method}
-\definedescribecategory{be-meth}{before-method}
-\definedescribecategory{af-meth}{after-method}
-\definedescribecategory{cls}{class}
-\definedescribecategory{ty}{type}
-\definedescribecategory{mac}{macro}
-
-\def\q@{\q@}
-\newenvironment{describe}[3][\q@]{%
-  \normalfont%
-  \par\goodbreak%
-  \vspace{\bigskipamount}%
-  \setbox\z@\hbox{\bfseries[\describecategoryname{#2}]}%
-  \dimen@\linewidth\advance\dimen@-\wd\z@%
-  \def\@temp##1 ##2\q@{\message{#2:##1}\label{#2:##1}}%
-  \def\@tempa{#1}\ifx\@tempa\q@\@temp#3 \q@\else\@temp{#1} \\\fi%
-  \edef\@temp{{\the\linewidth}{@{}p{\the\dimen@}%
-      @{\extracolsep{\fill}}l@{\extracolsep{0pt}}}}%
-  \noindent\csname tabular*\expandafter\endcsname\@temp%
-  \tabbing\codeface#3\endtabbing&\unhbox\z@\\\endtabular%
-%  \@afterheading%
-  \list{}{\rightmargin\z@}\item%
-}{%
-  \endlist%
-}
-
-\def\push{\quad\=\+\kill}
-
 \begin{document}
 
+\frontmatter
 \maketitle
 
-\include{sod-tut}
-
 %%%--------------------------------------------------------------------------
-\chapter{Internals}
 
-\section{Generated names}
+\tableofcontents
 
-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[@<class>] The full name of the `focus' class: the one for which we are
-  generating name.
-\item[@<super-nick>] The nickname of a superclass.
-\item[@<head-nick>] The nickname of the chain-head class of the chain
-  in question.
-\end{description}
-
-\subsection{Instance layout}
+\mainmatter
 
 %%%--------------------------------------------------------------------------
-\section{Syntax}
-\label{sec:syntax}
-
-Fortunately, Sod is syntactically quite simple.  I've used a little slightly
-unusual notation in order to make the presentation easier to read.
-\begin{itemize}
-\item $\epsilon$ denotes the empty nonterminal:
-  \begin{quote}
-    $\epsilon$ ::=
-  \end{quote}
-\item @[@<item>@] means an optional @<item>:
-  \begin{quote}
-    \syntax{@[<item>@] ::= $\epsilon$ @! <item>}
-  \end{quote}
-\item @<item>^* means a sequence of zero or more @<item>s:
-  \begin{quote}
-    \syntax{@<item>^* ::= $\epsilon$ @! @<item>^* <item>}
-  \end{quote}
-\item @<item>^+ means a sequence of one or more @<item>s:
-  \begin{quote}
-    \syntax{@<item>^+ ::= <item> @<item>^*}
-  \end{quote}
-\item @<item-list> means a sequence of one or more @<item>s separated
-  by commas:
-  \begin{quote}
-    \syntax{<item-list> ::= <item> @! <item-list> "," <item>}
-  \end{quote}
-\end{itemize}
-
-\subsection{Lexical syntax}
-\label{sec:syntax.lex}
-
-Whitespace and comments are discarded.  The remaining characters are
-collected into tokens according to the following syntax.
-
-\begin{grammar}
-<token> ::= <identifier>
-\alt <reserved-word>
-\alt <string-literal>
-\alt <char-literal>
-\alt <integer-literal>
-\alt <punctuation>
-\end{grammar}
-
-This syntax is slightly ambiguous.  The following two rules serve to
-disambiguate:
-\begin{enumerate}
-\item Reserved words take precedence.  All @<reserved-word>s are
-  syntactically @<identifier>s; Sod resolves the ambiguity in favour of
-  @<reserved-word>.
-\item `Maximal munch'.  In other cases, at each stage we take the longest
-  sequence of characters which could be a token.
-\end{enumerate}
-
-\subsubsection{Identifiers} \label{sec:syntax.lex.id}
-
-\begin{grammar}
-<identifier> ::= <id-start-char> @<id-body-char>^*
-
-<id-start-char> ::= <alpha-char> | "_"
-
-<id-body-char> ::= <id-start-char> @! <digit-char>
-
-<alpha-char> ::= "A" | "B" | \dots\ | "Z"
-\alt "a" | "b" | \dots\ | "z"
-\alt <extended-alpha-char>
-
-<digit-char> ::= "0" | <nonzero-digit-char>
-
-<nonzero-digit-char> ::= "1" | "2" $| \cdots |$ "9"
-\end{grammar}
-
-The precise definition of @<alpha-char> is left to the function
-\textsf{alpha-char-p} in the hosting Lisp system.  For portability,
-programmers are encouraged to limit themselves to the standard ASCII letters.
-
-\subsubsection{Reserved words} \label{sec:syntax.lex.reserved}
-
-\begin{grammar}
-<reserved-word> ::=
-"char" | "class" | "code" | "const" | "double" | "enum" |
-"extern" | "float" | "import" | "int" | "lisp" | "load" | "long"
-| "restrict" | "short" | "signed" | "struct" | "typename" |
-"union" | "unsigned" | "void" | "volatile"
-\end{grammar}
-
-Many of these are borrowed from~C; however, some (e.g., @"import" and
-@"lisp") are not, and some C reserved words are not reserved (e.g.,
-@"static").
-
-\subsubsection{String and character literals} \label{sec:syntax.lex.string}
-
-\begin{grammar}
-<string-literal> ::= "\"" @<string-literal-char>^* "\""
-
-<char-literal> ::= "'" <char-literal-char> "'"
-
-<string-literal-char> ::= any character other than "\\" or "\""
-\alt "\\" <char>
-
-<char-literal-char> ::= any character other than "\\" or "'"
-\alt "\\" <char>
-
-<char> ::= any single character
-\end{grammar}
-
-The syntax for string and character literals differs from~C.  In particular,
-escape sequences such as @`\textbackslash n' are not recognized.  The use
-of string and character literals in Sod, outside of C~fragments, is limited,
-and the simple syntax seems adequate.  For the sake of future compatibility,
-the use of character sequences which resemble C escape sequences is
-discouraged.
-
-\subsubsection{Integer literals} \label{sec:syntax.lex.int}
-
-\begin{grammar}
-<integer-literal> ::= <decimal-integer>
-\alt <binary-integer>
-\alt <octal-integer>
-\alt <hex-integer>
-
-<decimal-integer> ::= <nonzero-digit-char> @<digit-char>^*
-
-<binary-integer> ::= "0" @("b"|"B"@) @<binary-digit-char>^+
-
-<binary-digit-char> ::= "0" | "1"
-
-<octal-integer> ::= "0" @["o"|"O"@] @<octal-digit-char>^+
-
-<octal-digit-char> ::= "0" | "1" $| \cdots |$ "7"
-
-<hex-integer> ::= "0" @("x"|"X"@) @<hex-digit-char>^+
-
-<hex-digit-char> ::= <digit-char>
-\alt "A" | "B" | "C" | "D" | "E" | "F"
-\alt "a" | "b" | "c" | "d" | "e" | "f"
-\end{grammar}
-
-Sod understands only integers, not floating-point numbers; its integer syntax
-goes slightly beyond C in allowing a @`0o' prefix for octal and @`0b' for
-binary.  However, length and signedness indicators are not permitted.
-
-\subsubsection{Punctuation} \label{sec:syntax.lex.punct}
-
-\begin{grammar}
-<punctuation> ::= any character other than "\"" or "'"
-\end{grammar}
-
-Due to the `maximal munch' rule, @<punctuation> tokens cannot be
-alphanumeric.
-
-\subsubsection{Comments} \label{sec:lex-comment}
-
-\begin{grammar}
-<comment> ::= <block-comment>
-\alt <line-comment>
-
-<block-comment> ::=
-  "/*"
-  @<not-star>^* @(@<star>^+ <not-star-or-slash> @<not-star>^*@)^*
-  @<star>^*
-  "*/"
-
-<star> ::= "*"
-
-<not-star> ::= any character other than "*"
-
-<not-star-or-slash> ::= any character other than "*" or  "/"
-
-<line-comment> ::= "//" @<not-newline>^* <newline>
-
-<newline> ::= a newline character
-
-<not-newline> ::= any character other than newline
-\end{grammar}
-
-Comments are exactly as in C99: both traditional block comments `\texttt{/*}
-\dots\ \texttt{*/}' and \Cplusplus-style `\texttt{//} \dots' comments are
-permitted and ignored.
-
-\subsection{Special nonterminals}
-\label{sec:special-nonterminals}
-
-Aside from the lexical syntax presented above (\xref{sec:lexical-syntax}),
-two special nonterminals occur in the module syntax.
-
-\subsubsection{S-expressions} \label{sec:syntax-sexp}
-
-\begin{grammar}
-<s-expression> ::= an S-expression, as parsed by the Lisp reader
-\end{grammar}
-
-When an S-expression is expected, the Sod parser simply calls the host Lisp
-system's \textsf{read} function.  Sod modules are permitted to modify the
-read table to extend the S-expression syntax.
-
-S-expressions are self-delimiting, so no end-marker is needed.
-
-\subsubsection{C fragments} \label{sec:syntax.lex.cfrag}
-
-\begin{grammar}
-<c-fragment> ::= a sequence of C tokens, with matching brackets
-\end{grammar}
-
-Sequences of C code are simply stored and written to the output unchanged
-during translation.  They are read using a simple scanner which nonetheless
-understands C comments and string and character literals.
-
-A C fragment is terminated by one of a small number of delimiter characters
-determined by the immediately surrounding context -- usually a closing brace
-or bracket.  The first such delimiter character which is not enclosed in
-brackets, braces or parenthesis ends the fragment.
-
-\subsection{Module syntax} \label{sec:syntax-module}
-
-\begin{grammar}
-<module> ::= @<definition>^*
-
-<definition> ::= <import-definition>
-\alt <load-definition>
-\alt <lisp-definition>
-\alt <code-definition>
-\alt <typename-definition>
-\alt <class-definition>
-\end{grammar}
-
-A module is the top-level syntactic item.  A module consists of a sequence of
-definitions.
-
-\subsection{Simple definitions} \label{sec:syntax.defs}
-
-\subsubsection{Importing modules} \label{sec:syntax.defs.import}
-
-\begin{grammar}
-<import-definition> ::= "import" <string> ";"
-\end{grammar}
-
-The module named @<string> is processed and its definitions made available.
-
-A search is made for a module source file as follows.
-\begin{itemize}
-\item The module name @<string> is converted into a filename by appending
-  @`.sod', if it has no extension already.\footnote{%
-    Technically, what happens is \textsf{(merge-pathnames name (make-pathname
-    :type "SOD" :case :common))}, so exactly what this means varies
-    according to the host system.} %
-\item The file is looked for relative to the directory containing the
-  importing module.
-\item If that fails, then the file is looked for in each directory on the
-  module search path in turn.
-\item If the file still isn't found, an error is reported and the import
-  fails.
-\end{itemize}
-At this point, if the file has previously been imported, nothing further
-happens.\footnote{%
-  This check is done using \textsf{truename}, so it should see through simple
-  tricks like symbolic links.  However, it may be confused by fancy things
-  like bind mounts and so on.} %
-
-Recursive imports, either direct or indirect, are an error.
-
-\subsubsection{Loading extensions} \label{sec:syntax.defs.load}
-
-\begin{grammar}
-<load-definition> ::= "load" <string> ";"
-\end{grammar}
-
-The Lisp file named @<string> is loaded and evaluated.
-
-A search is made for a Lisp source file as follows.
-\begin{itemize}
-\item The name @<string> is converted into a filename by appending @`.lisp',
-  if it has no extension already.\footnote{%
-    Technically, what happens is \textsf{(merge-pathnames name (make-pathname
-    :type "LISP" :case :common))}, so exactly what this means varies
-    according to the host system.} %
-\item A search is then made in the same manner as for module imports
-  (\xref{sec:syntax-module}).
-\end{itemize}
-If the file is found, it is loaded using the host Lisp's \textsf{load}
-function.
-
-Note that Sod doesn't attempt to compile Lisp files, or even to look for
-existing compiled files.  The right way to package a substantial extension to
-the Sod translator is to provide the extension as a standard ASDF system (or
-similar) and leave a dropping @"foo-extension.lisp" in the module path saying
-something like
-\begin{listing}
-(asdf:operate 'asdf:load-op :foo-extension)
-\end{listing}
-which will arrange for the extension to be compiled if necessary.
-
-(This approach means that the language doesn't need to depend on any
-particular system definition facility.  It's bad enough already that it
-depends on Common Lisp.)
-
-\subsubsection{Lisp escapes} \label{sec:syntax.defs.lisp}
-
-\begin{grammar}
-<lisp-definition> ::= "lisp" <s-expression> ";"
-\end{grammar}
-
-The @<s-expression> is evaluated immediately.  It can do anything it likes.
-
-\textbf{Warning!}  This means that hostile Sod modules are a security hazard.
-Lisp code can read and write files, start other programs, and make network
-connections.  Don't install Sod modules from sources that you don't
-trust.\footnote{%
-  Presumably you were going to run the corresponding code at some point, so
-  this isn't as unusually scary as it sounds.  But please be careful.} %
-
-\subsubsection{Declaring type names} \label{sec:syntax.defs.typename}
-
-\begin{grammar}
-<typename-definition> ::=
-  "typename" <identifier-list> ";"
-\end{grammar}
-
-Each @<identifier> is declared as naming a C type.  This is important because
-the C type syntax -- which Sod uses -- is ambiguous, and disambiguation is
-done by distinguishing type names from other identifiers.
-
-Don't declare class names using @"typename"; use @"class" forward
-declarations instead.
-
-\subsection{Literal code} \label{sec:syntax-code}
-
-\begin{grammar}
-<code-definition> ::=
-  "code" <identifier> ":" <identifier> @[<constraints>@]
-  "{" <c-fragment> "}"
-
-<constraints> ::= "[" <constraint-list> "]"
-
-<constraint> ::= @<identifier>^+
-\end{grammar}
-
-The @<c-fragment> will be output unchanged to one of the output files.
-
-The first @<identifier> is the symbolic name of an output file.  Predefined
-output file names are @"c" and @"h", which are the implementation code and
-header file respectively; other output files can be defined by extensions.
+\part{Tutorial} \label{p:tut}
 
-The second @<identifier> provides a name for the output item.  Several C
-fragments can have the same name: they will be concatenated together in the
-order in which they were encountered.
-
-The @<constraints> provide a means for specifying where in the output file
-the output item should appear.  (Note the two kinds of square brackets shown
-in the syntax: square brackets must appear around the constraints if they are
-present, but that they may be omitted.)  Each comma-separated @<constraint>
-is a sequence of identifiers naming output items, and indicates that the
-output items must appear in the order given -- though the translator is free
-to insert additional items in between them.  (The particular output items
-needn't be defined already -- indeed, they needn't be defined ever.)
-
-There is a predefined output item @"includes" in both the @"c" and @"h"
-output files which is a suitable place for inserting @"\#include"
-preprocessor directives in order to declare types and functions for use
-elsewhere in the generated output files.
-
-\subsection{Property sets} \label{sec:syntax.propset}
-
-\begin{grammar}
-<properties> ::= "[" <property-list> "]"
-
-<property> ::= <identifier> "=" <expression>
-\end{grammar}
-
-Property sets are a means for associating miscellaneous information with
-classes and related items.  By using property sets, additional information
-can be passed to extensions without the need to introduce idiosyncratic
-syntax.
-
-A property has a name, given as an @<identifier>, and a value computed by
-evaluating an @<expression>.  The value can be one of a number of types,
-though the only operators currently defined act on integer values only.
-
-\subsubsection{The expression evaluator} \label{sec:syntax.propset.expr}
-
-\begin{grammar}
-<expression> ::= <term> | <expression> "+" <term> | <expression> "-" <term>
-
-<term> ::= <factor> | <term> "*" <factor> | <term> "/" <factor>
-
-<factor> ::= <primary> | "+" <factor> | "-" <factor>
-
-<primary> ::=
-     <integer-literal> | <string-literal> | <char-literal> | <identifier>
-\alt "?" <s-expression>
-\alt "(" <expression> ")"
-\end{grammar}
-
-The arithmetic expression syntax is simple and standard; there are currently
-no bitwise, logical, or comparison operators.
-
-A @<primary> expression may be a literal or an identifier.  Note that
-identifiers stand for themselves: they \emph{do not} denote values.  For more
-fancy expressions, the syntax
-\begin{quote}
-  @"?" @<s-expression>
-\end{quote}
-causes the @<s-expression> to be evaluated using the Lisp \textsf{eval}
-function.
-%%% FIXME crossref to extension docs
-
-\subsection{C types} \label{sec:syntax.c-types}
-
-Sod's syntax for C types closely mirrors the standard C syntax.  A C type has
-two parts: a sequence of @<declaration-specifier>s and a @<declarator>.  In
-Sod, a type must contain at least one @<declaration-specifier> (i.e.,
-`implicit @"int"' is forbidden), and storage-class specifiers are not
-recognized.
-
-\subsubsection{Declaration specifiers} \label{sec:syntax.c-types.declspec}
-
-\begin{grammar}
-<declaration-specifier> ::= <type-name>
-\alt "struct" <identifier> | "union" <identifier> | "enum" <identifier>
-\alt "void" | "char" | "int" | "float" | "double"
-\alt "short" | "long"
-\alt "signed" | "unsigned"
-\alt <qualifier>
-
-<qualifier> ::= "const" | "volatile" | "restrict"
-
-<type-name> ::= <identifier>
-\end{grammar}
-
-A @<type-name> is an identifier which has been declared as being a type name,
-using the @"typename" or @"class" definitions.
-
-Declaration specifiers may appear in any order.  However, not all
-combinations are permitted.  A declaration specifier must consist of zero or
-more @<qualifiers>, and one of the following, up to reordering.
-\begin{itemize}
-\item @<type-name>
-\item @"struct" @<identifier>, @"union" @<identifier>, @"enum" @<identifier>
-\item @"void"
-\item @"char", @"unsigned char", @"signed char"
-\item @"short", @"unsigned short", @"signed short"
-\item @"short int", @"unsigned short int", @"signed short int"
-\item @"int", @"unsigned int", @"signed int", @"unsigned", @"signed"
-\item @"long", @"unsigned long", @"signed long"
-\item @"long int", @"unsigned long int", @"signed long int"
-\item @"long long", @"unsigned long long", @"signed long long"
-\item @"long long int", @"unsigned long long int", @"signed long long int"
-\item @"float", @"double", @"long double"
-\end{itemize}
-All of these have their usual C meanings.
-
-\subsubsection{Declarators} \label{sec:syntax.c-types.declarator}
-
-\begin{grammar}
-<declarator>$[k]$ ::= @<pointer>^* <primary-declarator>$[k]$
-
-<primary-declarator>$[k]$ ::= $k$
-\alt "(" <primary-declarator>$[k]$ ")"
-\alt <primary-declarator>$[k]$ @<declarator-suffix>^*
-
-<pointer> ::= "*" @<qualifier>^*
-
-<declarator-suffix> ::= "[" <c-fragment> "]"
-\alt "(" <arguments> ")"
-
-<arguments> ::= $\epsilon$ | "..."
-\alt <argument-list> @["," "..."@]
-
-<argument> ::= @<declaration-specifier>^+ <argument-declarator>
-
-<argument-declarator> ::= <declarator>@[<identifier> @! $\epsilon$@]
-
-<simple-declarator> ::= <declarator>@[<identifier>@]
-
-<dotted-name> ::= <identifier> "." <identifier>
-
-<dotted-declarator> ::= <declarator>@[<dotted-name>@]
-\end{grammar}
-
-The declarator syntax is taken from C, but with some differences.
-\begin{itemize}
-\item Array dimensions are uninterpreted @<c-fragments>, terminated by a
-  closing square bracket.  This allows array dimensions to contain arbitrary
-  constant expressions.
-\item A declarator may have either a single @<identifier> at its centre or a
-  pair of @<identifier>s separated by a @`.'; this is used to refer to
-  slots or messages defined in superclasses.
-\end{itemize}
-The remaining differences are (I hope) a matter of presentation rather than
-substance.
-
-\subsection{Defining classes} \label{sec:syntax.class}
-
-\begin{grammar}
-<class-definition> ::= <class-forward-declaration>
-\alt <full-class-definition>
-\end{grammar}
-
-\subsubsection{Forward declarations} \label{sec:class.class.forward}
-
-\begin{grammar}
-<class-forward-declaration> ::= "class" <identifier> ";"
-\end{grammar}
-
-A @<class-forward-declaration> informs Sod that an @<identifier> will be used
-to name a class which is currently undefined.  Forward declarations are
-necessary in order to resolve certain kinds of circularity.  For example,
-\begin{listing}
-class Sub;
-
-class Super : SodObject {
-  Sub *sub;
-};
-
-class Sub : Super {
-  /* ... */
-};
-\end{listing}
-
-\subsubsection{Full class definitions} \label{sec:class.class.full}
-
-\begin{grammar}
-<full-class-definition> ::=
-  @[<properties>@]
-  "class" <identifier> ":" <identifier-list>
-  "{" @<class-item>^* "}"
-
-<class-item> ::= <slot-item> ";"
-\alt <message-item>
-\alt <method-item>
-\alt  <initializer-item> ";"
-\end{grammar}
-
-A full class definition provides a complete description of a class.
-
-The first @<identifier> gives the name of the class.  It is an error to
-give the name of an existing class (other than a forward-referenced class),
-or an existing type name.  It is conventional to give classes `MixedCase'
-names, to distinguish them from other kinds of identifiers.
-
-The @<identifier-list> names the direct superclasses for the new class.  It
-is an error if any of these @<identifier>s does not name a defined class.
-
-The @<properties> provide additional information.  The standard class
-properties are as follows.
-\begin{description}
-\item[@"lisp_class"] The name of the Lisp class to use within the translator
-  to represent this class.  The property value must be an identifier; the
-  default is @"sod_class".  Extensions may define classes with additional
-  behaviour, and may recognize additional class properties.
-\item[@"metaclass"] The name of the Sod metaclass for this class.  In the
-  generated code, a class is itself an instance of another class -- its
-  \emph{metaclass}.  The metaclass defines which slots the class will have,
-  which messages it will respond to, and what its behaviour will be when it
-  receives them.  The property value must be an identifier naming a defined
-  subclass of @"SodClass".  The default metaclass is @"SodClass".
-  %%% FIXME xref to theory
-\item[@"nick"] A nickname for the class, to be used to distinguish it from
-  other classes in various limited contexts.  The property value must be an
-  identifier; the default is constructed by forcing the class name to
-  lower-case.
-\end{description}
-
-The class body consists of a sequence of @<class-item>s enclosed in braces.
-These items are discussed on the following sections.
-
-\subsubsection{Slot items} \label{sec:sntax.class.slot}
-
-\begin{grammar}
-<slot-item> ::=
-  @[<properties>@]
-  @<declaration-specifier>^+ <init-declarator-list>
-
-<init-declarator> ::= <declarator> @["=" <initializer>@]
-\end{grammar}
-
-A @<slot-item> defines one or more slots.  All instances of the class and any
-subclass will contain these slot, with the names and types given by the
-@<declaration-specifiers> and the @<declarators>.  Slot declarators may not
-contain qualified identifiers.
-
-It is not possible to declare a slot with function type: such an item is
-interpreted as being a @<message-item> or @<method-item>.  Pointers to
-functions are fine.
-
-An @<initializer>, if present, is treated as if a separate
-@<initializer-item> containing the slot name and initializer were present.
-For example,
-\begin{listing}
-[nick = eg]
-class Example : Super {
-  int foo = 17;
-};
-\end{listing}
-means the same as
-\begin{listing}
-[nick = eg]
-class Example : Super {
-  int foo;
-  eg.foo = 17;
-};
-\end{listing}
-
-\subsubsection{Initializer items} \label{sec:syntax.class.init}
-
-\begin{grammar}
-<initializer-item> ::= @["class"@] <slot-initializer-list>
-
-<slot-initializer> ::= <qualified-identifier> "=" <initializer>
-
-<initializer> :: "{" <c-fragment> "}" | <c-fragment>
-\end{grammar}
-
-An @<initializer-item> provides an initial value for one or more slots.  If
-prefixed by @"class", then the initial values are for class slots (i.e.,
-slots of the class object itself); otherwise they are for instance slots.
-
-The first component of the @<qualified-identifier> must be the nickname of
-one of the class's superclasses (including itself); the second must be the
-name of a slot defined in that superclass.
-
-The initializer has one of two forms.
-\begin{itemize}
-\item A @<c-fragment> enclosed in braces denotes an aggregate initializer.
-  This is suitable for initializing structure, union or array slots.
-\item A @<c-fragment> \emph{not} beginning with an open brace is a `bare'
-  initializer, and continues until the next @`,' or @`;' which is not within
-  nested brackets.  Bare initializers are suitable for initializing scalar
-  slots, such as pointers or integers, and strings.
-\end{itemize}
-
-\subsubsection{Message items} \label{sec:syntax.class.message}
-
-\begin{grammar}
-<message-item> ::=
-  @[<properties>@]
-  @<declaration-specifier>^+ <declarator> @[<method-body>@]
-\end{grammar}
-
-\subsubsection{Method items} \label{sec:syntax.class.method}
-
-\begin{grammar}
-<method-item> ::=
-  @[<properties>@]
-  @<declaration-specifier>^+ <declarator> <method-body>
-
-<method-body> ::= "{" <c-fragment> "}" | "extern" ";"
-\end{grammar}
+\include{tutorial}
 
 %%%--------------------------------------------------------------------------
-\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;
+\part{Reference} \label{p:ref}
 
-  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}
+\include{concepts}
+\include{cmdline}
+\include{syntax}
+\include{runtime}
+\include{structures}
 
 %%%--------------------------------------------------------------------------
-\section{Classes}
+\part{Lisp interface} \label{p:lisp}
+
+\include{lispintro}
+%% package.lisp
+%% sod.asd.in
+%% sod-frontend.asd.in
+%% auto.lisp.in
+
+\include{misc}
+%% utilities.lisp
+%% pset-impl.lisp
+%% pset-parse.lisp
+%% pset-proto.lisp
+%% optparse.lisp
+%% frontend.lisp
+%% final.lisp
+
+\include{parsing}
+%% package.lisp
+%% floc-impl.lisp
+%% floc-proto.lisp
+%% streams-impl.lisp
+%% streams-proto.lisp
+%% scanner-context-impl.lisp
+%% scanner-impl.lisp
+%% scanner-proto.lisp
+%% scanner-token-impl.lisp
+%% scanner-charbuf-impl.lisp
+%% parser-impl.lisp
+%% parser-proto.lisp
+%% parser-expr-impl.lisp
+%% parser-expr-proto.lisp
+%% lexer-impl.lisp
+%% lexer-proto.lisp
+
+\include{clang}
+%% c-types-class-impl.lisp
+%% c-types-impl.lisp
+%% c-types-parse.lisp
+%% c-types-proto.lisp
+%% codegen-impl.lisp
+%% codegen-proto.lisp
+%% fragment-parse.lisp
+
+\include{meta}
+%% classes.lisp
+%% class-utilities.lisp
+%% class-make-impl.lisp
+%% class-make-proto.lisp
+%% class-finalize-impl.lisp
+%% class-finalize-proto.lisp
+
+\include{layout}
+%% class-layout-impl.lisp
+%% class-layout-proto.lisp
+%% method-impl.lisp
+%% method-proto.lisp
+%% method-aggregate.lisp
+
+\include{module}
+%% module-impl.lisp
+%% module-parse.lisp
+%% module-proto.lisp
+%% builtin.lisp
+
+\include{output}
+%% output-impl.lisp
+%% output-proto.lisp
+%% class-output.lisp
+%% module-output.lisp
 
-\subsection{Classes and superclasses}
-
-A @<full-class-definition> 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}
-
-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}
-
-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.
-
-\subsection{Items and inheritance}
-
-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}
-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}
-Mumble.
-
-\subsubsection{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}
-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}
+%%%--------------------------------------------------------------------------
+\part{Appendices}
+\appendix
 
-\include{sod-backg}
-\include{sod-protocol}
+\include{cutting-room-floor}
 
+%%%----- That's all, folks --------------------------------------------------
 \end{document}
-\f
+
 %%% Local variables:
 %%% mode: LaTeX
 %%% TeX-PDF-mode: t
diff --git a/doc/structures.tex b/doc/structures.tex
new file mode 100644 (file)
index 0000000..561075b
--- /dev/null
@@ -0,0 +1,584 @@
+%%% -*-latex-*-
+%%%
+%%% In-depth exploration of the generated structures
+%%%
+%%% (c) 2015 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{Object structures} \label{ch:structures}
+
+This chapter describes the structure and layout of standard Sod objects,
+classes and associated metadata.  Note that Sod's object system is very
+flexible and it's possible for an extension to define a new root class which
+works very differently from the standard @|SodObject| described here.
+
+The concrete types described in \xref{sec:structures.common} and
+\ref{sec:structures.root} are declared by the header file @|<sod/sod.h>|.
+The definitions described in sections \ref{sec:structures.layout} are defined
+in the header file generated by the containing module.
+
+%%%--------------------------------------------------------------------------
+\section{Common instance structure} \label{sec:structures.common}
+
+As described below, a pointer to an instance actually points to an
+\emph{instance chain} structure within the instances overall layout
+structure.
+
+Instance chains contain slots and vtable pointers, as described below.  All
+instances have the basic structure of a @|struct sod_instance|.
+
+\begin{describe}[struct sod_instance]{type}
+    {struct sod_instance \{ \\ \ind
+       const struct sod_vtable *_vt; \- \\
+     \};}
+
+  The basic structure of all instances.  Members are as follows.
+  \begin{description} \let\makelabel\code
+  \item[_vt] A pointer to a \emph{vtable}, which has the basic structure of a
+    @|struct sod_vtable|, described below.
+  \end{description}
+\end{describe}
+
+\begin{describe}[struct sod_vtable]{type}
+    {struct sod_vtable \{ \\ \ind
+       const SodClass *_class; \\
+       size_t _base; \- \\
+     \};}
+
+  A vtable contains static metadata needed for efficient conversions and
+  message dispatch, and pointers to the instance's class.  Each chain points
+  to a different vtable.  All vtables have the basic structure of a @|struct
+  sod_vtable|, which has the following members.
+  \begin{description} \let\makelabel\code
+  \item[_class] A pointer to the instance's class object.
+  \item[_base] The offset of this chain structure above the start of the
+    overall instance layout, in bytes.  Subtracting @|_base| from the
+    instance chain pointer finds the layout base address.
+  \end{description}
+\end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Built-in root objects} \label{sec:structures.root}
+
+This section describes the built-in classes @|SodObject| and @|SodClass|,
+which are the standard roots of the inheritance and metaclass graphs
+respectively.  Specifically, @|SodObject| has no direct superclasses, and
+@|SodClass| is its own metaclass.  It is not possible to define root classes
+in module files because of circularities: @|SodObject| has @|SodClass| as its
+metaclass, and @|SodClass| is a subclass of @|SodObject|.  Extensions can
+define additional root classes, but this is tricky, and not really to be
+recommended.
+
+\subsection{The SodObject class} \label{sec:structures.root.sodobject}
+
+\begin{figure}[tbp]
+  \begin{tabular}{p{10pt}p{10pt}}
+    \begin{prog}
+      struct SodObject__ilayout \{ \\ \ind
+        union \{ \\ \ind
+          struct SodObject__ichain_obj \{ \\ \ind
+            const struct SodObject__vt_obj *_vt; \- \\
+          \}; \- \\
+        \} obj; \- \\
+      \};
+    \end{prog}
+    &
+    \begin{prog}
+      struct SodObject__vt_obj \{ \\ \ind
+        const SodClass *_class; \\
+        size_t _base; \- \\
+      \};
+    \end{prog} \\
+  \end{tabular}
+  \caption{Instance and vtable layout of @|SodObject|}
+  \label{fig:structures.root.sodobject}
+\end{figure}
+
+\begin{describe}[SodObject]{cls}
+    {[metaclass = SodClass, lisp_metaclass = sod_class] \\
+     class SodObject \{ \}}
+
+  The @|SodObject| class defines no slots or messages.  Because @|SodObject|
+  has no direct superclasses, there is only one chain, and no inherited
+  slots or messages, so the single chain contains only a vtable pointer.
+
+  Since there are no messages, and @|SodClass| also has only one chain, the
+  vtable contains only the standard class pointer and offset-to-base members.
+  In a direct instance of @|SodObject| (why would you want one?)  the class
+  pointer contains the address of @|SodObject__class| and the offset is zero.
+
+  The instance and vtable layout of @|SodObject| is shown in
+  \xref{fig:structures.root.sodobject}.
+\end{describe}
+
+\subsection{The SodClass class} \label{sec:structures.root.sodclass}
+
+\begin{describe}[SodClass]{cls}
+    {class SodClass : SodObject \{ \\ \ind
+       const char *name; \\
+       const char *nick; \\
+       size_t initsz; \\
+       void *(*imprint)(void *@<p>); \\
+       void *(*init)(void *@<p>); \\
+       size_t n_supers; \\
+       const SodClass *const *supers; \\
+       size_t n_cpl; \\
+       const SodClass *const *cpl; \\
+       const SodClass *link; \\
+       const SodClass *head; \\
+       size_t level; \\
+       size_t n_chains; \\
+       const struct sod_chain *chains; \\
+       size_t off_islots; \\
+       size_t islotsz; \- \\
+     \}}
+
+  The @|SodClass| class defines no messages, but there are a number of slots.
+  Its only direct superclass is @|SodObject| and so (like its superclass) its
+  vtable is trivial.
+
+  The slots defined are as follows.
+  \begin{description} \let\makelabel\code
+
+  \item[name] A pointer to the class's name.
+
+  \item[nick] A pointer to the class's nickname.
+
+  \item[initsz] The size in bytes required to store an instance of the class.
+
+  \item[imprint] A pointer to a function: given a pointer @<p> to at least
+    @<initsz> bytes of appropriately aligned memory, `imprint' this memory it
+    so that it becomes a minimally functional instance of the class: all of
+    the vtable and class pointers are properly initialized, but the slots are
+    left untouched.  The function returns its argument @<p>.
+
+  \item[init] A pointer to a function: given a pointer @<p> to at least
+    @<initsz> bytes of appropriately aligned memory, initialize an instance
+    of the class in it: all of the vtable and class pointers are initialized,
+    as are slots for which initializers are defined.  Other slots are left
+    untouched.  The function returns its argument @<p>.
+
+  \item[n_supers] The number of direct superclasses.  (This is zero exactly
+    in the case of @|SodObject|.)
+
+  \item[supers] A pointer to an array of @<n_supers> pointers to class
+    objects listing the class's direct superclasses, in the order in which
+    they were listed in the class definition.  If @<n_supers> is zero, then
+    this pointer is null.
+
+  \item[n_cpl] The number of superclasses in the class's class precedence
+    list.
+
+  \item[cpl] A pointer to an array of pointers to class objects listing all
+    of the class's superclasses, from most- to least-specific, starting with
+    the class itself, so $c@->@|cls|.@|cpl|[0] = c$ for all class objects
+    $c$.
+
+  \item[link] If the class is a chain head, then this is a null pointer;
+    otherwise it points to the class's distinguished link superclass (which
+    might or might not be a direct superclass).
+
+  \item[head] A pointer to the least-specific class in this class's chain; so
+    $c@->@|cls|.@|head|@->@|cls|.@|link|$ is always null, and either
+    $c@->@|cls|.@|link|$ is null (in which case $c@->@|cls|.@|head| = c$) or
+    $c@->@|cls|.@|head| = c@->@|cls|.@|link|@->@|cls|.@|head|$.
+
+  \item[level] The number of less specific superclasses in this class's
+    chain.  If $c@->@|cls|.@|link|$ is null then $c@->@|cls|.@|level|$ is
+    zero; otherwise $c@->@|cls|.@|level| =
+    c@->@|cls|.@|link|@->@|cls|.@|level| + 1$.
+
+  \item[n_chains] The number of chains formed by the class's superclasses.
+
+  \item[chains] A pointer to an array of @|struct sod_chain| structures (see
+    below) describing the class's superclass chains, in decreasing order of
+    specificity of their most specific classes.  It is always the case that
+    $c@->@|cls|.@|chains|[0].@|classes|[c@->@|cls|.@|level|] = c$.
+
+  \item[off_islots] The offset of the class's @|islots| structure relative to
+    its containing @|ichain| structure.  The class doesn't define any slots
+    if and only if this is zero.  (The offset can't be zero because the
+    vtable pointer is at offset zero.)
+
+  \item[islotsz] The size required to store the class's direct slots, i.e.,
+    the size of its @|islots| structure.  The class doesn't define any slots
+    if and only if this is zero.
+
+  \end{description}
+\end{describe}
+
+\begin{describe}[struct sod_chain]{type}
+    {struct sod_chain \{ \\ \ind
+       size_t n_classes; \\
+       const SodClass *const *classes; \\
+       size_t off_ichain; \\
+       const struct sod_vtable *vt; \\
+       size_t ichainsz; \- \\
+     \};}
+
+   The @|struct sod_chain| structure describes an individual chain of
+   superclasses.  It has the following members.
+   \begin{description} \let\makelabel\code
+
+   \item[n_classes] The number of classes in the chain.  This is always at
+     least one.
+
+   \item[classes] A pointer to an array of class pointers listing the classes
+     in the chain from least- to most-specific.  So
+     $@<classes>[i]@->@|cls|.@|head| = @<classes>[0]$ for all $0 \le i <
+     @<n_classes>$, $@<classes>[0]@->@|cls|.@|link|$ is always null, and
+     $@<classes>[i]@->@|cls|.@|link| = @<classes>[i - 1]$ if $1 \le i <
+     @<n_classes>$.
+
+   \item[off_ichain] The size of the @|ichain| structure for this chain.
+
+   \item[vt] The vtable for this chain.  (It is possible, therefore, to
+     partially duplicate the behaviour of the @<imprint> function by walking
+     the chain structure.\footnote{%
+       There isn't enough information readily available to fill in the class
+       pointers correctly.} %
+     The @<imprint> function is much faster, though.)
+
+   \item[ichainsz] The size of the @|ichain| structure for this chain.
+
+   \end{description}
+ \end{describe}
+
+%%%--------------------------------------------------------------------------
+\section{Class and vtable layout} \label{sec:structures.layout}
+
+The layout algorithms for Sod instances and vtables are nontrivial.  They are
+defined here in full detail, since they're effectively fixed by Sod's ABI
+compatibility guarantees, so they might as well be documented for the sake of
+interoperating programs.
+
+Unfortunately, the descriptions are rather complicated, and, for the most
+part not necessary to a working understanding of Sod.  The skeleton structure
+definitions shown should be more than enough for readers attempting to make
+sense of the generated headers and tables.
+
+In the description that follows, uppercase letters vary over class names,
+while the corresponding lowercase letters indicate the class nicknames.
+Throughout, we consider a class $C$ (therefore with nickname $c$).
+
+\subsection{Generic instance structure}
+\label{sec:structures.layout.instance}
+
+The entire state of an instance of $C$ is contained in a single structure of
+type @|struct $C$__ilayout|.
+
+\begin{prog}
+  struct $C$__ilayout \{ \\ \ind
+    union $C$__ichainu_$h$ \{ \\ \ind
+      struct $C$__ichain_$h$ \{ \\ \ind
+        const struct $C$__vt_$h$ *_vt; \\
+        struct $H$__islots $h$; \\
+        \quad$\vdots$ \\
+        struct $C$__islots \{ \\ \ind
+          @<type>_1 @<slot>_1; \\
+          \quad$\vdots$ \\
+          @<type>_n @<slot>_n; \- \\
+        \} $c$; \- \\
+      \} $c$; \\
+      struct $H$__ichain_$h$ $h$; \\
+      \quad$\vdots$ \- \\
+    \} $h$; \\
+    union $B$__ichainu_$i$ $i$; \\
+    \quad$\vdots$ \- \\
+  \};
+  \\[\bigskipamount]
+  typedef struct $C$__ichain_$h$ $C$;
+\end{prog}
+
+The set of superclasses of $C$, including itself, can be partitioned into
+chains by following their distinguished superclass links.  (Formally, the
+chains are the equivalence classes determined by the reflexive, symmetric,
+transitive closure of the `links to' relation.)  Chains are identified by
+naming their least specific classes; the least specific class in a chain is
+called the \emph{chain head}.  Suppose that the chain head of the chain
+containing $C$ itself is named $H$ (though keep in mind that it's possible
+that .$H$ is in fact $C$ itself.)
+
+\subsubsection{The ilayout structure}
+The @|ilayout| structure contains one member for each of $C$'s superclass
+chains.  The first such member is
+\begin{prog}
+  union $C$__ichainu_$h$ $h$;
+\end{prog}
+described below; this is followed by members
+\begin{prog}
+  union $B$__ichainu_$i$ $i$;
+\end{prog}
+for each other chain, where $I$ is the head and $B$ the tail (most-specific)
+class of the chain.  The members are in decreasing order of the specificity
+of the chains' most-specific classes.  (Note that all but the first of these
+unions has already been defined as part of the definition of the
+corresponding $B$.)
+
+\subsubsection{The ichainu union}
+The @|ichainu| union contains a member for each class in the chain.  The
+first is
+\begin{prog}
+  struct $C$__ichain_$h$ $c$;
+\end{prog}
+and this is followed by corresponding members
+\begin{prog}
+  struct $A$__ichain_$h$ $a$;
+\end{prog}
+for each of $C$'s superclasses $A$ in the same chain in some (unimportant)
+order.
+
+\subsubsection{The ichain structure}
+The
+@|ichain|
+structure contains (in order), a pointer
+\begin{prog}
+  const struct $C$__vt_$h$ *_vt;
+\end{prog}
+followed by a structure
+\begin{prog}
+  struct $A$__islots $a$;
+\end{prog}
+for each superclass $A$ of $C$ in the same chain which defines slots, from
+least- to most-specific; if $C$ defines any slots, then the last member is
+\begin{prog}
+  struct $C$__islots $c$;
+\end{prog}
+A `pointer to $C$' is always assumed (and, indeed, defined in C's
+type system) to be a pointer to the @|struct $C$__ichain_$h$|.
+
+\subsubsection{The islots structure}
+Finally, the @|islots| structure simply contains one member for each slot
+defined by $C$ in the order they appear in the class definition.
+
+\subsection{Generic vtable structure} \label{sec:structures.layout.vtable}
+
+As described above, each @|ichain| structure of an instance's storage has a
+vtable pointer
+\begin{prog}
+  const struct $C$__vt_$h$ *_vt;
+\end{prog}
+In general, the vtables for the different chains will have \emph{different}
+structures.
+
+The instance layout split neatly into disjoint chains.  This is necessary
+because each @|ichain| must have as a prefix the @|ichain| for each
+superclass in the same chain, and each slot must be stored in exactly one
+place.  The layout of vtables doesn't have this second requirement: it
+doesn't matter that there are multiple method entry pointers for the same
+effective method as long as they all work correctly.  Indeed, it's essential
+that they do, because each chain's method entry function will need to apply a
+different offset to the receiver pointer before invoking the effective
+method.
+
+A vtable for a class $C$ with chain head $H$ has the following general
+structure.
+\begin{prog}
+  union $C$__vtu_$h$ \{ \\ \ind
+    struct $C$__vt_$h$ \{ \\ \ind
+      const $P$ *_class; \\
+      size_t _base; \\
+      \quad$\vdots$ \\
+      const $Q$ *_cls_$j$; \\
+      \quad$\vdots$ \\
+      ptrdiff_t _off_$i$; \\
+      \quad$\vdots$ \\
+      struct $C$__vtmsgs_$a$ \{ \\ \ind
+        @<type> (*@<msg>)($C$ *, $\dots$); \\
+        \quad$\vdots$ \- \\
+      \} $a$; \\
+      \quad$\vdots$ \- \\
+    \} $c$; \- \\
+  \};
+  \\[\bigskipamount]
+  extern const union $C$__vtu_$h$ $C$__vtable_$h$;
+\end{prog}
+
+\subsubsection{The vtu union}
+The outer layer is a @|union $C$__vtu_$h$| containing a member
+\begin{prog}
+  struct $A$__vt_$h$ $a$;
+\end{prog}
+for each of $C$'s superclasses $A$ in the same chain, with $C$ itself listed
+first.
+
+This is mostly an irrelevant detail,
+whose purpose is to defend against malicious compilers:
+pointers are always to one of the inner
+@|vt|
+structures.
+It's important only because it's the outer
+@|vtu|
+union which is exported by name.
+Specifically, for each chain of
+$C$'s
+superclasses
+there is an external object
+\begin{prog}
+  const union $A$__vtu_$i$ $C$__vtable_$i$;
+\end{prog}
+where $A$ and $I$ are respectively the most and least specific classes in the
+chain.
+
+\subsubsection{The vt structure}
+The first member in the @|vt| structure is the \emph{root class pointer}
+\begin{prog}
+  const $P$ *_class;
+\end{prog}
+Among the superclasses of $C$ there must be exactly one class $O$ which
+itself has no direct superclasses; this is the \emph{root superclass} of $C$.
+(This is a rule enforced by the Sod translator.)  The metaclass $R$ of $O$ is
+then the \emph{root metaclass} of $C$.  The @|_class| member points to the
+@|ichain| structure of most specific superclass $P$ of $M$ in the same chain
+as $R$.
+
+This is followed by the \emph{base offset}
+\begin{prog}
+  size_t _base;
+\end{prog}
+which is simply the offset of the @|ichain| structure from the instance base.
+
+The rest of the vtable structure is populated by walking the superclass chain
+containing $C$ as follows.  For each such superclass $B$, in increasing order
+of specificity, walk the class precedence list of $B$, again starting with
+its least-specific superclass.  (This complex procedure guarantees that the
+vtable structure for a class is a prefix of the vtable structure for any of
+its subclasses in the same chain.)
+
+So, let $A$ be some superclass of $C$ which has been encountered during this
+traversal.
+
+\begin{itemize}
+
+\item Let $N$ be the metaclass of $A$.  Examine the superclass chains of $N$
+  in order of decreasing specificity of their most-specific classes.  Let $J$
+  be the chain head of such a chain, and let $Q$ be the most specific
+  superclass of $M$ in the same chain as $J$.  Then, if there is currently no
+  class pointer of type $Q$, then add a member
+  \begin{prog}
+    const $Q$ *_cls_$j$;
+  \end{prog}
+  to the vtable pointing to the appropriate @|islots| structure within $M$'s
+  class object.
+
+\item Examine the superclass chains of $A$ in order of decreasing specificity
+  of their most-specific classes.  Let $I$ be the chain head of such a chain.
+  If there is currently no member @|_off_$i$| then add a member
+  \begin{prog}
+    ptrdiff_t _off_$i$;
+  \end{prog}
+  to the vtable, containing the (signed) offset from the @|ichain| structure
+  of the chain headed by $h$ to that of the chain headed by $i$ within the
+  instance's layout.
+
+\item If class $A$ defines any messages, and there is currently no member
+  $a$, then add a member
+  \begin{prog}
+    struct $C$__vtmsgs_$a$ $a$;
+  \end{prog}
+  to the vtable.  See below.
+
+\end{itemize}
+
+\subsubsection{The vtmsgs structure}
+Finally, the @|vtmsgs| structures contain pointers to the effective method
+entry functions for the messages defined by a superclass.  There may be more
+than one method entry for a message, but all of the entry pointers for a
+message appear together, and entry pointers for separate messages appear in
+the order in which the messages are defined.  If the receiver class has no
+applicable primary method for a message then it's usual for the method entry
+pointer to be null (though, as with a lot of things in Sod, extensions may do
+something different).
+
+For a standard message which takes a fixed number of arguments, defined as
+\begin{prog}
+  @<type>_0 $m$(@<type>_1 @<arg>_1, $\ldots$, @<type>_n @<arg>_n);
+\end{prog}
+there is always a `main' entry point,
+\begin{prog}
+  @<type>_0 $m$($C$ *me, @<type>_1 @<arg>_1, $\ldots$, @<type>_n @<arg>_n);
+\end{prog}
+
+For a standard message which takes a variable number of arguments,
+defined as
+\begin{prog}
+  @<type>_0 $m$(@<type>_1 @<arg>_1, $\ldots$, @<type>_n @<arg>_n, \dots);
+\end{prog}
+two entry points are defined: the usual `main' entry point which accepts a
+variable number of arguments, and a `valist' entry point which accepts an
+argument of type @|va_list| in place of the variable portion of the argument
+list.
+\begin{prog}
+  @<type>_0 $m$($C$ *me, @<type>_1 @<arg>_1, $\ldots$,
+                @<type>_n @<arg>_n, \dots); \\
+  @<type>_0 $m$__v($C$ *me, @<type>_1 @<arg>_1, $\ldots$,
+                   @<type>_n @<arg>_n, va_list sod__ap);
+\end{prog}
+
+\subsection{Additional definitions} \label{sec:structures.additional}
+
+In addition to the instance and vtable structures described above, the
+following definitions are made for each class $C$.
+
+For each message $m$ directly defined by $C$ there is a macro definition
+\begin{prog}
+  \#define $C$_$m$(@<me>, $\ldots$) @<me>@->_vt@->$c$.$m$(@<me>, $\ldots$)
+\end{prog}
+which makes sending the message $m$ to an instance of (any subclass of) $C$
+somewhat less ugly.
+
+If $m$ takes a variable number of arguments, the macro is more complicated
+and is only available in compilers advertising C99 support, but the effect is
+the same.  For each variable-argument message, there is also an additional
+macro for calling the `valist' entry point.
+\begin{prog}
+  \#define $C$_$m$__v(@<me>, $\ldots$, @<sod__ap>)
+    @<me>@->_vt@->$c$.$m$__v(@<me>, $\ldots$, @<sod__ap>)
+\end{prog}
+
+For each proper superclass $A$ of $C$, there is a macro defined
+\begin{prog}
+  $A$ *$C$__CONV_$a$($C$ *_obj);
+\end{prog}
+(named in \emph{upper case}) which converts a (static-type) pointer to $C$ to
+a pointer to the same actual instance, but statically typed as a pointer to
+$A$.  This is most useful when $A$ is not in the same chain as $C$ since
+in-chain upcasts are both trivial and rarely needed, but the full set is
+defined for the sake of completeness.
+
+Finally, the class object is defined as
+\begin{prog}
+  extern const struct $R$__ilayout $C$__classobj; \\
+  \#define $C$__class (\&$C$__classobj.$j$.$r$)
+\end{prog}
+The exported symbol @|$C$__classobj| contains the entire class instance.
+This is usually rather unwieldy.  The macro @|$C$__class| is usable as a
+pointer of type @|const $R$~*|, where $R$ is the root metaclass of $C$, i.e.,
+the metaclass of the least specific superclass of $C$; usually this is
+@|const SodClass~*|.
+
+%%%----- That's all, folks --------------------------------------------------
+
+%%% Local variables:
+%%% mode: LaTeX
+%%% TeX-master: "sod.tex"
+%%% TeX-PDF-mode: t
+%%% End:
diff --git a/doc/syntax.tex b/doc/syntax.tex
new file mode 100644 (file)
index 0000000..336f4bc
--- /dev/null
@@ -0,0 +1,667 @@
+%%% -*-latex-*-
+%%%
+%%% Module syntax
+%%%
+%%% (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{Module syntax} \label{ch:syntax}
+
+%%%--------------------------------------------------------------------------
+
+Fortunately, Sod is syntactically quite simple.  I've used a little slightly
+unusual notation in order to make the presentation easier to read.  For any
+nonterminal $x$:
+\begin{itemize}
+\item $\epsilon$ denotes the empty nonterminal:
+  \begin{quote}
+    $\epsilon$ ::=
+  \end{quote}
+\item @[$x$@] means an optional $x$:
+  \begin{quote}
+    \syntax{@[$x$@] ::= $\epsilon$ @! $x$}
+  \end{quote}
+\item $x^*$ means a sequence of zero or more $x$s:
+  \begin{quote}
+    \syntax{$x^*$ ::= $\epsilon$ @! $x^*$ $x$}
+  \end{quote}
+\item $x^+$ means a sequence of one or more $x$s:
+  \begin{quote}
+    \syntax{$x^+$ ::= $x$ $x^*$}
+  \end{quote}
+\item $x$@<-list> means a sequence of one or more $x$s separated
+  by commas:
+  \begin{quote}
+    \syntax{$x$<-list> ::= $x$ @! $x$<-list> "," $x$}
+  \end{quote}
+\end{itemize}
+
+\subsection{Lexical syntax}
+\label{sec:syntax.lex}
+
+Whitespace and comments are discarded.  The remaining characters are
+collected into tokens according to the following syntax.
+
+\begin{grammar}
+<token> ::= <identifier>
+\alt <string-literal>
+\alt <char-literal>
+\alt <integer-literal>
+\alt <punctuation>
+\end{grammar}
+
+This syntax is slightly ambiguous, and is disambiguated by the \emph{maximal
+munch} rule: at each stage we take the longest sequence of characters which
+could be a token.
+
+\subsubsection{Identifiers} \label{sec:syntax.lex.id}
+
+\begin{grammar}
+<identifier> ::= <id-start-char> @<id-body-char>^*
+
+<id-start-char> ::= <alpha-char> | "_"
+
+<id-body-char> ::= <id-start-char> @! <digit-char>
+
+<alpha-char> ::= "A" | "B" | \dots\ | "Z"
+\alt "a" | "b" | \dots\ | "z"
+\alt <extended-alpha-char>
+
+<digit-char> ::= "0" | <nonzero-digit-char>
+
+<nonzero-digit-char> ::= "1" | "2" $| \cdots |$ "9"
+\end{grammar}
+
+The precise definition of @<alpha-char> is left to the function
+\textsf{alpha-char-p} in the hosting Lisp system.  For portability,
+programmers are encouraged to limit themselves to the standard ASCII letters.
+
+There are no reserved words at the lexical level, but the higher-level syntax
+recognizes certain identifiers as \emph{keywords} in some contexts.  There is
+also an ambiguity (inherited from C) in the declaration syntax which is
+settled by distinguishing type names from other identifiers at a lexical
+level.
+
+\subsubsection{String and character literals} \label{sec:syntax.lex.string}
+
+\begin{grammar}
+<string-literal> ::= "\"" @<string-literal-char>^* "\""
+
+<char-literal> ::= "'" <char-literal-char> "'"
+
+<string-literal-char> ::= any character other than "\\" or "\""
+\alt "\\" <char>
+
+<char-literal-char> ::= any character other than "\\" or "'"
+\alt "\\" <char>
+
+<char> ::= any single character
+\end{grammar}
+
+The syntax for string and character literals differs from~C.  In particular,
+escape sequences such as @`\textbackslash n' are not recognized.  The use
+of string and character literals in Sod, outside of C~fragments, is limited,
+and the simple syntax seems adequate.  For the sake of future compatibility,
+the use of character sequences which resemble C escape sequences is
+discouraged.
+
+\subsubsection{Integer literals} \label{sec:syntax.lex.int}
+
+\begin{grammar}
+<integer-literal> ::= <decimal-integer>
+\alt <binary-integer>
+\alt <octal-integer>
+\alt <hex-integer>
+
+<decimal-integer> ::= <nonzero-digit-char> @<digit-char>^*
+
+<binary-integer> ::= "0" @("b"|"B"@) @<binary-digit-char>^+
+
+<binary-digit-char> ::= "0" | "1"
+
+<octal-integer> ::= "0" @["o"|"O"@] @<octal-digit-char>^+
+
+<octal-digit-char> ::= "0" | "1" $| \cdots |$ "7"
+
+<hex-integer> ::= "0" @("x"|"X"@) @<hex-digit-char>^+
+
+<hex-digit-char> ::= <digit-char>
+\alt "A" | "B" | "C" | "D" | "E" | "F"
+\alt "a" | "b" | "c" | "d" | "e" | "f"
+\end{grammar}
+
+Sod understands only integers, not floating-point numbers; its integer syntax
+goes slightly beyond C in allowing a @`0o' prefix for octal and @`0b' for
+binary.  However, length and signedness indicators are not permitted.
+
+\subsubsection{Punctuation} \label{sec:syntax.lex.punct}
+
+\begin{grammar}
+<punctuation> ::= any nonalphanumeric character other than "_", "\"" or "'"
+\end{grammar}
+
+\subsubsection{Comments} \label{sec:lex-comment}
+
+\begin{grammar}
+<comment> ::= <block-comment>
+\alt <line-comment>
+
+<block-comment> ::=
+  "/*"
+  @<not-star>^* @(@<star>^+ <not-star-or-slash> @<not-star>^*@)^*
+  @<star>^*
+  "*/"
+
+<star> ::= "*"
+
+<not-star> ::= any character other than "*"
+
+<not-star-or-slash> ::= any character other than "*" or  "/"
+
+<line-comment> ::= "//" @<not-newline>^* <newline>
+
+<newline> ::= a newline character
+
+<not-newline> ::= any character other than newline
+\end{grammar}
+
+Comments are exactly as in C99: both traditional block comments `\texttt{/*}
+\dots\ \texttt{*/}' and \Cplusplus-style `\texttt{//} \dots' comments are
+permitted and ignored.
+
+\subsection{Special nonterminals}
+\label{sec:special-nonterminals}
+
+Aside from the lexical syntax presented above (\xref{sec:lexical-syntax}),
+two special nonterminals occur in the module syntax.
+
+\subsubsection{S-expressions} \label{sec:syntax-sexp}
+
+\begin{grammar}
+<s-expression> ::= an S-expression, as parsed by the Lisp reader
+\end{grammar}
+
+When an S-expression is expected, the Sod parser simply calls the host Lisp
+system's \textsf{read} function.  Sod modules are permitted to modify the
+read table to extend the S-expression syntax.
+
+S-expressions are self-delimiting, so no end-marker is needed.
+
+\subsubsection{C fragments} \label{sec:syntax.lex.cfrag}
+
+\begin{grammar}
+<c-fragment> ::= a sequence of C tokens, with matching brackets
+\end{grammar}
+
+Sequences of C code are simply stored and written to the output unchanged
+during translation.  They are read using a simple scanner which nonetheless
+understands C comments and string and character literals.
+
+A C fragment is terminated by one of a small number of delimiter characters
+determined by the immediately surrounding context -- usually a closing brace
+or bracket.  The first such delimiter character which is not enclosed in
+brackets, braces or parenthesis ends the fragment.
+
+\subsection{Module syntax} \label{sec:syntax-module}
+
+\begin{grammar}
+<module> ::= @<definition>^*
+
+<definition> ::= <import-definition>
+\alt <load-definition>
+\alt <lisp-definition>
+\alt <code-definition>
+\alt <typename-definition>
+\alt <class-definition>
+\end{grammar}
+
+A module is the top-level syntactic item.  A module consists of a sequence of
+definitions.
+
+\subsection{Simple definitions} \label{sec:syntax.defs}
+
+\subsubsection{Importing modules} \label{sec:syntax.defs.import}
+
+\begin{grammar}
+<import-definition> ::= "import" <string> ";"
+\end{grammar}
+
+The module named @<string> is processed and its definitions made available.
+
+A search is made for a module source file as follows.
+\begin{itemize}
+\item The module name @<string> is converted into a filename by appending
+  @`.sod', if it has no extension already.\footnote{%
+    Technically, what happens is \textsf{(merge-pathnames name (make-pathname
+    :type "SOD" :case :common))}, so exactly what this means varies
+    according to the host system.} %
+\item The file is looked for relative to the directory containing the
+  importing module.
+\item If that fails, then the file is looked for in each directory on the
+  module search path in turn.
+\item If the file still isn't found, an error is reported and the import
+  fails.
+\end{itemize}
+At this point, if the file has previously been imported, nothing further
+happens.\footnote{%
+  This check is done using \textsf{truename}, so it should see through simple
+  tricks like symbolic links.  However, it may be confused by fancy things
+  like bind mounts and so on.} %
+
+Recursive imports, either direct or indirect, are an error.
+
+\subsubsection{Loading extensions} \label{sec:syntax.defs.load}
+
+\begin{grammar}
+<load-definition> ::= "load" <string> ";"
+\end{grammar}
+
+The Lisp file named @<string> is loaded and evaluated.
+
+A search is made for a Lisp source file as follows.
+\begin{itemize}
+\item The name @<string> is converted into a filename by appending @`.lisp',
+  if it has no extension already.\footnote{%
+    Technically, what happens is \textsf{(merge-pathnames name (make-pathname
+    :type "LISP" :case :common))}, so exactly what this means varies
+    according to the host system.} %
+\item A search is then made in the same manner as for module imports
+  (\xref{sec:syntax-module}).
+\end{itemize}
+If the file is found, it is loaded using the host Lisp's \textsf{load}
+function.
+
+Note that Sod doesn't attempt to compile Lisp files, or even to look for
+existing compiled files.  The right way to package a substantial extension to
+the Sod translator is to provide the extension as a standard ASDF system (or
+similar) and leave a dropping @"foo-extension.lisp" in the module path saying
+something like
+\begin{quote}
+  \textsf{(asdf:load-system :foo-extension)}
+\end{quote}
+which will arrange for the extension to be compiled if necessary.
+
+(This approach means that the language doesn't need to depend on any
+particular system definition facility.  It's bad enough already that it
+depends on Common Lisp.)
+
+\subsubsection{Lisp escapes} \label{sec:syntax.defs.lisp}
+
+\begin{grammar}
+<lisp-definition> ::= "lisp" <s-expression> ";"
+\end{grammar}
+
+The @<s-expression> is evaluated immediately.  It can do anything it likes.
+
+\begin{boxy}[Warning!]
+  This means that hostile Sod modules are a security hazard.  Lisp code can
+  read and write files, start other programs, and make network connections.
+  Don't install Sod modules from sources that you don't trust.\footnote{%
+    Presumably you were going to run the corresponding code at some point, so
+    this isn't as unusually scary as it sounds.  But please be careful.} %
+\end{boxy}
+
+\subsubsection{Declaring type names} \label{sec:syntax.defs.typename}
+
+\begin{grammar}
+<typename-definition> ::=
+  "typename" <identifier-list> ";"
+\end{grammar}
+
+Each @<identifier> is declared as naming a C type.  This is important because
+the C type syntax -- which Sod uses -- is ambiguous, and disambiguation is
+done by distinguishing type names from other identifiers.
+
+Don't declare class names using @"typename"; use @"class" forward
+declarations instead.
+
+\subsection{Literal code} \label{sec:syntax-code}
+
+\begin{grammar}
+<code-definition> ::=
+  "code" <identifier> ":" <identifier> @[<constraints>@]
+  "{" <c-fragment> "}"
+
+<constraints> ::= "[" <constraint-list> "]"
+
+<constraint> ::= @<identifier>^+
+\end{grammar}
+
+The @<c-fragment> will be output unchanged to one of the output files.
+
+The first @<identifier> is the symbolic name of an output file.  Predefined
+output file names are @"c" and @"h", which are the implementation code and
+header file respectively; other output files can be defined by extensions.
+
+The second @<identifier> provides a name for the output item.  Several C
+fragments can have the same name: they will be concatenated together in the
+order in which they were encountered.
+
+The @<constraints> provide a means for specifying where in the output file
+the output item should appear.  (Note the two kinds of square brackets shown
+in the syntax: square brackets must appear around the constraints if they are
+present, but that they may be omitted.)  Each comma-separated @<constraint>
+is a sequence of identifiers naming output items, and indicates that the
+output items must appear in the order given -- though the translator is free
+to insert additional items in between them.  (The particular output items
+needn't be defined already -- indeed, they needn't be defined ever.)
+
+There is a predefined output item @"includes" in both the @"c" and @"h"
+output files which is a suitable place for inserting @"\#include"
+preprocessor directives in order to declare types and functions for use
+elsewhere in the generated output files.
+
+\subsection{Property sets} \label{sec:syntax.propset}
+
+\begin{grammar}
+<properties> ::= "[" <property-list> "]"
+
+<property> ::= <identifier> "=" <expression>
+\end{grammar}
+
+Property sets are a means for associating miscellaneous information with
+classes and related items.  By using property sets, additional information
+can be passed to extensions without the need to introduce idiosyncratic
+syntax.
+
+A property has a name, given as an @<identifier>, and a value computed by
+evaluating an @<expression>.  The value can be one of a number of types,
+though the only operators currently defined act on integer values only.
+
+\subsubsection{The expression evaluator} \label{sec:syntax.propset.expr}
+
+\begin{grammar}
+<expression> ::= <term> | <expression> "+" <term> | <expression> "-" <term>
+
+<term> ::= <factor> | <term> "*" <factor> | <term> "/" <factor>
+
+<factor> ::= <primary> | "+" <factor> | "-" <factor>
+
+<primary> ::=
+     <integer-literal> | <string-literal> | <char-literal> | <identifier>
+\alt "?" <s-expression>
+\alt "(" <expression> ")"
+\end{grammar}
+
+The arithmetic expression syntax is simple and standard; there are currently
+no bitwise, logical, or comparison operators.
+
+A @<primary> expression may be a literal or an identifier.  Note that
+identifiers stand for themselves: they \emph{do not} denote values.  For more
+fancy expressions, the syntax
+\begin{quote}
+  @"?" @<s-expression>
+\end{quote}
+causes the @<s-expression> to be evaluated using the Lisp \textsf{eval}
+function.
+%%% FIXME crossref to extension docs
+
+\subsection{C types} \label{sec:syntax.c-types}
+
+Sod's syntax for C types closely mirrors the standard C syntax.  A C type has
+two parts: a sequence of @<declaration-specifier>s and a @<declarator>.  In
+Sod, a type must contain at least one @<declaration-specifier> (i.e.,
+`implicit @"int"' is forbidden), and storage-class specifiers are not
+recognized.
+
+\subsubsection{Declaration specifiers} \label{sec:syntax.c-types.declspec}
+
+\begin{grammar}
+<declaration-specifier> ::= <type-name>
+\alt "struct" <identifier> | "union" <identifier> | "enum" <identifier>
+\alt "void" | "char" | "int" | "float" | "double"
+\alt "short" | "long"
+\alt "signed" | "unsigned"
+\alt <qualifier>
+
+<qualifier> ::= "const" | "volatile" | "restrict"
+
+<type-name> ::= <identifier>
+\end{grammar}
+
+A @<type-name> is an identifier which has been declared as being a type name,
+using the @"typename" or @"class" definitions.
+
+Declaration specifiers may appear in any order.  However, not all
+combinations are permitted.  A declaration specifier must consist of zero or
+more @<qualifiers>, and one of the following, up to reordering.
+\begin{itemize}
+\item @<type-name>
+\item @"struct" @<identifier>, @"union" @<identifier>, @"enum" @<identifier>
+\item @"void"
+\item @"char", @"unsigned char", @"signed char"
+\item @"short", @"unsigned short", @"signed short"
+\item @"short int", @"unsigned short int", @"signed short int"
+\item @"int", @"unsigned int", @"signed int", @"unsigned", @"signed"
+\item @"long", @"unsigned long", @"signed long"
+\item @"long int", @"unsigned long int", @"signed long int"
+\item @"long long", @"unsigned long long", @"signed long long"
+\item @"long long int", @"unsigned long long int", @"signed long long int"
+\item @"float", @"double", @"long double"
+\end{itemize}
+All of these have their usual C meanings.
+
+\subsubsection{Declarators} \label{sec:syntax.c-types.declarator}
+
+\begin{grammar}
+<declarator>$[k]$ ::= @<pointer>^* <primary-declarator>$[k]$
+
+<primary-declarator>$[k]$ ::= $k$
+\alt "(" <primary-declarator>$[k]$ ")"
+\alt <primary-declarator>$[k]$ @<declarator-suffix>^*
+
+<pointer> ::= "*" @<qualifier>^*
+
+<declarator-suffix> ::= "[" <c-fragment> "]"
+\alt "(" <arguments> ")"
+
+<arguments> ::= $\epsilon$ | "..."
+\alt <argument-list> @["," "..."@]
+
+<argument> ::= @<declaration-specifier>^+ <argument-declarator>
+
+<argument-declarator> ::= <declarator>@[<identifier> @! $\epsilon$@]
+
+<simple-declarator> ::= <declarator>@[<identifier>@]
+
+<dotted-name> ::= <identifier> "." <identifier>
+
+<dotted-declarator> ::= <declarator>@[<dotted-name>@]
+\end{grammar}
+
+The declarator syntax is taken from C, but with some differences.
+\begin{itemize}
+\item Array dimensions are uninterpreted @<c-fragments>, terminated by a
+  closing square bracket.  This allows array dimensions to contain arbitrary
+  constant expressions.
+\item A declarator may have either a single @<identifier> at its centre or a
+  pair of @<identifier>s separated by a @`.'; this is used to refer to
+  slots or messages defined in superclasses.
+\end{itemize}
+The remaining differences are (I hope) a matter of presentation rather than
+substance.
+
+\subsection{Defining classes} \label{sec:syntax.class}
+
+\begin{grammar}
+<class-definition> ::= <class-forward-declaration>
+\alt <full-class-definition>
+\end{grammar}
+
+\subsubsection{Forward declarations} \label{sec:class.class.forward}
+
+\begin{grammar}
+<class-forward-declaration> ::= "class" <identifier> ";"
+\end{grammar}
+
+A @<class-forward-declaration> informs Sod that an @<identifier> will be used
+to name a class which is currently undefined.  Forward declarations are
+necessary in order to resolve certain kinds of circularity.  For example,
+\begin{listing}
+class Sub;
+
+class Super : SodObject {
+  Sub *sub;
+};
+
+class Sub : Super {
+  /* ... */
+};
+\end{listing}
+
+\subsubsection{Full class definitions} \label{sec:class.class.full}
+
+\begin{grammar}
+<full-class-definition> ::=
+  @[<properties>@]
+  "class" <identifier> ":" <identifier-list>
+  "{" @<class-item>^* "}"
+
+<class-item> ::= <slot-item> ";"
+\alt <message-item>
+\alt <method-item>
+\alt  <initializer-item> ";"
+\end{grammar}
+
+A full class definition provides a complete description of a class.
+
+The first @<identifier> gives the name of the class.  It is an error to
+give the name of an existing class (other than a forward-referenced class),
+or an existing type name.  It is conventional to give classes `MixedCase'
+names, to distinguish them from other kinds of identifiers.
+
+The @<identifier-list> names the direct superclasses for the new class.  It
+is an error if any of these @<identifier>s does not name a defined class.
+
+The @<properties> provide additional information.  The standard class
+properties are as follows.
+\begin{description}
+\item[@"lisp_class"] The name of the Lisp class to use within the translator
+  to represent this class.  The property value must be an identifier; the
+  default is @"sod_class".  Extensions may define classes with additional
+  behaviour, and may recognize additional class properties.
+\item[@"metaclass"] The name of the Sod metaclass for this class.  In the
+  generated code, a class is itself an instance of another class -- its
+  \emph{metaclass}.  The metaclass defines which slots the class will have,
+  which messages it will respond to, and what its behaviour will be when it
+  receives them.  The property value must be an identifier naming a defined
+  subclass of @"SodClass".  The default metaclass is @"SodClass".
+  %%% FIXME xref to theory
+\item[@"nick"] A nickname for the class, to be used to distinguish it from
+  other classes in various limited contexts.  The property value must be an
+  identifier; the default is constructed by forcing the class name to
+  lower-case.
+\end{description}
+
+The class body consists of a sequence of @<class-item>s enclosed in braces.
+These items are discussed on the following sections.
+
+\subsubsection{Slot items} \label{sec:sntax.class.slot}
+
+\begin{grammar}
+<slot-item> ::=
+  @[<properties>@]
+  @<declaration-specifier>^+ <init-declarator-list>
+
+<init-declarator> ::= <declarator> @["=" <initializer>@]
+\end{grammar}
+
+A @<slot-item> defines one or more slots.  All instances of the class and any
+subclass will contain these slot, with the names and types given by the
+@<declaration-specifiers> and the @<declarators>.  Slot declarators may not
+contain qualified identifiers.
+
+It is not possible to declare a slot with function type: such an item is
+interpreted as being a @<message-item> or @<method-item>.  Pointers to
+functions are fine.
+
+An @<initializer>, if present, is treated as if a separate
+@<initializer-item> containing the slot name and initializer were present.
+For example,
+\begin{listing}
+[nick = eg]
+class Example : Super {
+  int foo = 17;
+};
+\end{listing}
+means the same as
+\begin{listing}
+[nick = eg]
+class Example : Super {
+  int foo;
+  eg.foo = 17;
+};
+\end{listing}
+
+\subsubsection{Initializer items} \label{sec:syntax.class.init}
+
+\begin{grammar}
+<initializer-item> ::= @["class"@] <slot-initializer-list>
+
+<slot-initializer> ::= <qualified-identifier> "=" <initializer>
+
+<initializer> :: "{" <c-fragment> "}" | <c-fragment>
+\end{grammar}
+
+An @<initializer-item> provides an initial value for one or more slots.  If
+prefixed by @"class", then the initial values are for class slots (i.e.,
+slots of the class object itself); otherwise they are for instance slots.
+
+The first component of the @<qualified-identifier> must be the nickname of
+one of the class's superclasses (including itself); the second must be the
+name of a slot defined in that superclass.
+
+The initializer has one of two forms.
+\begin{itemize}
+\item A @<c-fragment> enclosed in braces denotes an aggregate initializer.
+  This is suitable for initializing structure, union or array slots.
+\item A @<c-fragment> \emph{not} beginning with an open brace is a `bare'
+  initializer, and continues until the next @`,' or @`;' which is not within
+  nested brackets.  Bare initializers are suitable for initializing scalar
+  slots, such as pointers or integers, and strings.
+\end{itemize}
+
+\subsubsection{Message items} \label{sec:syntax.class.message}
+
+\begin{grammar}
+<message-item> ::=
+  @[<properties>@]
+  @<declaration-specifier>^+ <declarator> @[<method-body>@]
+\end{grammar}
+
+\subsubsection{Method items} \label{sec:syntax.class.method}
+
+\begin{grammar}
+<method-item> ::=
+  @[<properties>@]
+  @<declaration-specifier>^+ <declarator> <method-body>
+
+<method-body> ::= "{" <c-fragment> "}" | "extern" ";"
+\end{grammar}
+
+
+%%%----- That's all, folks --------------------------------------------------
+
+%%% Local variables:
+%%% mode: LaTeX
+%%% TeX-master: "sod.tex"
+%%% TeX-PDF-mode: t
+%%% End:
similarity index 86%
rename from doc/sod-tut.tex
rename to doc/tutorial.tex
index cff9859..afc6109 100644 (file)
@@ -23,8 +23,7 @@
 %%% along with SOD; if not, write to the Free Software Foundation,
 %%% Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-\chapter{Tutorial}
-\label{ch:tut}
+\chapter{Tutorial} \label{ch:tutorial}
 
 This chapter provides a tutorial introduction to the Sod object system.  It
 intentionally misses out nitty-gritty details.  If you want those, the
@@ -35,7 +34,7 @@ You'll have to bear with him.  If you think you can do a better job, I'm sure
 that he'll be grateful for your contribution.
 
 %%%--------------------------------------------------------------------------
-\section{Introduction} \label{sec:tut.intro}
+\section{Introduction} \label{sec:tutorial.intro}
 
 Sod is an object system for the C~programming language.  Because it doesn't
 have enough already.  Actually, that's not right: it's got plenty already.
@@ -68,7 +67,7 @@ means that is has the following features.
 There's a good chance that half of that didn't mean anything to you.  Bear
 with me, though, because we'll explain it all eventually.
 
-\subsection{Building programs with Sod} \label{sec:tut.intro.build}
+\subsection{Building programs with Sod} \label{sec:tutorial.intro.build}
 
 Sod is basically a fancy preprocessor, in the same vein as Lex and Yacc.  It
 reads source files written in a vaguely C-like language.  It produces output
@@ -84,8 +83,8 @@ The main consequences of this are as follows.
 \item Sod hasn't made any attempt to improve C's syntax.  It's just as
   hostile to object-oriented programming as it ever was.  This means that
   you'll end up writing ugly things like
-  \begin{prog}%
-    thing->_vt->foo.frob(thing, mumble);%
+  \begin{prog}
+    thing->_vt->foo.frob(thing, mumble);
   \end{prog}
   fairly frequently.  This can be made somewhat less painful using macros,
   but we're basically stuck with C.  The upside is that you know exactly what
@@ -96,12 +95,12 @@ The main consequences of this are as follows.
 \end{itemize}
 Of course, this means that your build system needs to become more
 complicated.  If you use \man{make}{1}, then something like
-\begin{prog}%
-  SOD = sod
-
-  .SUFFIXES: .sod .c .h
-  .sod.c:; \$(SOD) -gc -o \$@@ \$<
-  .sod.h:; \$(SOD) -gh -o \$@@ \$< %
+\begin{prog}
+  SOD = sod \\
+  \\
+  .SUFFIXES: .sod .c .h \\
+  .sod.c:; \$(SOD) -tc \$< \\
+  .sod.h:; \$(SOD) -th \$<
 \end{prog}
 ought to do the job.
 
@@ -109,48 +108,47 @@ ought to do the job.
 \section{A traditional trivial introduction}
 
 The following is a simple Sod input file.
-\begin{prog}\quad\=\quad\=\kill%
-/* -*-sod-*- */
-
-code c : includes \{
-\#include "greeter.h"
-\}
-
-code h : includes \{
-\#include <stdio.h>
-\#include <sod.h>
+\begin{prog}
+/* -*-sod-*- */ \\
+\\
+code c : includes \{ \\
+\#include "greeter.h" \\
+\} \\
+\\
+code h : includes \{ \\
+\#include <stdio.h> \\
+\#include <sod/sod.h> \\
+\} \\
+\\
+class Greeter : SodObject \{ \\ \ind
+  void greet(FILE *fp) \{ \\ \ind
+    fputs("Hello, world!\textbackslash n", fp); \- \\
+  \} \- \\
 \}
-
-class Greeter : SodObject \{ \+
-  void greet(FILE *fp) \{ \+
-    fputs("Hello, world!\textbackslash n", fp); \-
-  \} \-
-\} %
 \end{prog}
 Save it as @"greeter.sod", and run
-\begin{prog}%
-sod --gc --gh greeter %
+\begin{prog}
+sod --gc --gh greeter
 \end{prog}
 This will create files @"greeter.c" and @"greeter.h" in the current
 directory.  Here's how we might use such a simple thing.
-\begin{prog}\quad\=\kill%
-\#include "greeter.h"
-
-int main(void)
-\{ \+
-  struct Greeter__ilayout g_obj;
-  Greeter *g = Greeter__class->cls.init(\&g_obj);
-
-  g->_vt.greeter.greet(g, stdout);
-  return (0); \-
-\} %
+\begin{prog}
+\#include "greeter.h" \\
+\\
+int main(void) \\
+\{ \\ \ind
+  SOD_DECL(Greeter, g); \\
+  \\
+  Greeter_greet(g, stdout); \\
+  return (0); \- \\
+\}
 \end{prog}
 Compare this to the traditional
-\begin{prog}\quad\=\kill%
-\#include <stdio.h>
-
-int main(void) \+
-  \{ fputs("Hello, world\\n", stdout); return (0); \} %
+\begin{prog}
+\#include <stdio.h> \\
+\\
+int main(void) \\ \ind
+  \{ fputs("Hello, world@\\n", stdout); return (0); \}
 \end{prog}
 and I'm sure you'll appreciate the benefits of using Sod already -- mostly to
 do with finger exercise.  Trust me, it gets more useful.
@@ -161,13 +159,13 @@ it (after the comment which tells Emacs how to cope with it).
 The first part consists of the two @"code" stanzas.  Both of them define
 gobbets of raw C code to copy into output files.  The first one, @"code~:
 c"~\ldots, says that
-\begin{prog}%
-  \#include "greeter.h" %
+\begin{prog}
+  \#include "greeter.h"
 \end{prog}
 needs to appear in the generated @|greeter.c| file; the second says that
-\begin{prog}%
-  \#include <stdio.h>
-  \#include <sod.h> %
+\begin{prog}
+  \#include <stdio.h> \\
+  \#include <sod/sod.h>
 \end{prog}
 needs to appear in the header file @|greeter.h|.  The generated C files need
 to get declarations for external types and functions (e.g., @"FILE" and
@@ -176,10 +174,10 @@ declarations from the corresponding @".h" file.  Sod takes a very simple
 approach to all of this: it expects you, the programmer, to deal with it.
 
 The basic syntax for @"code" stanzas is
-\begin{prog}\quad\=\kill%
-  code @<file-label> : @<section> \{
-  \>  @<code>
-  \} %
+\begin{prog}
+  code @<file-label> : @<section> \{ \\ \ind
+    @<code> \- \\
+  \}
 \end{prog}
 The @<file-label> is either @"c" or @"h", and says which output file the code
 wants to be written to.  The @<section> is a name which explains where in the
@@ -193,13 +191,13 @@ message.
 
 So far, so good.  The C code, which we thought we understood, contains some
 bizarre looking runes.  Let's take it one step at a time.
-\begin{prog}%
-  struct Greeter__ilayout g_obj; %
+\begin{prog}
+  struct Greeter__ilayout g_obj;
 \end{prog}
 allocates space for an instance of class @"Greeter".  We're not going to use
 this space directly.  Instead, we do this frightening looking thing.
-\begin{prog}%
-  Greeter *g = Greeter__class->cls.init(\&g_obj); %
+\begin{prog}
+  Greeter *g = Greeter__class->cls.init(\&g_obj);
 \end{prog}
 Taking it slowly: @"Greeter__class" is a pointer to the object that
 represents our class @"Greeter".  This object contains a member, named
@@ -209,8 +207,8 @@ the instance, which we use in preference to grovelling about in the
 @"ilayout" structure.
 
 Having done this, we `send the instance a message':
-\begin{prog}%
-  g->_vt->greeter.greet(g, stdout); %
+\begin{prog}
+  g->_vt->greeter.greet(g, stdout);
 \end{prog}
 This looks horrific, and seems to repeat itself quite unnecessarily.  The
 first @"g" is the recipient of our `message'.  The second is indeed a copy of