Wednesday, February 18, 2015

Table Class Hierarchy – Operand Entries

The last several commits involved the virtual encode, operand text, and remove table functions.  These virtual functions will only be used by codes that contain operands (a second program word with an index of a dictionary entry).  The table class hierarchy was implemented for these table entries.  The resulting implementation for the operand table sub-class hierarchy is shown in this diagram:
Table
  └── Operand
          ├── Rem [remCommand, remOperator]
          ├── Const [constDbl]
          │    ├── CosntInt [constInt]
              └── CosntStr [constStr]
          └── Var [var]
                ├── VarInt [varInt]
                ├── VarStr [varStr]
                └── VarRef [varRef]
                       ├── VarRefInt [varRefInt]
                       └── VarRefStr [varRefStr]

The names in bold are the derived table entry classes used to instantiate the table entries (names shown in brackets).  The italic-bold names are base classes and are not meant to be used to create instances.  Eventually these will contain pure virtual functions preventing instantiation.  Note that some of the derived table entry classes are also used as base classes for related derived table entry classes (Const, Var, and VarRef).

A separate derived table class is needed for each table entry because each will implement a unique run function for execution of that code at run-time.  Unique classes are not necessary for the REM command and REM (') operator because their run functions will do that same thing at execution (which is nothing).

Since the virtual
encode, operand text, and remove table functions are the same for all of these classes, they are implemented in the Operand sub-class and will be inherited by derived entry classes.  The operand recreate function is also common to all of these classes and its contents were moved to the virtual recreate function of Operand class.

For the primary derived table entry classes (Rem, Const, Var, and VarRef), only the constructor is different containing arguments necessary for the associated table entry members.  The table entry instantiations then contain initialization value unique to the entry.  The arguments of each constructor were pushed up the hierarchy for those values that are common.

For the constant sub-classes, each share the same constructor since each needs the same entry member values.  Normally a derived class does not inherit the constructors from its base class, but C++11 allows constructors to be inherited with the using syntax (for example, the ConstInt class contains a using Const::Const; statement to inherit the constructor from the Const class).  This feature should only be used when the derived class contains no additional data members that would not get initialized (which is the case here).

The REM recreate function contents were moved to the Rem class virtual recreate function.  The constant string recreate function contents were moved to the ConstStr class virtual recreate function.  This function was refactored a bit by separating out the replace double quotes with two function (mainly to simplify the recreate function and remove the necessity of a comment that might become stale).

The variable classes were similarly implemented and only the Var and VarRef classes contain constructors with the others inheriting theirs.  TODO comments were added to where the virtual run functions will be put when implemented for all of the derived table entry sub-classes.

Some of these table entries require alternate entries, so a mechanism was implemented to assign these alternates as they can't be automatic like with the operator table entries.  The base Operand constructor contains a reference to an Alternate Item structure instance.  This new simple structure contains a pointer to a primary table entry and an operand index that the entry should be assigned to.

A new table class append alternate function was implemented taking a reference to a Alternate Item structure and is called from the Operand class constructor.  This append alternate function appends the entry pointer (this) to the alternate entry vector of the primary entry for the operand index if the primary entry pointer is not a null pointer (the default if entry is not an alternate).  This functionality will probably be moved up into the base Table class since it will be needed for other table entries classes.

These classes and their instances are defined in the operand.cpp source (previously named basic.cpp) since it contains only sub-classes and entries related to operand table entries.  The sub-classes and instances do not need to be known outside of this source file (no header file is needed).  This will improve compile time since other source files only need to include the main table header file.  The pointers to the instances are added to the static table members via the base Table class constructor that gets called by each entry sub-class constructor.

With these operand table entries are now created in the new table model, their corresponding entries in the old table entries array were removed along with their code index enumerators.  The alternate initializers for these in the temporary alternate info initializer were also removed.

[branch table commit d4aec5bf13]