code_genome.html
来自「有趣的模拟进化的程序 由国外一生物学家开发 十分有趣」· HTML 代码 · 共 375 行 · 第 1/2 页
HTML
375 行
class <font color="#880000">cHardwareBase</font>; typedef void (<font color="#880000">cHardwareBase</font>::*<font color="#880000">tHardwareMethod</font>)();</pre><p>The first command basically states that there will be a class called<font color="#880000">cHardwareBase</font> that will be fully defined atsome point in the future. We need to refer to the class here, but notdirectly interact with any of its methods or variables, so it is sufficientto just tell the compiler that it is a class. This form of statement iscalled a <b>predeclaration</b>.<p>The second line is a <tt>typedef</tt> statement, which defines a new data \type. A typedef looks just like a variable declaration, but thekeyword <tt>typedef</tt> indicates that the "variable" thatwould have been defined is instead a new "type". For example, the command"<tt>typedef unsigned char UCHAR</tt>" creates a new type called "UCHAR" thatis just an unsigned char. In the case above, we are creating a new typecalled <font color="#880000">tHardwareMethod</font>, which is a pointer toa method in the class cHardwareBase. Basically it will point to a locationin memory that contains a method in the yet-to-be-defined class. This isa tricky concept -- but it is the easiest way to point to a variable methodthat we don't know about until run time (when we load the instruction setfile in).<p>The cInstLib class is long, so I'm going to split the code presentation intotwo halves, with explanation in between. Here is the first part:<pre> class <font color="#880000">cInstLib</font> { private: // This class gives full info about a single instruction in the library. class <font color="#880000">cInstEntry</font> { public: <font color="#880000">cString</font> <font color="#000088">name</font>; <font color="#886600">// Name of this instruction.</font> <font color="#880000">tHardwareMethod</font> <font color="#000088">function</font>; <font color="#886600">// Pointer to hardware method.</font> <font color="#886600">// Some additional details to be used in the future...</font> <font color="#880000">int</font> <font color="#000088">redundancy</font>; <font color="#886600">// Weight in instruction set</font> <font color="#880000">int</font> <font color="#000088">cost</font>; <font color="#886600">// additional time spent to execute inst.</font> <font color="#880000">int</font> <font color="#000088">ft_cost</font>; <font color="#886600">// additional time spent first time exec</font> <font color="#880000">double</font> <font color="#000088">prob_fail</font>; <font color="#886600">// probability of failing to execute inst</font> }; <font color="#880000">tArray<cInstEntry></font> <font color="#000088">inst_array</font>; <font color="#886600">// The instructions</font> <font color="#880000">tArray<int></font> <font color="#000088">nop_mods</font>; <font color="#886600">// Modification table for nops</font> <font color="#886600">// Static components...</font> static const <font color="#880000">cInstruction</font> <font color="#000088">inst_error</font>; static const <font color="#880000">cInstruction</font> <font color="#000088">inst_none</font>; static const <font color="#880000">cInstruction</font> <font color="#000088">inst_default</font>;</pre><p>The first thing that I do in the private section of the cInstLib definition isdefine another class called <font color="#880000">cInstEntry</font>, whichcontains all of the information about a single entry in an instructionlibrary. Since it is defined internally and privately, cInstEntry can onlybe used <i>inside</i> of cInstLib; we refer to it as a <b>helper</b> class.<p>cInstEntry contains only pubiic data about a single instruction. At themoment, the only portion of that data that we are using is the instructionname and the hardware method that it is supposed to call. We also haveroom to record how redundant this instruction is supposed to be in the full instruction set, how many CPU cycles should be spent as the cost toexecuting it, an additional first-time cost incurred only the first timethe instruction is used by an organism, and a probability of failure, thatthe instruction will not be executed at all. Any other useful informationabout an instruction can be put here, but then it should also be made useof elsewhere in the code.<p>After the definition of cInstEntry, we have the declaration of an array ofentries called <font color="#000088">inst_array</font>. The position ofan instruction in this array is the ID number that uniquely identifies thatinstruction. Thus, whichever instruction entry is placed in the array first,that instruction has ID of 0. The next one has an ID of 1, then 2, and so on.<p>The inst_array has the instructions ordered in the same order they arepresented in the inst_lib file from which they are loaded with onecaveat: all no-operation instructions must be listed first. This is because the next variable, <font color="#000088">nop_mods</font> is anarray that indicates which CPU component each nop is associated with.The size of this array determines how many nops there are, and they directly correspond to the same array positions in inst_array.<p>In the default instruction set, the inst_array has 26 entries containedin it, since this is the size of the instruction set, the first three ofwhich are <tt>nop-A</tt>, <tt>nop-B</tt>, and <tt>nop-C</tt> respectively.The nop_mods array has three integers in it, one for each of the threenops.<p>The remainder of the private section of the cInstSet definition containsthree static and constant variables that represent special instructions.They are <font color="#000088">inst_error</font>, for an illegal instruction(it will be given the ID number 254), <font color="#000088">inst_none</font>to represent an empty position (ID number 255), and<font color="#000088">inst_default</font> for the default instruction toinitialize genomes with, unless otherwise specified (usually ID number 0-- <tt>nop-A</tt> in the default set -- but this can be changed).<p>Here is the public portion of the cInstLib definition:<pre> public: <font color="#008800">cInstLib()</font> { ; } <font color="#008800">cInstLib</font>(const <font color="#880000">cInstLib</font> & <font color="#000088">in_inst_lib</font>); <font color="#008800">~cInstLib()</font> { ; } <font color="#880000">cInstLib</font> & <font color="#008800">operator=</font>(const <font color="#880000">cInstLib</font> & <font color="#000088">_in</font>); <font color="#886600">// Accessors</font> const <font color="#880000">cString</font> & <font color="#008800">GetName</font>(const <font color="#880000">cInstruction</font> & <font color="#000088">inst</font>) const; <font color="#880000">tHardwareMethod</font> <font color="#008800">GetFunction</font>(const <font color="#880000">cInstruction</font> & <font color="#000088">inst</font>) const; <font color="#880000">int</font> <font color="#008800">GetNopMod</font>(const <font color="#880000">cInstruction</font> & <font color="#000088">inst</font>) const { return <font color="#000088">nop_mods</font>[<font color="#000088">inst</font>.<font color="#008800">GetOp()</font>]; } <font color="#880000">cInstruction</font> <font color="#008800">GetInst</font>(const <font color="#880000">cString</font> & <font color="#000088">in_name</font>) const; <font color="#880000">int</font> <font color="#008800">GetSize()</font> const { return <font color="#000088">inst_array</font>.<font color="#008800">GetSize()</font>; } <font color="#880000">int</font> <font color="#008800">GetNumNops()</font> const { return <font color="#000088">nop_mods</font>.<font color="#008800">GetSize()</font>; } <font color="#886600">// Instruction Analysis.</font> <font color="#880000">int</font> <font color="#008800">IsNop</font>(const <font color="#880000">cInstruction</font> & <font color="#000088">inst</font>) const { return (<font color="#000088">inst</font>.<font color="#008800">GetOp()</font> < <font color="#000088">nop_mods</font>.<font color="#008800">GetSize()</font>); } <font color="#880000">cString</font> <font color="#008800">FindBestMatch</font>(const <font color="#880000">cString</font> & <font color="#000088">in_name</font>) const; <font color="#886600">// Insertion of new instructions...</font> <font color="#880000">int</font> <font color="#008800">Add</font>(const <font color="#880000">cString</font> & <font color="#000088">_name</font>, <font color="#880000">tHardwareMethod</font> <font color="#000088">_fun</font>, <font color="#880000">int</font> <font color="#000088">redundancy</font>=1, <font color="#880000">int</font> <font color="#000088">ft_cost</font>=0, <font color="#880000">int</font> <font color="#000088">cost</font>=0, <font color="#880000">double</font> <font color="#000088">prob_fail</font>=0.0); <font color="#880000">int</font> <font color="#008800">AddNop</font>(const <font color="#880000">cString</font> & <font color="#000088">_name</font>, <font color="#880000">tHardwareMethod</font> <font color="#000088">_fun</font>, <font color="#880000">int</font> <font color="#000088">reg</font>, <font color="#880000">int</font> <font color="#000088">redundancy</font>=1, <font color="#880000">int</font> <font color="#000088">ft_cost</font>=0, <font color="#880000">int</font> <font color="#000088">cost</font>=0, <font color="#880000">double</font> <font color="#000088">prob_fail</font>=0.0); <font color="#886600">// Static methods...</font> static const <font color="#880000">cInstruction</font> & <font color="#008800">GetInstDefault()</font> { return <font color="#000088">inst_default</font>; } static const <font color="#880000">cInstruction</font> & <font color="#008800">GetInstError()</font> { return <font color="#000088">inst_error</font>; } static const <font color="#880000">cInstruction</font> & <font color="#008800">GetInstNone()</font> { return <font color="#000088">inst_none</font>; } };</pre><p>The constructors, destructor, and assignment operator are all rather standardfor this class -- an instruction library can either be created from scratchor else copied over from a pre-existing one.<p>The accessors in this class allow specific information to be obtained aboutinstructions passed in. The <font color="#008800">GetName()</font> methodreturns the human-readable name for a specific instruction,<font color="#008800">GetFunction()</font> returns a pointer to the methodassociated with an instruction, and <font color="#008800">GetNopMod()</font>returns the id of the component modified by a nop-instruction passed in.Conversely, <font color="#008800">GetInst()</font> will return an instructionobject when an instruction name (as a string) is passed in.Additionally, there are the accessors <font color="#008800">GetSize()</font>to obtain the total number of instructions in the set, and<font color="#008800">GetNumNops()</font> will return the number of nopinstructions in the set.<p>Two instruction analysis methods also exist; one to determine if aninstruction is a nop called <font color="#008800">IsNop()</font>, andanother method called <font color="#008800">FindBestMatch()</font> takesin an unknown instruction name, and returns the closest name match that itcan find in the set. This allows Avida to make suggestions to the userin the case of a mis-spelled instruction name.<p>An instruction set is initially loaded by successive calls to the<font color="#008800">Add()</font> and <font color="#008800">AddNop()</font>,filling in the appropriate arguments. These methods are called from autility class (<font color="#880000">cHardwareUtil</font>) that manages theloading of the inst_set file. Next class we will be integrating the classesdiscussed here with the classes that directly implment the hardware.<p>Finally, three static methods are included to provide access to thethree pre-defined instructions.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?