PreviousUpNext

15.4.635  src/lib/compiler/front/typer/main/expand-oop-syntax.pkg

## expand-oop-syntax.pkg

# Compiled by:
#     src/lib/compiler/front/typer/typer.sublib

# Design
# ------
#
# We follow the path outlined by Bernard Berthomieu
# in his March 2000 paper
#
#     OO Programming styles in ML
#     http://www.laas.fr/~bernard/oo/ooml.html
#
# This paper's approach has the advantage of requiring no
# change in the base language semantics:  It can be implemented
# entirely in terms of derived forms that expand into the
# underlying vanilla language during initial parsetree
# construction.
#
# This leaves the bulk of the compiler unchanged.
#
# More importantly, it eliminates all risk of introducing
# anomalies into the core language semantics, such as say
# typechecking becoming undecidable (as in C++).
#
# Our approach is based on his "simple dispatch with
# embedded methods" design.
#
# As syntactic support, in
#
#     src/lib/compiler/front/parser/yacc/mythryl.grammar
#
# we have made four changes to the base Mythryl syntax:
#
# (1) We allow 
#
#         class   foo = pkg ... end;
#
#     as a synonym for
#
#         package foo = pkg ... end;
#
#     This is purely cosmetic.
#
# (2) At package toplevel we allow
#
#         field name;
#
#     This serves to declare OOP object fields.
#
# (3) At package toplevel we allow substitution
#     of 'method' for 'fun' in function declarations,
#     with otherwise identical syntax.
#
#     This serves to declare OOP methods:
#
#         method print_name self
#             =
#             printf  "My name is %s.\n"  self->name;
#
# (4) We allow the syntax object->field for accessing
#     object fields within class methods and functions.
#



# Implementation
# --------------
#
# We have a small supporting hack
#
#     src/lib/compiler/front/parser/raw-syntax/oop-syntax-parser-transform.pkg 
#
# invoked directly from
#
#     src/lib/compiler/front/parser/yacc/mythryl.grammar
#
# which establishes needed module dependencies on
#
#     src/lib/src/oop.pkg
#     src/lib/src/object.pkg

# These dependencies are special because at that point we
# have not yet synthesized the code using them, hence the
# need for a special hack to make the dependency analysis
# phase of the compiler aware of them.
#
# Our logic in this file gets invoked at compile time from
# typecheck_named_packages() in
#
#     src/lib/compiler/front/typer/main/type-package-language-g.pkg
#
# with the raw syntax tree for a complete
#
#     class { ... }
#
# construct, presumably containing 'field' and
# 'method' declarations.
#
# Our task is to eliminate those declarations by
# expanding them into equivalent declarations in
# the underlying vanilla language.  (If there are
# no 'field' or 'method' declarations present,
# we have nothing to do.)
#
# This task breaks down into the following subtasks:
#
#   o  Collect and count the 'field' declarations,
#      assigning them successive slots in the eventual
#      object vector (tuple).
#
#   o  Collect and count the 'method' declarations,
#      saving them in successive slots in a package-global
#      method vector (tuple).
#      
#   o  Replace each 'method' declaration by a trivial
#      message wrapper which fetches and invokes the
#      corresponding method function from the appropriate
#      slot of self's method vector.
#
#   o  Make a 'make__object' function which creates
#      new objects which are instances of the class.
#      Each consists of a
#          { object__methods, object__fields }
#      record.



###          "The mathematician's patterns, like the painter's
###           or the poet's, must be beautiful; the ideas, like
###           the colours or the words, must fit together in
###           a harmonious way.
###
###          "Beauty is the first test: there is no permanent
###           place in the world for ugly mathematics."
###
###                              -- Godfrey Harold Hardy



stipulate
    package bug = typer_debugging;                                              # typer_debugging                               is from   src/lib/compiler/front/typer/main/typer-debugging.pkg
herein

    package expand_oop_syntax:   Expand_Oop_Syntax   {                          # Expand_Oop_Syntax                             is from   src/lib/compiler/front/typer/main/expand-oop-syntax.api
        #
                                                                                # typer_control                                 is from   src/lib/compiler/front/typer/basics/typer-control.pkg
        # Debugging: 
        #
        say         =   control_print::say;
        debugging   =   typer_control::expand_oop_syntax_debugging;             #  eval:   set_control "typechecker::expand_oop_syntax_debugging" "TRUE";
        #
        fun if_debugging_say (msg: String)
            =
            if *debugging 
                say msg;
                say "\n";
            fi;

                                                                                    # error_message                             is from   src/lib/compiler/front/basics/errormsg/error-message.pkg
        #
        fun bug msg
            =
            error_message::impossible("type_package_language: " + msg);


        debug_print
            =
            fn x =  bug::debug_print  debugging  x;


                                                                                    # raw_syntax                                is from   src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg
                                                                                    # symbolmapstack                            is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg
                                                                                    # prettyprinter                             is from   src/lib/prettyprint/big/src/prettyprinter.pkg
                                                                                    # unparse_raw_syntax                        is from   src/lib/compiler/front/typer/print/unparse-raw-syntax.pkg
        fun unparse_raw_declaration
            (
              msg:          String,
              declaration:  raw_syntax::Declaration,
              symbolmapstack: symbolmapstack::Symbolmapstack
            )
            =
            if *debugging
                print "\n";
                print msg;
                pp = prettyprinter::make_file_prettyprinter "/dev/stdout";

                pps = pp.stream;

                unparse_raw_syntax::unparse_declaration
                    (symbolmapstack, NULL)
                    pps
                    (declaration, 100);

                pp.flush ();
                pp.close ();
                print "\n";
            fi;
        #
        fun prettyprint_raw_declaration
            (
              msg:          String,
              declaration:  raw_syntax::Declaration,
              symbolmapstack: symbolmapstack::Symbolmapstack
            )
            =
            if *debugging
                print "\n";
                print msg;
                pp = prettyprinter::make_file_prettyprinter "/dev/stdout";

                pps = pp.stream;

                prettyprint_raw_syntax::prettyprint_declaration
                    (symbolmapstack, NULL)
                    pps
                    (declaration, 100);

                pp.flush ();
                pp.close ();
                print "\n";
            fi;

                                                                                    # prettyprint_raw_syntax            is from   src/lib/compiler/front/typer/print/prettyprint-raw-syntax.pkg
        fun prettyprint_named_function
            (
              msg:          String,
              function:     raw_syntax::Named_Function,
              symbolmapstack: symbolmapstack::Symbolmapstack
            )
            =
            if *debugging
                print "\n";
                print msg;
                pp = prettyprinter::make_file_prettyprinter "/dev/stdout";

                pps = pp.stream;

                prettyprint_raw_syntax::prettyprint_named_function
                    (symbolmapstack, NULL)
                    pps
                    "method/message"
                    (function, 100);

                pp.flush ();
                pp.close ();
                print "\n";
            fi;

        include fast_symbol;                                                    # fast_symbol                           is from   src/lib/compiler/front/basics/map/fast-symbol.pkg
        include raw_syntax;                                                     # raw_syntax                            is from   src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg
        include raw_syntax_junk;                                                # raw_syntax_junk                       is from   src/lib/compiler/front/parser/raw-syntax/raw-syntax-junk.pkg

        package eos = expand_oop_syntax_junk;                                   # expand_oop_syntax_junk                is from   src/lib/compiler/front/typer/main/expand-oop-syntax-junk.pkg

        typevar_x =  TYPE_VARIABLE (symbol::make_type_variable_symbol "X");

                                                                                # line_number_db                        is from   src/lib/compiler/front/basics/source/line-number-db.pkg
                                                                                # typer_junk                            is from   src/lib/compiler/front/typer/main/typer-junk.pkg
                                                                                # oop_collect_methods_and_fields        is from   src/lib/compiler/front/typer/main/oop-collect-methods-and-fields.pkg
                                                                                # oop_rewrite_declaration               is from   src/lib/compiler/front/typer/main/oop-rewrite-declaration.pkg
        oop_collect_methods_and_fields
            =
            oop_collect_methods_and_fields::collect_methods_and_fields;

        oop_rewrite_declaration
            =
            oop_rewrite_declaration::rewrite_declaration;

        #
        fun expand_oop_syntax_in_declaration
            ( class_name:       symbol::Symbol,
              declaration:      raw_syntax::Declaration,
              symbolmapstack:         symbolmapstack::Symbolmapstack,
              source_code_region:   line_number_db::Source_Code_Region,
              per_compile_info as
                {
                  error_fn,
                  ...
                }:                      typer_junk::Per_Compile_Info
            )
            =
            {
                (oop_collect_methods_and_fields  (declaration, symbolmapstack, source_code_region, per_compile_info))
                    ->
                    { fields,
                      methods_and_messages,                                             # Definitions of 'method' and 'message' methods.
                      null_or_superclass,                                               # First 'class super = ...' declaration found, else NULL.
                      syntax_errors
                    }; 

                # We're now using tuples to hold fields,
                # and there are no length-0 or length-1
                # tuples in Mythryl, so pad 'fields' to
                # at least length 2:
                #
                fields
                    =
                    case fields

                        []        => [ NAMED_FIELD { name => symbol::make_value_symbol "__dummy1__", type => TYP_TYPE ([symbol::make_value_symbol "String"],[]), init => THE (STRING_CONSTANT_IN_EXPRESSION "") },
                                       NAMED_FIELD { name => symbol::make_value_symbol "__dummy2__", type => TYP_TYPE ([symbol::make_value_symbol "String"],[]), init => THE (STRING_CONSTANT_IN_EXPRESSION "") }
                                     ];

                        [ field ] => [ field,
                                       NAMED_FIELD { name => symbol::make_value_symbol "__dummy1__", type => TYP_TYPE ([symbol::make_value_symbol "String"],[]), init => THE (STRING_CONSTANT_IN_EXPRESSION "") }
                                     ];

                        _         => fields;

                    esac;

                fun field_to_offset field_name
                    =
                    field_to_offset' (fields, 0)
                    where 
                        fun field_to_offset' ([], field_num)
                                =>
                                raise exception FAIL
                                  ( sprintf     
                                    "expand-oop-syntax.pkg: field_to_offset': error: Class %s has no field %s"
                                    (symbol::name class_name)
                                    (symbol::name field_name)
                                  );

                            field_to_offset' (field ! rest, field_num)
                                =>
                                if (symbol::eq (get_fieldname field,  field_name))
                                     field_num;
                                else
                                     field_to_offset' (rest, field_num + 1);
                                fi
                                where
                                    fun get_fieldname (NAMED_FIELD { name, ... })
                                            =>
                                            name;

                                        get_fieldname (SOURCE_CODE_REGION_FOR_NAMED_FIELD ( named_field, _ ))
                                            =>
                                            get_fieldname  named_field;
                                    end;
                                end;
                        end;
                    end;

                if *debugging
                    printf "expand_oop_syntax_in_declaration/TOP: methods_and_messages\n";
                    count = REF 0;
                    apply  print_it  methods_and_messages
                    where
                        fun print_it  method_or_message
                            =
                            {   prettyprint_named_function
                                  (  sprintf "method/message #%d: " *count,
                                     method_or_message,
                                     symbolmapstack
                                  );

                                  count := *count + 1;
                            };
                    end;
                fi;

                initializer_fields                                      # Fields which have no initial value, hence need to be supplied via initializer record.
                    =
                    list::filter  filter_fn  fields
                    where
                        fun filter_fn (NAMED_FIELD { name, type, init => NULL })
                                =>
                                TRUE;

                            filter_fn _
                                =>
                                FALSE;
                        end;
                    end;


                message_definitions                                     # Definitions of new messages.
                    =
                    list::filter  filter_fn  methods_and_messages
                    where
                        fun filter_fn (NAMED_FUNCTION { pattern_clauses, is_lazy, kind, null_or_type })
                                =>
                                kind == MESSAGE_FUN;

                            filter_fn _
                                =>
                                raise exception FAIL "expand-oop-syntax.pkg: Internal compiler error.";
                        end;
                    end;
    # XXX BUGGO FIXME  Need to pad this to at least length 2 in
    #                  general because Object__Methods is now a
    #                  tuple and we don't have length-0 or length-1 tuples.


                method_overrides                                        # Definitions which override an inherited method.
                    =
                    list::filter  filter_fn  methods_and_messages
                    where
                        fun filter_fn (NAMED_FUNCTION { pattern_clauses, is_lazy, kind, null_or_type })
                                =>
                                kind == METHOD_FUN;

                            filter_fn _
                                =>
                                raise exception FAIL "expand-oop-syntax.pkg: Internal compiler error.";
                        end;
                    end;


                methods_and_messages
                    =
                    map  convert_to_normal_function  methods_and_messages
                    where
                        fun convert_to_normal_function (NAMED_FUNCTION { pattern_clauses, is_lazy, kind, null_or_type })
                                =>
                                NAMED_FUNCTION { pattern_clauses, is_lazy, kind => PLAIN_FUN, null_or_type => NULL };

                            convert_to_normal_function _
                                =>
                                raise exception FAIL "expand-oop-syntax.pkg: convert_to_normal_function: Internal compiler error.";
                        end;
                    end;        


                # If the user did not declare an explicit superclass,
                # default to using 'object' as our superclass:
                #
                superclass
                    =
                    case (null_or_superclass)

                        THE superclass => superclass;

                        NULL
                            =>
                            NAMED_PACKAGE
                              { name_symbol =>  symbol::make_package_symbol "super",
                                definition  =>  PACKAGE_BY_NAME [ symbol::make_package_symbol "object" ],
                                constraint  =>  NO_PACKAGE_CAST,
                                kind        =>  PLAIN_PACKAGE
                              };
                    esac;


                parent_path
                    = 
                    REF [];

                #
                case superclass
                    (NAMED_PACKAGE { name_symbol, definition, constraint, kind })
                        =>
                        {   if *debugging  printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: supers[0].name_symbol is %s\n" (symbol::name name_symbol); fi;

                            case definition
                                ((PACKAGE_BY_NAME path) | (SOURCE_CODE_REGION_FOR_PACKAGE (PACKAGE_BY_NAME path,_)))
                                    =>
                                    {
                                        parent_path
                                            :=
                                            path;

                                        if *debugging

                                            printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: 'super' defined by name as: '";

                                            print_path path
                                            where
                                                fun print_path [] => ();
                                                    print_path [ symbol ] => { print (symbol::name symbol); };
                                                    print_path (symbol ! more) => { printf "%s::" (symbol::name symbol); print_path more; };
                                                end;
                                            end; 

                                            print "'\n";

                                            printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: superclass chain length of %s is %d\n" (eos::path_to_string *parent_path) (eos::compute_superclass_chain_length (symbolmapstack, *parent_path));
                                        fi;


                                        ();
                                    };
                                _ => ();
                            esac;
                            ();
                        };
                    _ => ();
                esac;


                message_count =  length message_definitions;
                method_count  =  length method_overrides;
                field_count   =  length fields;


                if *debugging

                    printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: %d method definitions found <=============================================\n"  message_count;

                    printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: %d method overrides found <=============================================\n"  method_count;

                    printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: %d fields found  <=============================================\n"  field_count;

                    printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: %d syntax errors found  <=============================================\n"  syntax_errors;
                fi;

                if (syntax_errors > 0)

                    # User declared 'super' twice
                    # or specified a non-existent
                    # superclass or some sort so just
                    # return a dummy package.  This
                    # avoids generating downstream errors
                    # from, for example, field declarations
                    # not removed from the original code
                    # because we didn't do full normal
                    # oop code expansion:
                    #
                    PACKAGE_DEFINITION (EXCEPTION_DECLARATIONS []);

                elif (message_count == 0
                and   method_count  == 0
                and   field_count   == 0)

                    # No OOP constructs present,
                    # so nothing to do -- just
                    # return original declaration:
                    #
                    PACKAGE_DEFINITION declaration;

                else

                    # We do have methods and/or fields, so at this
                    # point we need to expand them into vanilla
                    # Mythryl, thus converting the class definition
                    # into a vanilla package definition so far as
                    # downstream logic is concerned.
                    #
                    # First we compute a few useful values.
                    # Then we define functions to generate the various
                    # pieces of raw syntax which we will need.
                    # (Defining those functions nested here allows
                    # them to see our 'methods' 'fields' etc values
                    # without having to constantly pass them around
                    # as explicit arguments.)  Finally we put it all
                    # together as a rewritten raw syntax tree.


                    # How deep are we in the inheritance hierarchy?
                    # We need to know this because our argument
                    # initialization record tuple will have one
                    # entry for each superclass, plus us:
                    #
                    inheritance_hierarchy_depth
                        =
                        eos::compute_superclass_chain_length
                          (symbolmapstack, *parent_path);


                    if *debugging

                        printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: inheritance_hierarchy_depth d=%d\n" inheritance_hierarchy_depth;
                    fi;


                    # Now comes a good stretch of
                    # raw-syntax synthesis code:

                    #
                    fun make_object_fields_type_declaration (
                            fields:   List( Named_Field )                       # List of fields found in input class body.
                        )
                        :   Any_Type
                        =
                        {   # Our  input is a list of values like     NAMED_FIELD        (Symbol, Any_Type)
                            # Our output is a tuple  declaration      TULPE_TYPE   List (         Any_Type )
                            #
                            TUPLE_TYPE  (map  extract_type  fields)
                            where
                                fun extract_type (NAMED_FIELD { name, type, init })
                                        =>
                                        type;

                                    extract_type (SOURCE_CODE_REGION_FOR_NAMED_FIELD (named_field, _))
                                        =>
                                        extract_type  named_field;
                                end;
                            end;
                        };

                    #
                    fun make_init_fields_type_declaration (
                            fields:   List( Named_Field )                       # List of fields found in input class body.
                        )
                        :   Any_Type
                        =
                        {   # Our  input is a list of values like     NAMED_FIELD        (Symbol, Any_Type)
                            # Our output is a record declaration      RECORD_TYPE  List ((Symbol, Any_Type))
                            #
                            # The symbols are in both cases label_symbols,
                            # so we can use the input pairs as-is in our result:
                            #
                            RECORD_TYPE  (map  extract_symbol_and_type  fields)
                            where
                                fun extract_symbol_and_type (NAMED_FIELD { name, type, init })
                                        =>
                                        (name, type);

                                    extract_symbol_and_type (SOURCE_CODE_REGION_FOR_NAMED_FIELD (named_field, _))
                                        =>
                                        extract_symbol_and_type  named_field;
                                end;
                            end;
                        };


                    # Fishing the name of the method out of
                    # the raw syntax tree is a pain.  Here we
                    # look at the first clause and take the
                    # first variable in it at top level.
                    #
                    # This won't work if the user tries to
                    # define an infix method. XXX BUGGO FIXME
                    #
                    # Anyhow, the following functions do recursive
                    # descent down the raw syntax tree, innermost
                    # function first: 
                    # 
                    stipulate 

                        #
                        fun extract_name_of_symbol_from_path  [ symbol ]
                                =>
                                {   # We need to make up a new symbol because the existing
                                    # one from the pattern will be a value symbol but we
                                    # need a label symbol:
                                    #
                                    symbol::name  symbol;
                                };

                            extract_name_of_symbol_from_path  _
                                =>
                                raise exception FAIL "expand-oop-syntax.pkg: extract_name_of_symbol_from_path: Internal compiler error";        # XXX BUGGO FIXME what's the correct error protocol?
                        end;

                        #       
                        fun extract_name_of_symbol_from_patterns
                                ( { item => VARIABLE_IN_PATTERN path,  fixity => _,  source_code_region => _ }
                                  !
                                  more_patterns
                                )
                                =>
                                extract_name_of_symbol_from_path  path;

                            extract_name_of_symbol_from_patterns  (_ ! more_patterns)
                                =>
                                extract_name_of_symbol_from_patterns  more_patterns;

                            extract_name_of_symbol_from_patterns  []
                                =>
                                raise exception FAIL "expand-oop-syntax.pkg: extract_name_of_symbol_from_patterns: Internal compiler error";    # XXX BUGGO FIXME what's the correct error protocol?
                        end;

                        #
                        fun extract_name_of_symbol_from_fun_clause (PATTERN_CLAUSE { patterns, result_type, expression } )
                            =
                            extract_name_of_symbol_from_patterns  patterns;


                        #
                        fun extract_name_of_symbol_from_fun_clauses (fun_clause ! fun_clauses)
                                =>
                                extract_name_of_symbol_from_fun_clause  fun_clause;

                            extract_name_of_symbol_from_fun_clauses _
                                =>
                                raise exception FAIL "expand-oop-syntax.pkg: extract_name_of_symbol_from_fun_clauses:  Internal compiler error";                        # XXX BUGGO FIXME what's the correct error protocol?
                        end; 

                    herein

                        #
                        fun     name_string_of_mythryl_named_method (SOURCE_CODE_REGION_FOR_NAMED_FUNCTION (ff, _))
                                =>
                                name_string_of_mythryl_named_method  ff;

                            name_string_of_mythryl_named_method (NAMED_FUNCTION  { pattern_clauses, is_lazy, kind, null_or_type })
                                =>
                                extract_name_of_symbol_from_fun_clauses  pattern_clauses;
                        end;
                    end;

                    # To help map message names message tuple slots,
                    # make a list of all messages defined by this sub/class:
                    #
                    message_names
                        =
                        map  name_string_of_mythryl_named_method  message_definitions;

                    fun message_to_offset  message_name
                        =
                        message_to_offset' (message_names, 0)
                        where 
                            fun message_to_offset' ([], message_num)
                                    =>
                                    raise exception FAIL
                                      ( sprintf 
                                        "expand-oop-syntax.pkg: message_to_offset': error: Class %s defines no message %s"
                                        (symbol::name class_name)
                                        message_name
                                      );

                                message_to_offset' (message ! rest, message_num)
                                    =>
                                    if (message == message_name)
                                         message_num;
                                    else
                                         message_to_offset' (rest, message_num + 1);
                                    fi;
                            end;
                        end;


                    stipulate
                        # A convenience function shared
                        # by the next two functions:
                        #
                        fun     extract_type (SOURCE_CODE_REGION_FOR_NAMED_FUNCTION (f, _))
                                =>
                                extract_type f;

                            extract_type (NAMED_FUNCTION  { null_or_type, ... } )
                                =>
                                case null_or_type
                                     THE type => type;
                                     NULL     => raise exception FAIL "expand-oop-syntax.pkg: extract type:  Internal compiler errore"; # XXX BUGGO FIXME what's the correct error protocol?
                                esac;
                        end; 

                    herein

                        # Generate declaration of 'Object__Methods' record for subpackage.
                        #
                        fun make_methods_type_declaration (
                                methods:  List( Named_Function )                # List of methods found in input class body.
                            )
                            :   Any_Type
                            =
                            {   # Our  input is a list of values like      NAMED_FUNCTION { pattern_clauses: List( Pattern_Clause ), is_lazy: Bool, kind: Fun_Kind, null_or_type: Null_Or(Any_Type))
                                # Our output is a record declaration       RECORD_TYPE             (List ((Symbol, Any_Type)))
                                #
                                TUPLE_TYPE  (map  extract_type  methods);
                            };

                        # This is almost identical to the above,
                        # but generates method function declarations
                        # for the API instead of a Object__Methods record
                        # declaration for the package:
                        #
                        fun make_methods_type_declarations (
                                methods:  List( Named_Function )                # List of methods found in input class body.
                            )
                            :   List( Api_Element )
                            =
                            {   # Our  input is a list of values like      NAMED_FUNCTION { pattern_clauses: List( Pattern_Clause ), is_lazy: Bool, kind: Fun_Kind, null_or_type: Null_Or(Any_Type))
                                # Our output is a declaration:             VALUES_IN_API           (List ((Symbol, Any_Type)))
                                #
                                map  make_method_type_declaration  methods
                                where
                                    fun make_method_type_declaration  method
                                        =
                                        VALUES_IN_API [ extract_symbol_and_type  method ]
                                        where
                                            #
                                            fun extract_symbol_and_type  mythryl_named_method
                                                =
                                                ( symbol::make_value_symbol  (name_string_of_mythryl_named_method  mythryl_named_method),
                                                  extract_type                                                     mythryl_named_method
                                                );
                                        end;
                                end;
                            };
                    end;                                                # stipulate

                    #
                    fun make_methods_record
                            (methods:   List( Named_Function ))
                        :   Declaration
                        =
                        {   # Here we make the
                            #
                            #     object__methods
                            #         =
                            #         ( get_string_method,
                            #           get_int_method
                            #         );
                            #
                            # methods record definition statement,
                            # mutatis mutandis per actual methods declared:
                            #
                            VALUE_DECLARATIONS (
                              [                                                                                         # List( Named_Value )
                                NAMED_VALUE {

                                  pattern                                                                                       # Case_Pattern
                                      =>
                                      VARIABLE_IN_PATTERN [ symbol::make_value_symbol "object__methods" ],

                                  expression                                                                            # Raw_Expression
                                      =>
                                      TUPLE_EXPRESSION                                                                  # List( (Symbol, Raw_Expression) )
                                        (map  method_to_tuple_entry  methods),

                                  is_lazy => FALSE
                                }
                              ],
                              []                                                                                                # List( Typevar_Ref )
                            )
                            where
                                fun method_to_tuple_entry  mythryl_named_method
                                    =
                                    {   name_string
                                            =
                                            name_string_of_mythryl_named_method
                                                           mythryl_named_method;

                                        VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol  name_string  ];
                                    };
                            end;
                        };

                    #
                    stipulate
                        fun make_get_fields_or_get_methods_function
                            ( function_name,                            # "get__fields" or "get__methods"
                              return_value                                      # "object__fields" or "object__methods"
                            )
                            :   Declaration
                            =
                            {   # Here we make a function to extract just
                                # our object__fields or object__methods record:
                                #
                                #     fun get__fields (self: Self(X))
                                #         =
                                #         {   (super::get__substate  self)
                                #                 ->
                                #                 (OBJECT__STATE { object__methods, object__fields }, substate);
                                #
                                #             object__fields;
                                #         };
                                #
                                # of
                                #
                                #     fun get__methods (self: Self(X))
                                #         =
                                #         {   (super::get__substate  self)
                                #                 ->
                                #                 (OBJECT__STATE { object__methods, object__fields }, substate);
                                #
                                #             object__methods;
                                #         };
                                #
                                #

                                FUNCTION_DECLARATIONS 
                                  (
                                    [ get_fields ],
                                    []                                                                                          # List( Typevar_Ref )
                                  )
                                  where
                                      get_fields
                                          =
                                          NAMED_FUNCTION
                                            {
                                              kind    => PLAIN_FUN,
                                              is_lazy => FALSE,

                                              null_or_type => NULL,

                                              pattern_clauses
                                                  =>
                                                  [                                                                                     # List( Pattern_Clause )
                                                    PATTERN_CLAUSE
                                                      { patterns
                                                            =>
                                                            [ { fixity => NULL,
                                                                source_code_region => (0,0),
                                                                item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol function_name ]
                                                              },
                                                              { fixity => NULL,
                                                                source_code_region => (0,0),
                                                                item => TYPE_CONSTRAINT_PATTERN
                                                                            { pattern                                           # Case_Pattern
                                                                                  =>
                                                                                  VARIABLE_IN_PATTERN
                                                                                    [ symbol::make_value_symbol "self" ],

                                                                              type_constraint                                   # Any_Type
                                                                                  =>    
                                                                                  TYP_TYPE
                                                                                    ( [ symbol::make_type_symbol "Self" ],
                                                                                      [ TYPE_VARIABLE_TYPE typevar_x ]          # anytype'
                                                                                    )
                                                                            }
                                                              }
                                                            ],

                                                        result_type 
                                                            =>
                                                            NULL, 

                                                        expression
                                                            =>
                                                            LET_EXPRESSION {

                                                              declaration                                                               # Declaration
                                                                =>
                                                                SEQUENTIAL_DECLARATIONS [
                                                                  VALUE_DECLARATIONS (
                                                                    [ NAMED_VALUE {                                                     # List( Named_Value )

                                                                        is_lazy => FALSE,

                                                                        pattern                                                 # Case_Pattern
                                                                            =>  
                                                                            TUPLE_PATTERN [                                             # List( Case_Pattern )

                                                                              APPLY_PATTERN
                                                                                {
                                                                                  constructor                                   # Case_Pattern
                                                                                      =>
                                                                                      VARIABLE_IN_PATTERN
                                                                                        [ symbol::make_value_symbol "OBJECT__STATE" ],

                                                                                  argument                                      # Case_Pattern
                                                                                      =>
                                                                                      RECORD_PATTERN
                                                                                        {
                                                                                          is_incomplete => FALSE,                       # No "..."

                                                                                          definition                            # List( (Symbol, Case_Pattern) )
                                                                                              =>
                                                                                              [ (                       symbol::make_label_symbol "object__methods",
                                                                                                  VARIABLE_IN_PATTERN [ symbol::make_value_symbol "object__methods" ]
                                                                                                ),
                                                                                                (                       symbol::make_label_symbol "object__fields",
                                                                                                  VARIABLE_IN_PATTERN [ symbol::make_value_symbol "object__fields" ]
                                                                                                )
                                                                                              ]
                                                                                        }
                                                                                },

                                                                              VARIABLE_IN_PATTERN
                                                                                [ symbol::make_value_symbol "substate" ]                # We don't use the value this binds.
                                                                            ],

                                                                        expression                                                      # Raw_Expression
                                                                            =>
                                                                            APPLY_EXPRESSION
                                                                              {
                                                                                function                                                # Raw_Expression
                                                                                  =>
                                                                                  VARIABLE_IN_EXPRESSION
                                                                                    [ symbol::make_package_symbol "super",
                                                                                      symbol::make_value_symbol "get__substate"
                                                                                    ],

                                                                                argument                                                # Raw_Expression
                                                                                  =>
                                                                                  VARIABLE_IN_EXPRESSION
                                                                                    [ symbol::make_value_symbol "self" ]
                                                                              }
                                                                      }
                                                                    ],
                                                                    []                                                                  # List( Typevar_Ref )
                                                                  )                                                                     # VALUE_DECLARATIONS
                                                                ],                                                                      # SEQUENTIAL_DECLARATIONS

                                                              expression                                                                # Raw_Expression
                                                                =>
                                                                VARIABLE_IN_EXPRESSION
                                                                  [ symbol::make_value_symbol  return_value ]
                                                            }                                                                           # LET_EXPRESSION
                                                      }
                                                  ]
                                            };
                                  end;
                            };
                    herein
                        fun make_function_get_fields  () =  make_get_fields_or_get_methods_function ("get__fields",  "object__fields" );
                        fun make_function_get_methods () =  make_get_fields_or_get_methods_function ("get__methods", "object__methods");
                    end;

                    #
                    fun make_method_dispatch_functions
                        (methods:    List( Named_Function ))
                        :   Declaration
                        =
                        {   # Here we make for each method a wrapper
                            # function which merely finds and invokes
                            # the appropriate method function.  For
                            # example for a method 'get_string' we
                            # would synthesize:
                            #
                            #     fun get_string (self: Self(X))
                            #         =
                            #         {   object__methods = get__methods self;
                            #
                            #             (#1 object__methods)  self;
                            #         };
                            #
                            # This provides dynamic dispatch because different
                            # subclasses of us may have stored different functions
                            # in their copy of the methods vector.

                            method_names
                                =
                                map  name_string_of_mythryl_named_method
                                     methods;

                            SEQUENTIAL_DECLARATIONS 
                              (
                                map  make_method_dispatch_function
                                     method_names
                              )
                              where
                                  fun make_method_dispatch_function  method_name
                                      =
                                      FUNCTION_DECLARATIONS
                                        (
                                          [
                                            NAMED_FUNCTION
                                              {
                                                kind    => PLAIN_FUN,
                                                is_lazy => FALSE,

                                                null_or_type => NULL,

                                                pattern_clauses
                                                    =>
                                                    [                                                                                   # List( Pattern_Clause )
                                                      PATTERN_CLAUSE
                                                        { patterns
                                                              =>
                                                              [ { fixity => NULL,
                                                                  source_code_region => (0,0),
                                                                  item => VARIABLE_IN_PATTERN
                                                                            [ symbol::make_value_symbol method_name ]                   # First place  method_name  is used.
                                                                },
                                                                { fixity => NULL,
                                                                  source_code_region => (0,0),
                                                                  item => TYPE_CONSTRAINT_PATTERN
                                                                              { pattern                                         # Case_Pattern
                                                                                    =>
                                                                                    VARIABLE_IN_PATTERN
                                                                                      [ symbol::make_value_symbol "self" ],

                                                                                type_constraint                                 # Any_Type
                                                                                    =>  
                                                                                    TYP_TYPE
                                                                                      ( [ symbol::make_type_symbol "Self" ],
                                                                                        [ TYPE_VARIABLE_TYPE typevar_x ]                # anytype'
                                                                                      )
                                                                              }
                                                                }
                                                              ],

                                                          result_type 
                                                              =>
                                                              NULL, 

                                                          expression
                                                              =>
                                                              LET_EXPRESSION {

                                                                declaration                                                             # Declaration
                                                                  =>
                                                                  SEQUENTIAL_DECLARATIONS [
                                                                    VALUE_DECLARATIONS (
                                                                      [ NAMED_VALUE {                                                   # List( Named_Value )

                                                                          is_lazy => FALSE,

                                                                          pattern                                                       # Case_Pattern
                                                                              =>        
                                                                              VARIABLE_IN_PATTERN [ symbol::make_value_symbol "object__methods" ],

                                                                          expression                                                    # Raw_Expression
                                                                              =>
                                                                              APPLY_EXPRESSION
                                                                                {
                                                                                  function                                              # Raw_Expression
                                                                                    =>
                                                                                    VARIABLE_IN_EXPRESSION
                                                                                      [ symbol::make_value_symbol "get__methods" ],

                                                                                  argument                                              # Raw_Expression
                                                                                    =>
                                                                                    VARIABLE_IN_EXPRESSION
                                                                                      [ symbol::make_value_symbol "self" ]
                                                                                }
                                                                        }
                                                                      ],
                                                                      []                                                                        # List( Typevar_Ref )
                                                                    )                                                                   # VALUE_DECLARATIONS
                                                                  ],                                                                    # SEQUENTIAL_DECLARATIONS

                                                                expression                                                              # Raw_Expression
                                                                  =>
                                                                  APPLY_EXPRESSION
                                                                    {
                                                                      function                                                          # Raw_Expression
                                                                        =>
                                                                        APPLY_EXPRESSION
                                                                          {
                                                                            function                                                    # Raw_Expression
                                                                              =>
                                                                              RECORD_SELECTOR_EXPRESSION
                                                                                (symbol::make_label_symbol  (int::to_string ((message_to_offset method_name) + 1))),                    # Second (and last) place method_name gets used.

                                                                            argument                                                    # Raw_Expression
                                                                              =>
                                                                              VARIABLE_IN_EXPRESSION
                                                                                [ symbol::make_value_symbol "object__methods" ]
                                                                          },

                                                                      argument                                                          # Raw_Expression
                                                                        =>
                                                                        VARIABLE_IN_EXPRESSION
                                                                          [ symbol::make_value_symbol "self" ]
                                                                    }
                                                              }                                                                         # LET_EXPRESSION
                                                        }
                                                    ]
                                              }
                                          ],

                                          []                                                                                            # List( Typevar_Ref )
                                        );
                              end;                                                                                                              # where
                        };                                                                                                                      # fun make_method_dispatch_functions

                    #
                    fun wrap_method_and_message_functions
                        (methods_and_messages:    List( Named_Function ))
                        :   Declaration
                        =
                        SEQUENTIAL_DECLARATIONS
                            (map  wrap  methods_and_messages)
                            where
                                fun wrap  method_or_message
                                    =
                                    FUNCTION_DECLARATIONS
                                      (
                                        [ method_or_message ],
                                        []
                                      );
                            end;

                    #
                    fun make_method_override_calls
                        ( methods:    List( Named_Function )
                        )
                        :   List( Declaration )
                        =
                        {   # Here we make for each overridden method
                            # a call to go in 'make__object' of the form
                            #     self  =  super::override__get  replacement_get  self;
                            # where 'get' is replaced by the appropriate
                            # method name and there may be any number of
                            # "super::" prefixes on the override function:

                            parent_path
                                =
                                eos::path_for_parent_class  superclass;

                            if *debugging  print ("make_method_override_calls: path to parent is " + (eos::path_to_string  parent_path) + "\n"); fi;


                            loop (methods, []) 
                            where 
                                fun loop ([], results)
                                        =>
                                        reverse  results;                                                                       # List( Declaration )

                                    loop (method ! remaining_methods, results)
                                        =>
                                        {
                                            method_name
                                                =
                                                name_string_of_mythryl_named_method
                                                     method;

                                            override_function_symbol
                                                =
                                                symbol::make_value_symbol
                                                    ("override__" + method_name);

                                            case (eos::find_path_defining_method
                                                   ( symbolmapstack,
                                                     parent_path,
                                                     method_name
                                                 ) )

                                                THE method_path
                                                    =>
                                                    {
                                                        if *debugging
                                                            printf "make_method_override_calls: Method %s is defined in %s\n"     method_name (eos::path_to_string method_path);
                                                            printf "make_method_override_calls: Override function for %s is %s\n" method_name (eos::path_to_string (method_path @ [ override_function_symbol ]));
                                                        fi;

                                                        declaration
                                                            =
                                                            # Synthesize
                                                            #     self  =  super::override__get get self;
                                                            #           
                                                            VALUE_DECLARATIONS (
                                                              [
                                                                NAMED_VALUE {

                                                                  is_lazy => FALSE,

                                                                  pattern                                                               # Case_Pattern
                                                                      =>
                                                                      VARIABLE_IN_PATTERN
                                                                        [ symbol::make_value_symbol "self" ],

                                                                  expression                                                    # Raw_Expression
                                                                      =>
                                                                      APPLY_EXPRESSION {

                                                                        function                                                        # Raw_Expression
                                                                          =>
                                                                          APPLY_EXPRESSION {

                                                                            function                                            # Raw_Expression
                                                                              =>
                                                                              VARIABLE_IN_EXPRESSION
                                                                                ( method_path
                                                                                  @
                                                                                  [ override_function_symbol ]
                                                                                ),

                                                                            argument                                            # Raw_Expression
                                                                              =>
                                                                              VARIABLE_IN_EXPRESSION
                                                                                [ symbol::make_value_symbol method_name ]
                                                                          },    

                                                                        argument                                                        # Raw_Expression
                                                                          =>
                                                                          VARIABLE_IN_EXPRESSION
                                                                            [ symbol::make_value_symbol "self" ]
                                                                      }
                                                                }
                                                              ],

                                                              []                                                                        # Type variables.
                                                            ); 

                                                        if *debugging  print ("Now generating override call for method '" + method_name + "'\n"); fi;

                                                        loop (remaining_methods, declaration ! results);
                                                    };

                                                NULL
                                                    =>
                                                    {    raise exception FAIL ("make_method_override_calls:  Did not find path defining method " + method_name + "\n");
                                                    };
                                            esac;

                                        };      
                                end;
                            end;
                        };                                              # fun make_method_override_calls


                    #
                    fun declare_method_override_functions
                        ( methods:    List( Named_Function ),
                          results:    List( Api_Element    )
                        )
                        :   List( Api_Element )
                        =
                        case methods

                            [] =>  reverse results;

                            method ! remaining_methods
                                =>
                                {
                                    # The method type will be something like
                                    #     Self(X) -> String
                                    # Call that Method.
                                    #
                                    # The replacement method will be of type
                                    #     Method -> Method
                                    # because it receives the old method as its
                                    # first argument.  (It may need the old method,
                                    # and has no other easy way of getting access
                                    # to it.)
                                    # Call that Replacement.
                                    #
                                    # The method override function has type
                                    #     Replacement -> Self(X) -> Self(X)
                                    # because it accepts first the replacement
                                    # function, then the object to be modified,
                                    # and returns the modified object.

                                    method_type
                                        =
                                        case method
                                            NAMED_FUNCTION { null_or_type => THE type, ... }
                                                =>
                                                type;

                                            _   => raise exception FAIL  "oop-expand-syntax.pkg: declare_method_override_functions: Internal compiler error";
                                        esac;

                                    method_name
                                        =
                                        name_string_of_mythryl_named_method
                                            method;

                                    replacement_type
                                        =
                                        TYP_TYPE
                                          ( [ symbol::make_type_symbol "->" ],
                                            [ method_type,
                                              method_type
                                            ]
                                          );

                                    #
                                    method_override_fun_type
                                        =
                                        TYP_TYPE
                                          ( [ symbol::make_type_symbol "->" ],
                                            [ replacement_type,
                                              TYP_TYPE
                                                ( [ symbol::make_type_symbol "->" ],
                                                  [ TYP_TYPE
                                                      ( [ symbol::make_type_symbol "Self" ],
                                                        [ TYPE_VARIABLE_TYPE typevar_x ]
                                                      ),
                                                    TYP_TYPE
                                                      ( [ symbol::make_type_symbol "Self" ],
                                                        [ TYPE_VARIABLE_TYPE typevar_x ]
                                                      )
                                                  ]
                                                )
                                            ]
                                          );

                                    declaration
                                        =
                                        ( symbol::make_value_symbol  ("override__" + method_name),
                                          method_override_fun_type
                                        );

                                    declare_method_override_functions
                                      (
                                        remaining_methods,
                                        (VALUES_IN_API [ declaration ]) ! results
                                      );
                                };
                        esac;

                                                                                                                            # oop                       is from   src/lib/src/oop.pkg
                    #
                    fun make_method_override_functions
                        (methods:    List( Named_Function ))
                        :   Declaration
                        =
                        {   # Here we make for each method a function
                            # which overrides that method in the methods record
                            # by synthesizing a complete new object otherwise
                            # identical to the prototype object 'me'.
                            #
                            # For a method 'get_int' in a class with only
                            # 'get_int' and 'get_string' methods this will
                            # look like:
                            #
                            #     fun override__get_int  new_method  me
                            #         =
                            #         oop::repack_object
                            #             (fn (OBJECT__STATE { object__fields, object__methods })
                            #                     =
                            #                     OBJECT__STATE
                            #                       { object__fields,
                            #                         object__methods
                            #                             =>
                            #                             (             (#1 object__methods),  # get_string
                            #                               (new_method (#2 object__methods)   # get_int
                            #                             )
                            #                       }
                            #                 )
                            #             (super::unpack__object  me);
                            #

                            method_names
                                =
                                map  name_string_of_mythryl_named_method
                                     methods;

                            SEQUENTIAL_DECLARATIONS
                                (map  make_named_function
                                      method_names
                                )
                            where
                                fun make_named_function
                                        method_name
                                    =
                                    FUNCTION_DECLARATIONS
                                      ( 
                                        [
                                          NAMED_FUNCTION
                                            {
                                              kind    => PLAIN_FUN,
                                              is_lazy => FALSE,

                                              null_or_type => NULL,

                                              pattern_clauses
                                                  =>
                                                  [                                                                                     # List( Pattern_Clause )
                                                    PATTERN_CLAUSE
                                                      {
                                                        result_type                                                                     # Null_Or( Any_Type )
                                                          =>
                                                          NULL,

                                                        patterns                                                                        # List( Fixity_Item( Case_Pattern ) )
                                                          =>    
                                                          [
                                                            { fixity => NULL,
                                                              source_code_region => (0,0),
                                                              item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol ("override__" + method_name) ]
                                                            },
                                                            { fixity => NULL,
                                                              source_code_region => (0,0),
                                                              item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "new_method" ]
                                                            },
                                                            { fixity => NULL,
                                                              source_code_region => (0,0),
                                                              item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "me" ]
                                                            }
                                                          ],

                                                        expression                                                                      # Raw_Expression
                                                          =>    
                                                          APPLY_EXPRESSION {

                                                            function                                                                    # Raw_Expression
                                                              =>
                                                              APPLY_EXPRESSION {

                                                                function                                                                # Raw_Expression
                                                                  =>
                                                                  VARIABLE_IN_EXPRESSION
                                                                    [ symbol::make_package_symbol "oop",
                                                                      symbol::make_value_symbol   "repack_object"
                                                                    ],

                                                                argument                                                                # Raw_Expression
                                                                  =>
                                                                  FN_EXPRESSION
                                                                    [                                                                   # List( Case_Rule );
                                                                      CASE_RULE {
                                                                        pattern                                                 # Case_Pattern
                                                                          =>
                                                                          APPLY_PATTERN {

                                                                            constructor                                         # Case_Pattern
                                                                              =>
                                                                              VARIABLE_IN_PATTERN
                                                                                [ symbol::make_value_symbol "OBJECT__STATE" ],

                                                                            argument                                                    # Case_Pattern
                                                                              =>
                                                                              RECORD_PATTERN {

                                                                                is_incomplete => FALSE,                         # No "..."

                                                                                definition                                              # List( (Symbol, Case_Pattern) )
                                                                                  =>
                                                                                  [ (                       symbol::make_label_symbol "object__methods",
                                                                                      VARIABLE_IN_PATTERN [ symbol::make_value_symbol "object__methods" ]
                                                                                    ),
                                                                                    (                       symbol::make_label_symbol "object__fields",
                                                                                      VARIABLE_IN_PATTERN [ symbol::make_value_symbol "object__fields" ]
                                                                                    )
                                                                                  ]
                                                                              }
                                                                          },
                                                                        expression                                                      # Raw_Expression
                                                                          =>
                                                                          APPLY_EXPRESSION {

                                                                            function                                                    # Raw_Expression
                                                                              =>
                                                                              VARIABLE_IN_EXPRESSION
                                                                                [ symbol::make_value_symbol "OBJECT__STATE" ],

                                                                            argument                                                    # Raw_Expression
                                                                              =>
                                                                              RECORD_IN_EXPRESSION [                                    # List( (Symbol, Raw_Expression) )

                                                                                (                          symbol::make_label_symbol "object__fields",
                                                                                  VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol "object__fields" ]
                                                                                ),

                                                                                ( symbol::make_label_symbol "object__methods",
                                                                                  TUPLE_EXPRESSION                                      # List( Raw_Expression)
                                                                                   (map  make_tuple_entry  method_names)
                                                                                    where
                                                                                        fun make_tuple_entry  name
                                                                                            =
                                                                                            if (name == method_name)

                                                                                                # Replace overridden method by
                                                                                                #     (new_method object__methods.method_name):
                                                                                                #
                                                                                                APPLY_EXPRESSION {

                                                                                                  function                                                              # Raw_Expression
                                                                                                    =>
                                                                                                    VARIABLE_IN_EXPRESSION
                                                                                                      [ symbol::make_value_symbol "new_method" ],

                                                                                                  argument                                                              # Raw_Expression
                                                                                                    =>
                                                                                                      APPLY_EXPRESSION
                                                                                                        {
                                                                                                          function                                                      # Raw_Expression
                                                                                                            =>
                                                                                                            RECORD_SELECTOR_EXPRESSION
                                                                                                              (symbol::make_label_symbol  (int::to_string ((message_to_offset name) + 1))),

                                                                                                          argument                                                      # Raw_Expression
                                                                                                            =>
                                                                                                            VARIABLE_IN_EXPRESSION
                                                                                                              [ symbol::make_value_symbol "object__methods" ]
                                                                                                        }
                                                                                                };
                                                                                            else
                                                                                                # Non-overridden methods just get copied over:
                                                                                                #
                                                                                                APPLY_EXPRESSION
                                                                                                  {
                                                                                                    function                                                    # Raw_Expression
                                                                                                      =>
                                                                                                      RECORD_SELECTOR_EXPRESSION
                                                                                                        (symbol::make_label_symbol  (int::to_string ((message_to_offset name) + 1))),

                                                                                                    argument                                                    # Raw_Expression
                                                                                                      =>
                                                                                                      VARIABLE_IN_EXPRESSION
                                                                                                        [ symbol::make_value_symbol "object__methods" ]
                                                                                                  };
                                                                                            fi;
                                                                                    end
                                                                                )
                                                                              ]
                                                                          }
                                                                      }
                                                                    ]
                                                              },

                                                            argument                                                                    # Raw_Expression
                                                              =>
                                                              APPLY_EXPRESSION {

                                                                function                                                                # Raw_Expression
                                                                  =>
                                                                  VARIABLE_IN_EXPRESSION
                                                                    [ symbol::make_package_symbol "super",
                                                                      symbol::make_value_symbol "unpack__object"
                                                                    ],

                                                                argument                                                                # Raw_Expression
                                                                  =>
                                                                  VARIABLE_IN_EXPRESSION
                                                                    [ symbol::make_value_symbol "me" ]
                                                              }
                                                        }
                                                      }
                                                  ]

                                            }
                                        ],

                                        []                                                                                      # Type variables
                                      );
                                                                                                                            # NAMED_FUNCTION
                            end;                                                                                                # 'where'
                        };

                                                                                                                            # oop                       is from   src/lib/src/oop.pkg
                    #
                    fun make_function_make_object_fields ()
                        :   Declaration
                        =
                        {   # Here we make a function which given an
                            # Initializer__Fields record 'init' creates an
                            # Object__Fields tuple:
                            #
                            #     fun make_object__fields (init: Initializer__Fields)
                            #         =
                            #         ( init.field1,            # No initializer given  in 'field my Foo field1;' so initialize from 'init'.
                            #               0                   # Initializer specified in 'field my Int field2 = 0;' statement.
                            #         );        
                            #

                            FUNCTION_DECLARATIONS ( 

                              [ make_fun () ],                                                                          # List( Named_Function )

                              []                                                                                                # List( Typevar_Ref )
                            )
                            where
                                fun make_fun ()
                                    =
                                    NAMED_FUNCTION
                                      {
                                        kind    => PLAIN_FUN,
                                        is_lazy => FALSE,

                                        null_or_type => NULL,

                                        pattern_clauses
                                            =>
                                            [                                                                           # List( Pattern_Clause )
                                              PATTERN_CLAUSE
                                                {
                                                  result_type                                                           # Null_Or( Any_Type )
                                                    =>
                                                    NULL,

                                                  patterns                                                                      # List( Fixity_Item( Case_Pattern ) )
                                                    =>  
                                                    [
                                                      { fixity => NULL,
                                                        source_code_region => (0,0),
                                                        item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "make_object__fields" ]
                                                      },
                                                      { fixity => NULL,
                                                        source_code_region => (0,0),
                                                        item => TYPE_CONSTRAINT_PATTERN
                                                                    { pattern                                           # Case_Pattern
                                                                          =>
                                                                          VARIABLE_IN_PATTERN
                                                                            [ symbol::make_value_symbol "init" ],

                                                                      type_constraint                                   # Any_Type
                                                                          =>    
                                                                          TYP_TYPE
                                                                            ( [ symbol::make_type_symbol "Initializer__Fields" ],
                                                                              [ TYPE_VARIABLE_TYPE typevar_x ]                                          # anytype'
                                                                            )
                                                                    }
                                                      }
                                                    ],

                                                  expression                                                                    # Raw_Expression
                                                    =>  
                                                    TUPLE_EXPRESSION
                                                       (map  make_tuple_entry fields)
                                                       where
                                                           fun make_tuple_entry (NAMED_FIELD { name, type, init => NULL } )
                                                                   =>
                                                                   # User's
                                                                   #     field my String foo;
                                                                   # statement provided no default value,
                                                                   # so copy one over from initializer record:
                                                                   #
                                                                   APPLY_EXPRESSION
                                                                     {
                                                                       function                                                 # Raw_Expression
                                                                         =>
                                                                         RECORD_SELECTOR_EXPRESSION
                                                                           (symbol::make_label_symbol  (symbol::name name)),

                                                                       argument                                                 # Raw_Expression
                                                                         =>
                                                                         VARIABLE_IN_EXPRESSION
                                                                           [ symbol::make_value_symbol "init" ]
                                                                     };

                                                               make_tuple_entry (NAMED_FIELD { name, type, init => THE expression } )
                                                                   =>
                                                                   # Set field to default value provided
                                                                   # by user in
                                                                   #     field my String foo = "whatever";
                                                                   #
                                                                   expression;

                                                               make_tuple_entry _
                                                                   =>
                                                                   raise exception FAIL "expand-oop-syntax.pkg: make_function_make_object_fields: Internal compiler error";
                                                           end;                                                         # fun make_record_entry
                                                       end                                                                      # where
                                                }
                                            ]
                                      };                                                                                        # NAMED_FUNCTION
                            end;                                                                                                # 'where'
                        };

                                                                                                                            # oop                       is from   src/lib/src/oop.pkg
                    #
                    fun make_function_get_substate ()
                        :   Declaration
                        =
                        {   # Here we make
                            #
                            #     fun get__substate me
                            #         =
                            #         {   my (state, substate) =  super::get__substate  me;
                            #             substate;
                            #     }; 
                            #
                            # This could be abbreviated to just   
                            #
                            #         fun get__substate me =   #2 (super::get__substate me);
                            #
                            # but we're not APL programmers!
                            #
                            FUNCTION_DECLARATIONS 
                                ( [ NAMED_FUNCTION
                                        {
                                          kind    => PLAIN_FUN,
                                          is_lazy => FALSE,

                                          null_or_type => NULL,

                                          pattern_clauses
                                              =>
                                              [ PATTERN_CLAUSE
                                                  { patterns
                                                        =>
                                                        [ { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "get__substate" ]
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "me" ]
                                                          }
                                                        ],

                                                    result_type 
                                                        =>
                                                        NULL, 

                                                    expression
                                                        =>
                                                        LET_EXPRESSION {

                                                          declaration                                                           # Declaration
                                                            =>
                                                            SEQUENTIAL_DECLARATIONS [
                                                              VALUE_DECLARATIONS (
                                                                [ NAMED_VALUE {                                                 # List( Named_Value )

                                                                    is_lazy => FALSE,

                                                                    pattern                                                     # Case_Pattern
                                                                        =>      
                                                                        TUPLE_PATTERN [                                         # List( Case_Pattern )

                                                                          VARIABLE_IN_PATTERN
                                                                            [ symbol::make_value_symbol "state" ],              # We don't use the value this binds.


                                                                          VARIABLE_IN_PATTERN
                                                                            [ symbol::make_value_symbol "substate" ]
                                                                        ],

                                                                    expression                                                  # Raw_Expression
                                                                        =>
                                                                        APPLY_EXPRESSION
                                                                          {
                                                                            function                                                            # Raw_Expression
                                                                              =>
                                                                              VARIABLE_IN_EXPRESSION
                                                                                [ symbol::make_package_symbol "super",
                                                                                  symbol::make_value_symbol   "get__substate"
                                                                                ],

                                                                            argument                                                            # Raw_Expression
                                                                              =>
                                                                              VARIABLE_IN_EXPRESSION
                                                                                [ symbol::make_value_symbol "me" ]
                                                                          }
                                                                  }
                                                                ],
                                                                []                                                                      # List( Typevar_Ref )
                                                              )                                                                 # VALUE_DECLARATIONS
                                                            ],                                                                  # SEQUENTIAL_DECLARATIONS

                                                          expression                                                            # Raw_Expression
                                                            =>
                                                            VARIABLE_IN_EXPRESSION
                                                                [ symbol::make_value_symbol "substate" ]

                                                        }                                                                               # LET_EXPRESSION
                                                  }
                                              ]
                                        }
                                  ],
                                  [                                     # Type variables
                                  ]
                                ); 
                        };

                    #
                    fun make_function_unpack_object ()
                        :   Declaration
                        =
                        {   # Here we make
                            #
                            #     fun unpack__object  me
                            #         =
                            #         oop::unpack_object  (super::unpack__object me); 
                            #
                            # This fun will yield the usual
                            #
                            #     (repack, (state, substate))
                            #
                            # where
                            #     (repack (state, substate))
                            # will recreate 'me' by re-wrapping it with the states for
                            # all our superlcasses and
                            #     state
                            # is our own (STATE { object__fields, object__methods }) and
                            #     substate
                            # is oop::OOP_NULL or else the (state', substate')
                            # tuple for our subclass.
                            #
                            FUNCTION_DECLARATIONS 
                                ( [ NAMED_FUNCTION
                                        {
                                          kind    => PLAIN_FUN,
                                          is_lazy => FALSE,

                                          null_or_type => NULL,

                                          pattern_clauses
                                              =>
                                              [ PATTERN_CLAUSE
                                                  { patterns
                                                        =>
                                                        [ { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "unpack__object" ]
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "me" ]
                                                          }
                                                        ],

                                                    result_type 
                                                        =>
                                                        NULL, 

                                                    expression
                                                        =>
                                                        PRE_FIXITY_EXPRESSION [
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_EXPRESSION [ symbol::make_package_symbol "oop",
                                                                                             symbol::make_value_symbol   "unpack_object"
                                                                                           ]
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => PRE_FIXITY_EXPRESSION  [
                                                                      { fixity => NULL,
                                                                        source_code_region => (0,0),
                                                                        item => VARIABLE_IN_EXPRESSION [ symbol::make_package_symbol "super",
                                                                                                         symbol::make_value_symbol   "unpack__object"
                                                                                                       ]
                                                                      },
                                                                      { fixity => NULL,
                                                                        source_code_region => (0,0),
                                                                        item => VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol   "me" ]
                                                                      }
                                                                    ]
                                                          }
                                                        ]
                                                  }
                                              ]
                                        }
                                  ],
                                  [                                     # Type variables
                                  ]
                                ); 
                        };

                    #
                    fun make_function_pack_object ()
                        :   Declaration
                        =
                        {   # Here we make
                            #
                            #     fun pack__object (fields_1, fields_0) substate
                            #         =
                            #         {   object__fields = make_object__fields fields_1;
                            #
                            #             self = super::pack__object  fields_0  (OBJECT__STATE { object__methods, object__fields }, substate);
                            #
                            #             self = super::override__get replacement_get self;     # One of these for each overridden method.
                            #
                            #             self;
                            #         };
                            #
                            # If we are five deep in the inheritance hierarchy
                            # this will look like
                            #
                            #     fun pack__object (fields_4, fields_3, fields_2, fields_1, fields_0) substate
                            #         =
                            #         {   object__fields = make_object__fields fields_4;
                            #
                            #             self = super::pack__object (fields_3, fields_2, fields_1, fields_0) (OBJECT__STATE { object__methods, object__fields }, substate);
                            #
                            #             self = super::override__get replacement_get self;     # One of these for each overridden method.
                            #
                            #         self;
                            #         };        
                            #
                            FUNCTION_DECLARATIONS 
                                ( [ NAMED_FUNCTION
                                        {
                                          kind    => PLAIN_FUN,
                                          is_lazy => FALSE,

                                          null_or_type => NULL,

                                          pattern_clauses
                                              =>        
                                              [ PATTERN_CLAUSE
                                                  { patterns
                                                        =>
                                                        [ { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "pack__object" ]
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item
                                                                =>
                                                                TUPLE_PATTERN
                                                                    ( loop (inheritance_hierarchy_depth, [])
                                                                      where
                                                                          fun loop (0, result_list)
                                                                                  =>
                                                                                  reverse  result_list;

                                                                              loop (i, result_list)
                                                                                  =>
                                                                                  loop
                                                                                    ( i - 1,
                                                                                      (VARIABLE_IN_PATTERN [ (symbol::make_value_symbol (sprintf "fields_%d" (i - 1))) ])
                                                                                      !
                                                                                      result_list
                                                                                    );
                                                                          end;
                                                                      end
                                                                    )
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "substate" ]
                                                          }
                                                        ],

                                                    result_type 
                                                        =>
                                                        NULL, 


                                                    expression
                                                        =>
                                                        LET_EXPRESSION {

                                                          declaration                                                           # Declaration
                                                            =>
                                                            SEQUENTIAL_DECLARATIONS ([

                                                              # Synthesize
                                                              #         
                                                              #     our_fields = make_object__fields  fields_1; # or fields_3 or whatever.
                                                              #         
                                                              VALUE_DECLARATIONS (
                                                                [                                                                       # List( Named_Value )
                                                                  NAMED_VALUE
                                                                    {
                                                                      is_lazy => FALSE,

                                                                      pattern                                                   # Case_Pattern
                                                                          =>
                                                                          VARIABLE_IN_PATTERN
                                                                            [ symbol::make_value_symbol "object__fields" ],

                                                                      expression                                                        # Raw_Expression
                                                                          =>
                                                                          APPLY_EXPRESSION
                                                                            {
                                                                              function                                          # Raw_Expression
                                                                                =>
                                                                                VARIABLE_IN_EXPRESSION
                                                                                  [ symbol::make_value_symbol "make_object__fields" ],

                                                                              argument                                          # Raw_Expression
                                                                                =>
                                                                                VARIABLE_IN_EXPRESSION
                                                                                  [ symbol::make_value_symbol (sprintf "fields_%d" (inheritance_hierarchy_depth - 1)) ]
                                                                            }
                                                                    }
                                                                ],

                                                                []                                                                      # List( Typevar_Ref )
                                                              ),

                                                              VALUE_DECLARATIONS (
                                                                [                                                                       # List( Named_Value )

                                                                  # Synthesize
                                                                  #     self = super::pack__object  fields_0  (OBJECT__STATE { object__methods, object__fields => our_fields }, substate);
                                                                  #             
                                                                  NAMED_VALUE {

                                                                    is_lazy => FALSE,

                                                                    pattern                                                             # Case_Pattern
                                                                        =>
                                                                        VARIABLE_IN_PATTERN
                                                                          [ symbol::make_value_symbol "self" ],

                                                                    expression                                                  # Raw_Expression
                                                                        =>
                                                                        APPLY_EXPRESSION {

                                                                          function                                                              # Raw_Expression
                                                                            =>
                                                                            APPLY_EXPRESSION {

                                                                              function                                                          # Raw_Expression
                                                                                =>
                                                                                VARIABLE_IN_EXPRESSION
                                                                                  [ symbol::make_package_symbol "super",
                                                                                    symbol::make_value_symbol "pack__object"
                                                                                  ],

                                                                              argument                                                          # Raw_Expression
                                                                                =>
                                                                                TUPLE_EXPRESSION                                                # List( (Symbol, Raw_Expression) )
                                                                                    if (inheritance_hierarchy_depth == 2)
                                                                                        [];                                                     # List( (Symbol, Raw_Expression) )
                                                                                    else
                                                                                        loop (inheritance_hierarchy_depth - 1, [])
                                                                                        where
                                                                                            fun loop (0, results)
                                                                                                    =>
                                                                                                    reverse results;

                                                                                                loop (i, results)
                                                                                                    =>
                                                                                                    loop ( i - 1,
                                                                                                           (VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol (sprintf "fields_%d" (i - 1)) ])
                                                                                                           !
                                                                                                           results
                                                                                                         );
                                                                                            end; 
                                                                                        end;
                                                                                    fi 
                                                                            },

                                                                          argument                                                                      # Raw_Expression
                                                                            =>
                                                                            TUPLE_EXPRESSION [                                                  # List( Raw_Expression )
                                                                              APPLY_EXPRESSION {

                                                                                function                                                                # Raw_Expression
                                                                                  =>
                                                                                  VARIABLE_IN_EXPRESSION
                                                                                    [ symbol::make_value_symbol "OBJECT__STATE" ],

                                                                                argument                                                                # Raw_Expression
                                                                                  =>
                                                                                  RECORD_IN_EXPRESSION [                                                # List( (Symbol, Raw_Expression) )

                                                                                    (                          symbol::make_label_symbol "object__fields",
                                                                                      VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol "object__fields" ]
                                                                                    ),

                                                                                    (                          symbol::make_label_symbol "object__methods",
                                                                                      VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol "object__methods" ]
                                                                                    )
                                                                                  ]
                                                                              },

                                                                              VARIABLE_IN_EXPRESSION
                                                                                [ symbol::make_value_symbol "substate" ]
                                                                            ]
                                                                        }
                                                                  }
                                                                ],

                                                                []                                                      # Type variables
                                                              )
                                                            ]
                                                            @
                                                            (make_method_override_calls
                                                               (  
                                                                 method_overrides
                                                               )
                                                            )),                                                 # SEQUENTIAL_DECLARATIONS


                                                          # Finally our return value from block:
                                                          #     self;
                                                          #     
                                                          expression                                            # Raw_Expression
                                                            =>
                                                            VARIABLE_IN_EXPRESSION
                                                                [ symbol::make_value_symbol "self" ]
                                                        }                                                               # LET_EXPRESSION
                                                  }
                                              ]
                                        }
                                  ],
                                  [                                     # Type variables
                                  ]
                                ); 
                        };                                              # fun make_function_pack_object

                    #
                    fun make_function_make_object ()
                        :   Declaration
                        =
                        {   # Here we make
                            #
                            #     fun make__object fields_tuple
                            #         =
                            #         {   self  =  pack__object  fields_tuple  oop::OOP_NULL;
                            #             self;
                            #         };
                            #
                            FUNCTION_DECLARATIONS 
                                ( [ NAMED_FUNCTION
                                        {
                                          kind    => PLAIN_FUN,
                                          is_lazy => FALSE,

                                          null_or_type => NULL,

                                          pattern_clauses
                                              =>
                                              [ PATTERN_CLAUSE
                                                  { patterns
                                                        =>
                                                        [ { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "make__object" ]
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "fields_tuple" ]
                                                          }
                                                        ],

                                                    result_type 
                                                        =>
                                                        NULL, 

                                                    expression
                                                        =>
                                                        LET_EXPRESSION {

                                                          declaration                                                           # Declaration
                                                            =>
                                                            SEQUENTIAL_DECLARATIONS ([
                                                              VALUE_DECLARATIONS (
                                                                [                                                                       # List( Named_Value )

                                                                  # Synthesize
                                                                  #     self  =  pack__object  fields_tuple  oop::OOP_NULL;
                                                                  #             
                                                                  NAMED_VALUE {

                                                                    is_lazy => FALSE,

                                                                    pattern                                                             # Case_Pattern
                                                                        =>
                                                                        VARIABLE_IN_PATTERN
                                                                          [ symbol::make_value_symbol "self" ],

                                                                    expression                                                  # Raw_Expression
                                                                        =>
                                                                        APPLY_EXPRESSION {

                                                                          function                                                              # Raw_Expression
                                                                            =>
                                                                            APPLY_EXPRESSION {

                                                                              function                                                          # Raw_Expression
                                                                                =>
                                                                                VARIABLE_IN_EXPRESSION
                                                                                  [ symbol::make_value_symbol "pack__object"
                                                                                  ],

                                                                              argument                                                          # Raw_Expression
                                                                                =>
                                                                                VARIABLE_IN_EXPRESSION
                                                                                  [ symbol::make_value_symbol "fields_tuple"
                                                                                  ]
                                                                            },

                                                                          argument                                                              # Raw_Expression
                                                                            =>
                                                                            VARIABLE_IN_EXPRESSION [ symbol::make_package_symbol "oop",
                                                                                                     symbol::make_value_symbol   "OOP_NULL"
                                                                                                   ]
                                                                        }
                                                                  }
                                                                  #     
                                                                  # end of
                                                                  #     self  =  pack__object  fields_tuple  oop::OOP_NULL;
                                                                  #     synthesis.      
                                                                ],

                                                                []                                                                      # List( Typevar_Ref )
                                                              )                                                                 # VALUE_DECLARATIONS

                                                            ]                                                                   # SEQUENTIAL_DECLARATIONS
                                                            ),

                                                          # Finally our return value from block:
                                                          #     self;
                                                          #     
                                                          expression                                                            # Raw_Expression
                                                            =>
                                                            VARIABLE_IN_EXPRESSION
                                                                [ symbol::make_value_symbol "self" ]
                                                        }                                                                               # LET_EXPRESSION
                                                  }
                                              ]
                                        }
                                  ],
                                  [                                                                                                     # Type variables
                                  ]
                                ); 

                        };                                                                                                              # fun make_function_make_object

                    # See comments at   make_make_object_ref ()
                    #
                    fun make_function_make_object_ii ()
                        :   Declaration
                        =
                        {   # Here we make
                            #
                            #     fun make__object arg
                            #         =
                            #         (the (*make__object__ref)) arg;
                            #
                            FUNCTION_DECLARATIONS 
                                ( [ NAMED_FUNCTION
                                        {
                                          kind    => PLAIN_FUN,
                                          is_lazy => FALSE,

                                          null_or_type => NULL,

                                          pattern_clauses
                                              =>
                                              [ PATTERN_CLAUSE
                                                  { patterns
                                                        =>
                                                        [ { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "make__object" ]
                                                          },
                                                          { fixity => NULL,
                                                            source_code_region => (0,0),
                                                            item => VARIABLE_IN_PATTERN [ symbol::make_value_symbol "arg" ]
                                                          }
                                                        ],

                                                    result_type 
                                                        =>
                                                        NULL, 

                                                    expression
                                                        =>
                                                        APPLY_EXPRESSION {

                                                          function                                                                      # Raw_Expression
                                                            =>
                                                            APPLY_EXPRESSION {

                                                              function                                                          # Raw_Expression
                                                                =>
                                                                VARIABLE_IN_EXPRESSION
                                                                  [ symbol::make_value_symbol "the" ],

                                                              argument                                                          # Raw_Expression
                                                                =>
                                                                APPLY_EXPRESSION {

                                                                  function                                                              # Raw_Expression
                                                                    =>
                                                                    VARIABLE_IN_EXPRESSION
                                                                      [ symbol::make_value_symbol "*_" ],

                                                                  argument                                                              # Raw_Expression
                                                                    =>
                                                                    VARIABLE_IN_EXPRESSION
                                                                      [ symbol::make_value_symbol "make__object__ref" ]
                                                                }
                                                            },

                                                          argument                                                                      # Raw_Expression
                                                            =>
                                                            VARIABLE_IN_EXPRESSION [ symbol::make_value_symbol "arg" ]
                                                        }
                                                  }
                                                ]
                                        }
                                  ],

                                  []
                                );
                        };

                    # See comments at   make_make_object_ref ()
                    #
                    fun make_make_object_backpatch ()
                        :   Declaration
                        =
                        {   # Here we make
                            #
                            #     my _
                            #         =
                            #         make__object__ref := THE make__object;
                            #
                            VALUE_DECLARATIONS 
                                ( [ NAMED_VALUE
                                      {
                                        pattern
                                            =>
                                            WILDCARD_PATTERN,

                                        expression
                                            =>
                                            APPLY_EXPRESSION
                                              {
                                                function
                                                    =>
                                                    VARIABLE_IN_EXPRESSION
                                                        [ symbol::make_value_symbol ":=" ],

                                                argument
                                                    =>
                                                    TUPLE_EXPRESSION
                                                      [
                                                        VARIABLE_IN_EXPRESSION
                                                            [ symbol::make_value_symbol "make__object__ref" ],

                                                            APPLY_EXPRESSION
                                                              {
                                                                function
                                                                    =>
                                                                    VARIABLE_IN_EXPRESSION
                                                                        [ symbol::make_value_symbol "THE" ],

                                                                argument
                                                                    =>
                                                                    VARIABLE_IN_EXPRESSION
                                                                        [ symbol::make_value_symbol "make__object" ]
                                                              }
                                                      ]
                                              },


                                        is_lazy => FALSE
                                      }
                                  ],

                                  []
                                );
                        };                                                              # fun make_make_object_backpatch

                    stipulate

                        # A little fun to prepend 'n' "super"
                        # components to a given list, yielding
                        # a list like
                        #     [ symbol::make_package_symbol "super",
                        #       symbol::make_package_symbol "super",
                        #       symbol::make_type_symbol "Initializer__Fields"
                        #     ]
                        #
                        fun prepend_n_supers (0, list) => list;
                            prepend_n_supers (i, list) => prepend_n_supers (i - 1, (symbol::make_package_symbol "super") ! list);
                        end;

                        # A little fun to build raw syntax for
                        #     super::super::Initializer__Fields(X)
                        # for 'n' "supers":
                        #
                        fun build_super_super_fields_x n
                            =
                            TYP_TYPE
                              ( prepend_n_supers (n, [ symbol::make_type_symbol "Initializer__Fields" ]),
                                [ TYPE_VARIABLE_TYPE typevar_x ]                                                # anytype'
                              );

                        # A little fun to build up the
                        #     (Initializer__Fields(X), super::Initializer__Fields(X), super::super::Initializer__Fields(X), Void)
                        # tuple list by prepending ...Object__Fields(X) components:
                        #
                        fun prepend_fields_to_tuple_list (1, list_so_far)
                                =>
                                list_so_far;

                            prepend_fields_to_tuple_list (chain_length, list_so_far)
                                =>
                                prepend_fields_to_tuple_list
                                  ( chain_length - 1,
                                    (build_super_super_fields_x (chain_length - 2)) ! list_so_far
                                  );
                        end;

                        # A little fun to build raw syntax for a complete tuple
                        #     (Initializer__Fields(X), super::Initializer__Fields(X), super::super::Initializer__Fields(X), ... Void)
                        # for a given chain length:
                        #
                        fun build_tuple  chain_length
                            =
                            TUPLE_TYPE (
                                prepend_fields_to_tuple_list
                                  ( chain_length,
                                    [ TYP_TYPE
                                        ([ symbol::make_type_symbol "Void" ], [])
                                    ]
                                  )
                            );

                    herein

                        #
                        fun declare_function_pack_object_in_api ()
                            :   Api_Element
                            =
                            {   # Here we make a declaration depending
                                # on our superclass chain length:
                                #
                                #    chain length 2:   pack__object: (Initializer__Fields(X),                                                                      Void) -> X -> Self(X);
                                #    chain length 3:   pack__object: (Initializer__Fields(X), super::Initializer__Fields(X),                                       Void) -> X -> Self(X);
                                #    chain length 4:   pack__object: (Initializer__Fields(X), super::Initializer__Fields(X), super::super::Initializer__Fields(X), Void) -> X -> Self(X);
                                #
                                # and so forth.

                                VALUES_IN_API
                                  [
                                    ( symbol::make_value_symbol "pack__object",
                                      TYP_TYPE
                                        ( [ symbol::make_type_symbol "->" ],
                                          [ build_tuple  inheritance_hierarchy_depth,           # The "(Object__Fields(X), Void)" tuple or similar.
                                            TYP_TYPE
                                              ( [ symbol::make_type_symbol "->" ],
                                                [ TYPE_VARIABLE_TYPE typevar_x,
                                                  TYP_TYPE
                                                    ( [ symbol::make_type_symbol "Self" ],
                                                      [ TYPE_VARIABLE_TYPE typevar_x ]
                                                    )
                                                ]
                                              )
                                          ]
                                        )
                                    )
                                  ];
                            };

                        #
                        fun declare_function_make_object_in_api ()
                            :   Api_Element
                            =
                            {   # Here we make a declaration depending
                                # on our superclass chain length:
                                #
                                #    chain length 2:   make__object: (Object__Fields(X),                                                            Void) -> Myself;
                                #    chain length 3:   make__object: (Object__Fields(X), super::Object__Fields(X),                                  Void) -> Myself;
                                #    chain length 4:   make__object: (Object__Fields(X), super::Object__Fields(X), super::super::Object__Fields(X), Void) -> Myself;
                                #
                                # and so forth.

                                VALUES_IN_API
                                  [
                                    ( symbol::make_value_symbol "make__object",
                                      TYP_TYPE
                                        ( [ symbol::make_type_symbol "->" ],
                                          [ build_tuple  inheritance_hierarchy_depth,           # The "(Object__Fields(X), Void)" tuple or similar.
                                            TYP_TYPE
                                              ( [ symbol::make_type_symbol "Myself" ],
                                                []
                                              )
                                          ]
                                        )
                                    )
                                  ];
                            };

                    #
                    fun make_make_object_ref ()
                        :   Declaration
                        =
                        {   # There's a problem in that make__object has
                            # to be defined after the user-supplied method
                            # functions because it needs to have them in scope,
                            # but we'd like to call make__object from within
                            # user-supplied methods. 
                            #
                            # We can get around that by putting a ref
                            # upfront and a function which calls it, and
                            # then later backpatching the reference to
                            # point to make__object:
                            #
                            #     make__object__ref = (REF NULL): Ref (Null_Or( <type of make__object> ));
                            #     fun make__object arg = (the (*make__object__ref)) arg;
                            #
                            #     <user-supplied-methods> 
                            #     fun make__object ...
                            #     make__object__ref := THE make__object;
                            #
                            VALUE_DECLARATIONS (
                              [
                                NAMED_VALUE
                                  {
                                    pattern
                                        => 
                                        VARIABLE_IN_PATTERN
                                          [ symbol::make_value_symbol "make__object__ref" ],

                                    expression                                                  # Raw_Expression
                                        =>
                                        TYPE_CONSTRAINT_EXPRESSION
                                          {
                                            expression
                                                =>
                                                APPLY_EXPRESSION
                                                  {
                                                    function
                                                        =>
                                                        VARIABLE_IN_EXPRESSION
                                                            [ symbol::make_value_symbol "REF" ],

                                                    argument
                                                        =>
                                                        VARIABLE_IN_EXPRESSION
                                                            [ symbol::make_value_symbol "NULL" ]
                                                  },

                                            constraint
                                                =>
                                                TYP_TYPE
                                                  ( [ symbol::make_type_symbol "Ref" ],
                                                    [
                                                      TYP_TYPE
                                                        ( [ symbol::make_type_symbol "Null_Or" ],
                                                          [     
                                                            TYP_TYPE
                                                              ( [ symbol::make_type_symbol "->" ],
                                                                [ build_tuple  inheritance_hierarchy_depth,             # The "(Object__Fields(X), Void)" tuple or similar.
                                                                  TYP_TYPE
                                                                    ( [ symbol::make_type_symbol "Myself" ],
                                                                      []
                                                                    )
                                                                ]
                                                              )
                                                          ]
                                                        )
                                                    ]
                                                  )

                                          },

                                    is_lazy => FALSE
                                  }
                              ],

                              []
                            );
                        };
                    end;                                # stipulate

                    #
                    fun declare_function_unpack_object_in_api ()
                        :   Api_Element
                        =
                        {   # Here we make a declaration
                            #
                            #               unpack__object:      Self(X) -> (X -> Self(X), X);
                            #
                            VALUES_IN_API
                              [
                                ( symbol::make_value_symbol "unpack__object",
                                  TYP_TYPE
                                    ( [ symbol::make_type_symbol "->" ],
                                      [ TYP_TYPE
                                          ( [ symbol::make_type_symbol "Self" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x ]
                                          ),
                                        TUPLE_TYPE
                                          [
                                            TYP_TYPE
                                              ( [ symbol::make_type_symbol "->" ],
                                                [ TYPE_VARIABLE_TYPE typevar_x,
                                                  TYP_TYPE
                                                    ( [ symbol::make_type_symbol "Self" ],
                                                      [ TYPE_VARIABLE_TYPE typevar_x ]
                                                    )
                                                ]
                                              ),
                                            TYPE_VARIABLE_TYPE  typevar_x
                                          ]
                                      ]
                                    )
                                )
                              ];
                        };

                    #
                    fun declare_function_get_substate_in_api ()
                        :   Api_Element
                        =
                        {   # Here we make a declaration
                            #
                            #               get__substate:      Self(X) -> X;
                            #
                            VALUES_IN_API
                              [
                                ( symbol::make_value_symbol "get__substate",
                                  TYP_TYPE
                                    ( [ symbol::make_type_symbol "->" ],
                                      [ TYP_TYPE
                                          ( [ symbol::make_type_symbol "Self" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x ]
                                          ),
                                        TYPE_VARIABLE_TYPE typevar_x
                                      ]
                                    )
                                )
                              ];
                        };

                    #
                    fun declare_function_get_fields_in_api ()
                        :   Api_Element
                        =
                        {   # Here we make a declaration
                            #
                            #               get__fields:      Self(X) -> Object__Fields(X);
                            #
                            VALUES_IN_API
                              [
                                ( symbol::make_value_symbol "get__fields",
                                  TYP_TYPE
                                    ( [ symbol::make_type_symbol "->" ],
                                      [ TYP_TYPE
                                          ( [ symbol::make_type_symbol "Self" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x ]
                                          ),
                                        TYP_TYPE
                                          ( [ symbol::make_type_symbol "Object__Fields" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x  ]                           # anytype'
                                          )
                                      ]
                                    )
                                )
                              ];
                        };

                    #
                    fun declare_function_get_methods_in_api ()
                        :   Api_Element
                        =
                        {   # Here we make a declaration
                            #
                            #               get__methods:      Self(X) -> Object__Methods(X);
                            #
                            VALUES_IN_API
                              [
                                ( symbol::make_value_symbol "get__methods",
                                  TYP_TYPE
                                    ( [ symbol::make_type_symbol "->" ],
                                      [ TYP_TYPE
                                          ( [ symbol::make_type_symbol "Self" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x ]
                                          ),
                                        TYP_TYPE
                                          ( [ symbol::make_type_symbol "Object__Methods" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x ]                            # anytype'
                                          )
                                      ]
                                    )
                                )
                              ];
                        };

                    #
                    fun declare_function_make_object_fields_in_api ()
                        :   Api_Element
                        =
                        {   # Here we make a declaration
                            #
                            #               make_object__fields:      Initializer__Fields(X) -> Object__Fields(X);
                            #
                            VALUES_IN_API
                              [
                                ( symbol::make_value_symbol "make_object__fields",
                                  TYP_TYPE
                                    ( [ symbol::make_type_symbol "->" ],
                                      [ TYP_TYPE
                                          ( [ symbol::make_type_symbol "Initializer__Fields" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x ]
                                          ),
                                        TYP_TYPE
                                          ( [ symbol::make_type_symbol "Object__Fields" ],
                                            [ TYPE_VARIABLE_TYPE typevar_x  ]                           # anytype'
                                          )
                                      ]
                                    )
                                )
                              ];
                        };

                    #
                    fun make_big_type_declaration_for_package {
                            fields:   List( Named_Field            ),           # List of fields found in input class body.
                            methods:  List( Named_Function )            # List of methods found in input class body.
                        }
                        :   Declaration
                        =
                        {   # Here we make the big type declaration
                            # cluster for the class package proper.
                            # In source form e.g., src/app/tut/oop-crib/oop-crib.pkg
                            #
                            # this looks like
                            # 
                            #    Object__State(X)
                            #        =
                            #        OBJECT__STATE
                            #          { object__methods: Object__Methods(X),
                            #            object__fields:  Object__Fields(X)
                            #          }
                            #    withtype
                            #        Full__State(X) = (Object__State(X), X)                     # Our state record plus those of our subclass chain, if any.
                            #    also
                            #        Self(X) = super::Self( Full__State(X) )
                            #    also
                            #        Object__Methods(X)
                            #            =
                            #            ( Self(X) -> String,   # get_string
                            #          Self(X) -> Int       # get_int
                            #        )
                            #    also
                            #    Object__Fields(X)  = ( String,  # self_string.
                            #                           Int      # self_int.
                            #                         )
                            #    ;
                            #
                            # where the specific fields and methods will of course vary.
                            #
                            # In raw syntax form this looks like:
                            #                                                                           # hash_string           is from   src/lib/src/hash-string.pkg
                            #
                            #        NAMED_ENUM Object__State
                            #            TYPE VARIABLE $X
                            #            =
                            #            VALCONS OBJECT__STATE
                            #                RECORD_TYPE
                            #                    {
                            #                      object__methods:  TYP_TYPE TYPE_VARIABLE_TYPE TYPE_VARIABLE $X Object__Methods, 
                            #                  object__fields:   TYP_TYPE TYPE_VARIABLE_TYPE TYPE_VARIABLE $X Object__Fields
                            #                    };
                            #        withtype
                            #
                            #            NAMED_TYPE Full__State
                            #                TYPE VARIABLE $X
                            #                =
                            #                TUPLE_TYPE TYP_TYPE VARIABLE TYPE TYPE VARIABLE $X Object__State, 
                            #                                VARIABLE TYPE TYPE VARIABLE $X
                            #
                            #            NAMED_TYPE Self
                            #                =
                            #                TYP_TYPE TYP_TYPE VARIABLE TYPE TYPE VARIABLE $X Full__State
                            #                                            super::Self
                            #                TYPE VARIABLE $X
                            #
                            #            NAMED_TYPE Object__Methods
                            #                    TYPE VARIABLE $X
                            #                    =
                            #                TUPLE_TYPE
                            #                      (
                            #                        TYP_TYPE TYP_TYPE VARIABLE TYPE TYPE VARIABLE $X Self -> TYP_TYPE String,    # get_string
                            #                    TYP_TYPE TYP_TYPE VARIABLE TYPE TYPE VARIABLE $X Self -> TYP_TYPE Int        # get_int
                            #                      )
                            #
                            #            NAMED_TYPE Object__Fields
                            #                TYPE VARIABLE $X
                            #                =
                            #                TUPLE_TYPE
                            #                    [ TYP_TYPE String, # self_string.
                            #                  TYP_TYPE Int     # self_int.
                            #                    }
                            #
                            # which can be generated by code looking like
                            #
                            ENUM_DECLARATIONS
                              {
                                datatyps                                                                        # List( Named_Datatype )
                                    =>
                                    [  NAMED_ENUM
                                           {
                                             typ                                                                # Symbol
                                                 =>
                                                 symbol::make_type_symbol "Object__State",                                      # Type name for "Object__State(X) = ..."

                                             type_variables                                                                     # List( Typevar_Ref ),
                                                 =>
                                                 [ typevar_x ],                                                         # Type variable X for "Object__State(X) = ..."

                                             is_lazy                                                                    # Bool
                                                 =>
                                                 FALSE,

                                             right_hand_side                                                            # Named_Datatype_Right_Hand_Side,
                                                 =>
                                                 VALCONS [
                                                   ( symbol::make_value_symbol "OBJECT__STATE",                         # Constructor name OBJECT__STATE
                                                     THE (
                                                         RECORD_TYPE [
                                                           ( symbol::make_label_symbol "object__fields",                                # Record field name "object__fields".
                                                             TYP_TYPE
                                                               ( [ symbol::make_type_symbol "Object__Fields" ],
                                                                 [ TYPE_VARIABLE_TYPE typevar_x  ]                              # anytype'
                                                               )
                                                           ),
                                                           ( symbol::make_label_symbol "object__methods",                               # Record field name "object__methods".
                                                             TYP_TYPE
                                                               ( [ symbol::make_type_symbol "Object__Methods" ],
                                                                 [ TYPE_VARIABLE_TYPE typevar_x ]                               # anytype'
                                                               )
                                                           )
                                                        ]
                                                     )
                                                   )
                                                 ]
                                           }
                                    ],

                                with_typs                                                                       # List( Named_Type )
                                    =>
                                    [
                                      # Full__State(X) = (Object__State(X), X):
                                      # 
                                      NAMED_TYPE
                                       {
                                          typ                                                                   # Symbol
                                              =>
                                              symbol::make_type_symbol "Full__State",

                                          type_variables                                                                        # List( Typevar_Ref )
                                              =>
                                              [ typevar_x ],

                                          definition                                                                    # Any_Type
                                              =>
                                              TUPLE_TYPE [
                                                TYP_TYPE (
                                                  [ symbol::make_type_symbol "Object__State" ],
                                                  [ TYPE_VARIABLE_TYPE typevar_x ]                                              # anytype'
                                                ),
                                                TYPE_VARIABLE_TYPE typevar_x
                                              ] 
                                        },

                                      # Self(X) = super::Self( Full__State(X) ):
                                      # 
                                      NAMED_TYPE
                                        {
                                          typ                                                                   # Symbol
                                              =>
                                              symbol::make_type_symbol "Self",

                                          type_variables                                                                        # List( Typevar_Ref )
                                              =>
                                              [ typevar_x ],

                                          definition                                                                    # Any_Type
                                              =>
                                              TYP_TYPE
                                                  (  [ symbol::make_package_symbol "super",
                                                       symbol::make_type_symbol "Self"
                                                     ],
                                                     [ TYP_TYPE
                                                           ( [ symbol::make_type_symbol "Full__State"
                                                             ],
                                                             [ TYPE_VARIABLE_TYPE typevar_x ]                           # anytype'
                                                           )
                                                     ] 
                                                  )
                                        },

                                      # Myself = Self( oop::Oop_Null ):
                                      # 
                                      NAMED_TYPE
                                          {
                                            typ                         # Symbol
                                                =>
                                                symbol::make_type_symbol "Myself",

                                            type_variables                                      # List( Typevar_Ref )
                                                =>
                                                [],

                                            definition                                  # Any_Type
                                                =>
                                                TYP_TYPE
                                                    (  [ symbol::make_type_symbol "Self" ],
                                                       [ TYP_TYPE
                                                             ( [ symbol::make_package_symbol "oop",
                                                                 symbol::make_type_symbol "Oop_Null"
                                                               ],
                                                               []
                                                             )
                                                       ] 
                                                    ) 
                                          },

                                      NAMED_TYPE
                                        {
                                          typ                                                                   # Symbol
                                              =>
                                              symbol::make_type_symbol "Object__Methods",

                                          type_variables                                                                        # List( Typevar_Ref )
                                              =>
                                              [ typevar_x ],

                                          definition                                                                    # Any_Type
                                              =>
                                              make_methods_type_declaration  methods
                                        },

                                      NAMED_TYPE
                                        {
                                          typ                                                                   # Symbol
                                              =>
                                              symbol::make_type_symbol "Object__Fields",

                                          type_variables                                                                        # List( Typevar_Ref )
                                              =>
                                              [ typevar_x ],

                                          definition                                                                    # Any_Type
                                              =>
                                              make_object_fields_type_declaration  fields
                                        },

                                      NAMED_TYPE
                                        {
                                          typ                                                                   # Symbol
                                              =>
                                              symbol::make_type_symbol "Initializer__Fields",

                                          type_variables                                                                        # List( Typevar_Ref )
                                              =>
                                              [ typevar_x ],

                                          definition                                                                    # Any_Type
                                              =>
                                              make_init_fields_type_declaration  initializer_fields
                                        }
                                    ]
                              };
                        };


                    #
                    fun make_big_type_declaration_for_api {
                            fields:   List( Named_Field    ),           # List of fields found in input class body.
                            methods:  List( Named_Function )            # List of method definitions found in input class body.
                        }
                        :   List( Api_Element )
                        =
                        {   # Here we make the big type declaration
                            # cluster for the class api.  In source form
                            # e.g., src/app/tut/oop-crib/oop-crib.pkg
                            #
                            # this looks like
                            # 
                            #   Full__State(X);
                            #   Self(X)  = super::Self( Full__State(X) );
                            #   Myself   = Self( oop::Oop_Null );                       # Used only for the return type of 'make__object', everywhere else is Self(X).
                            #
                            #   Object__Fields(X)  = ( String,  # self_string.
                            #                      Int      # self_int.
                            #                    );
                            #
                            #   Initializer__Fields(X) = { self_string: String,
                            #                          self_int:    Int
                            #                        };
                            #
                            #   Object__Methods(X) = ( Self(X) -> String,   # get_string
                            #                      Self(X) -> Int       # get_int
                            #                    };
                            #
                            #   get_string: Self(X) -> String;
                            #   get_int:    Self(X) -> Int;
                            #
                            # where the specific fields and methods will of course vary.
                            #
                            api_elements
                                =
                                [
                                  # Full__State(X);
                                  #
                                  TYPS_IN_API
                                    (
                                      [ ( symbol::make_type_symbol "Full__State",
                                          [ typevar_x ],
                                          NULL
                                        )
                                      ],
                                      FALSE             # Not an equality type
                                    ),

                                  # Self(X)  = super::Self( Full__State(X) );
                                  #
                                  TYPS_IN_API
                                    (
                                      [ ( symbol::make_type_symbol "Self",
                                          [ typevar_x ],
                                          THE
                                            ( TYP_TYPE
                                                ( [ symbol::make_package_symbol "super",
                                                    symbol::make_type_symbol    "Self"
                                                  ],
                                                  [ TYP_TYPE
                                                      ( [ symbol::make_type_symbol"Full__State" ],
                                                        [ TYPE_VARIABLE_TYPE typevar_x ]
                                                      )
                                                  ]
                                                )
                                             )
                                        )
                                      ],
                                      FALSE             # Not an equality type
                                    ),

                                  # Myself = Self( oop::Oop_Null );
                                  #
                                  TYPS_IN_API
                                    (
                                      [ ( symbol::make_type_symbol "Myself",
                                          [],
                                          THE
                                            ( TYP_TYPE
                                                ( [ symbol::make_type_symbol "Self" ],
                                                  [ TYP_TYPE
                                                      ( [ symbol::make_package_symbol "oop",
                                                          symbol::make_type_symbol    "Oop_Null"
                                                        ],
                                                        []
                                                      )
                                                  ]
                                                )
                                            )
                                        )
                                      ],
                                      FALSE             # Not an equality type
                                    ),

                                  # Object__Fields(X) = ( String, # self_string.
                                  #                           Int     # self_int.
                                  #                         );
                                  #
                                  TYPS_IN_API
                                    (
                                      [ ( symbol::make_type_symbol "Object__Fields",
                                          [ typevar_x ],
                                          THE
                                            (make_object_fields_type_declaration  fields)
                                        )
                                      ],
                                      FALSE             # Not an equality type
                                    ),

                                  TYPS_IN_API
                                    (
                                      [ ( symbol::make_type_symbol "Initializer__Fields",
                                          [ typevar_x ],
                                          THE
                                            (make_init_fields_type_declaration  initializer_fields)
                                        )
                                      ],
                                      FALSE             # Not an equality type
                                    ),

                                  #   Object__Methods(X)
                                  #       =
                                  #       ( Self(X) -> String,   # get_string
                                  #             Self(X) -> Int       # get_int
                                  #           );
                                  #
                                  TYPS_IN_API
                                    (
                                      [ ( symbol::make_type_symbol "Object__Methods",
                                          [ typevar_x ],
                                          THE
                                            (make_methods_type_declaration  methods)
                                        )
                                      ],
                                      FALSE             # Not an equality type
                                    )
                                ]
                                @
                                # Here we synthesize the API declarations       
                                #       
                                #   get_string: Self(X) -> String;
                                #   get_int:    Self(X) -> Int;
                                #       
                                make_methods_type_declarations  methods;

                            api_elements;
                        };


                    # We now have in hand all needed raw-syntax
                    # synthesis support code.  In the following
                    # function we pull it all together to do
                    # the actual class-definition rewrite into
                    # a vanilla Mythryl package definition in
                    # raw syntax form:
                    #
                    fun make_new_class_declaration (
                            user_code:  List( Declaration )                                                                     # The original list of top-level statements in the class body.
                        )
                        =
                        {
                            # We start by duplicating "class super = ...;" at the
                            # start of what will be the added code at start of
                            # class body.  This ensures that 'super' will be in
                            # scope for all the following code we generate.
                            #
                            # NB: If the user did not provide a 'class super = ...'
                            #     declaration, this will be the only one present,
                            #     our synthesized "class super = object;":
                            #
                            new_body
                                =
                                [ PACKAGE_DECLARATIONS [ superclass ] ];


                            # Construct the raw syntax tree for our
                            # synthesized code implementing all the
                            # OOP stuff for the package.
                            #
                            # This goes in a subpackage which gets strong-sealed
                            # with a matching API to make Full__State(X)
                            # is abstract (which is essential for
                            # proper method invocation in the presence of
                            # subclasses -- see Bernard Berthomieu's paper)
                            # and then 'included' back into the code.
                            #
                            synthesized_code
                                =
                                SEQUENTIAL_DECLARATIONS [
                                  PACKAGE_DECLARATIONS
                                    [
                                      NAMED_PACKAGE
                                        {
                                          name_symbol
                                              =>
                                              symbol::make_package_symbol "oop__internal",

                                          constraint
                                              =>
                                              STRONG_PACKAGE_CAST (
                                                  API_DEFINITION (
                                                      (make_big_type_declaration_for_api { fields, methods => message_definitions })
                                                      @
                                                      [
                                                        declare_function_pack_object_in_api        (),
                                                        declare_function_make_object_in_api        (),
                                                        declare_function_unpack_object_in_api      (),
                                                        declare_function_get_substate_in_api       (),
                                                        declare_function_get_fields_in_api         (),
                                                        declare_function_get_methods_in_api        (),
                                                        declare_function_make_object_fields_in_api ()
                                                      ]
                                                      @
                                                      declare_method_override_functions (message_definitions, [])
                                                  )
                                              ),

                                          definition
                                              =>
                                              PACKAGE_DEFINITION (
                                                 SEQUENTIAL_DECLARATIONS
                                                   [ make_big_type_declaration_for_package { fields, methods => message_definitions },

                                                     make_function_get_fields  (),
                                                     make_function_get_methods (),

                                                     make_make_object_ref (),
                                                     make_function_make_object_ii (),

                                                     wrap_method_and_message_functions  methods_and_messages,
                                                     make_methods_record                message_definitions,
                                                     make_method_dispatch_functions     message_definitions,

                                                     make_function_make_object_fields (),
                                                     make_function_pack_object (),
                                                     make_function_make_object (),

                                                     make_function_unpack_object (),
                                                     make_function_get_substate (),

                                                     make_method_override_functions  message_definitions,
                                                     make_make_object_backpatch ()
                                                   ]
                                              ),

                                          kind => PLAIN_PACKAGE
                                        }
                                    ],

                                  INCLUDE_DECLARATIONS [ [ symbol::make_package_symbol "oop__internal" ] ]              # List of paths, each path a list of symbols.
                                ];


                            user_code
                                =
                                case (oop_rewrite_declaration
                                        { original_declaration => SEQUENTIAL_DECLARATIONS user_code,
                                          synthesized_code,
                                          field_to_offset
                                        }
                                     )

                                    SEQUENTIAL_DECLARATIONS user_code
                                        =>
                                        user_code;

                                    _   => raise exception FAIL "expand-oop-syntax.pkg: make_new_class_declaration: Internal compiler error.";
                                esac;

                            # Drop in the user-supplied package body.
                            # This contains the user method functions,
                            # now mutated to be vanilla user functions:
                            #
                            new_body @= user_code;

                            if *debugging

                                prettyprint_raw_declaration
                                  (
                                    "expand-oop-syntax.pkg:  make_new_class_declaration:  Final rewritten class: ",
                                    SEQUENTIAL_DECLARATIONS  new_body,
                                    symbolmapstack
                                  );

                                unparse_raw_declaration
                                  (
                                    "expand-oop-syntax.pkg:  make_new_class_declaration:  Final rewritten class: ",
                                    SEQUENTIAL_DECLARATIONS  new_body,
                                    symbolmapstack
                                  );
                            fi;

                            SEQUENTIAL_DECLARATIONS  new_body;

                        };                              # fun make_new_class_declaration


                    # Take apart the given raw syntax tree
                    # to find the parts we need:
                    #
                    case declaration
                        #
                        SEQUENTIAL_DECLARATIONS list
                            =>
                            PACKAGE_DEFINITION (make_new_class_declaration list);

                        ( VALUE_DECLARATIONS _
                        | FIELD_DECLARATIONS _
                        | EXCEPTION_DECLARATIONS _
                        | TYPE_DECLARATIONS        _
                        | GENERIC_DECLARATIONS     _
                        | API_DECLARATIONS         _
                        | GENERIC_API_DECLARATIONS _
                        | LOCAL_DECLARATIONS      _
                        | INCLUDE_DECLARATIONS  _
                        | OVERLOADED_VARIABLE_DECLARATION _
                        | FIXITY_DECLARATIONS _
                        | FUNCTION_DECLARATIONS _
                        | NADA_FUNCTION_DECLARATIONS _
                        | RECURSIVE_VALUE_DECLARATIONS _
                        | ENUM_DECLARATIONS _
                        | ABSTRACT_TYPE_DECLARATIONS _
                        | SOURCE_CODE_REGION_FOR_DECLARATION _
                        | PACKAGE_DECLARATIONS _
                        | PRE_COMPILE_CODE _
                        )   =>
                           {   # XXX SUCKO FIXME put a proper compiler error message here.
                               printf "src/lib/compiler/front/typer/main/expand-oop-syntax.pkg: Internal compiler error, unsupported oop raw syntax tree, %d messages, %d methods and %d fields ignored\n"
                                      message_count  method_count  field_count;
                               PACKAGE_DEFINITION declaration;
                           };
                    esac;  
                fi; 
            };                                                          # fun expand_oop_syntax_in_declaration


        #
        fun expand_oop_syntax_in_package_expression
            (
              package_name:         symbol::Symbol,
              package_expression:   raw_syntax::Package_Expression,
              symbolmapstack:         symbolmapstack::Symbolmapstack,
              source_code_region:   line_number_db::Source_Code_Region,
              per_compile_info:     typer_junk::Per_Compile_Info
            )
            : raw_syntax::Package_Expression
            =
            case   package_expression

                PACKAGE_BY_NAME          _ =>  package_expression;
                CALL_OF_GENERIC          _ =>  package_expression;
                INTERNAL_CALL_OF_GENERIC _ =>  package_expression;
                LET_IN_PACKAGE           _ =>  package_expression;
                PACKAGE_CAST             _ =>  package_expression;

                SOURCE_CODE_REGION_FOR_PACKAGE
                    (package_expression, source_code_region')
                    =>
                    expand_oop_syntax_in_package_expression
                      (
                        package_name,
                        package_expression,
                        symbolmapstack,
                        source_code_region',
                        per_compile_info
                      );

                PACKAGE_DEFINITION  declaration
                    =>
                    expand_oop_syntax_in_declaration
                      (
                        package_name,
                        declaration,
                        symbolmapstack,
                        source_code_region,
                        per_compile_info
                      );                
            esac;
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext