The CodePattern Service Class
The service class
CodePattern contains methods to provide a better notation for doing
tests like the following within the tool code and to provide a facility for doing tests like
this in
gmSL.
if(codptr[icode ] == OPC_LDA &&
codptr[icode+5 ] == OPC_LSB &&
codptr[icode+6 ] == LSB_List &&
codptr[icode+7 ] == OPC_MEM &&
codptr[icode+9 ] == OPC_LEV &&
codptr[icode+11] == OPC_LDA &&
codptr[icode+16] == OPC_LSB &&
codptr[icode+17] == LSB_ListIndex &&
codptr[icode+18] == OPC_MEM &&
codptr[icode+20] == OPC_ARG &&
codptr[icode+22] == OPC_INX)
The issue is that code like this requires that the user be very familiar with not just the
operation codes, but also with how these codes are physically laid out in the code vector.
That the user must know the opcodes is still a requirement. Higher level methods are provided
but they do not always provide the needed level of detail and whether they actually remove
the need to know the opcodes themselves is questionable. The need to know the layouts -- i.e.
the number of bytes associated with each opcode and the resultant offsets -- can be removed
by observing that there are two types of tests performed: (1) a test for the opcode itself
only and (2) a test for the opcode and its associated subcode information. A match operation
is needed that says "match the opcode and if OK move to the next opcode". This match
operation is performed by a new opcode
OPC whose subcodes are the opcodes. This opcode
is entered into the file
opcodes.xml in the standard way.
<opcode id="OPC" opc="127" type="DoubleByte" role="none" subcodes="181" >
<subcode id="NEW" value="0" /> <!-- Start new command -->
<subcode id="LDA" value="1" /> <!-- Load a variable address -->
....
In addition an opcode to control the overall match logic is needed. It is called
OPO
and has five subcodes.
<opcode id="OPO" opc="178" type="DoubleByte" role="none" subcodes="5" >
<subcode id="EndList" value="0" />
<subcode id="Argument" value="1" />
<subcode id="Lvalue" value="2" />
<subcode id="FindMatch" value="3" />
<subcode id="Comment" value="4" />
</opcode>
Given these additional opcodes it is now possible to write a static operation specification.
static UBYTE anaSetSelected[] =
{
OPC_OPC,OPC_LDA,
OPC_LSB,LSB_List,
OPC_OPC,OPC_MEM,
OPC_OPC,OPC_LEV,
OPC_OPC,OPC_LDA,
OPC_LSB,LSB_ListIndex,
OPC_OPC,OPC_MEM,
OPC_OPC,OPC_ARG,
OPC_OPC,OPC_INX,
OPC_OPO,OPO_EndList
};
Methods in this class perform matches using these code pattern specifications and methods that
read them using a simplified notation for use primarily by
gmSL.
The method CodePattern_FindOpcode
Prototype
int CodePattern_FindOpcode(char* ident);
The
CodePattern_FindOpcode method finds an opcode given its identifier. It looks up
the label for a particular opcode in the
OPCODES information for the language. Its
parameter is:
Parameter | Description
|
ident | Contains the opcode identifier in null-terminated string form.
|
If there is an opcode with the indicated identifier, then its
opc value is returned.
If no such opcode exists, then a minus one is returned.
The method CodePattern_FindSubcode
Prototype
int CodePattern_FindSubcode(int opcode,char* label);
The
CodePattern_FindSubcode method finds a subcode of a give opcode via the subcode
label. Its parameters are:
Parameter | Description
|
opcode | Contains the sequence number of the desired opcode. This was the opc
attribute of opcode when it was defined.
|
label | Contains a null-terminated string specifying the label to be searched for.
|
If found, the method returns the subcode value that was assigned. If not found, it returns
a minus one.
The method CodePattern_Match
Prototype
int CodePattern_Match(UBYTE* pcode,int opadr,UBYTE* operation);
The
CodePattern_Match method checks if a sequence of operation codes in a code block
match a code pattern. Its parameters are:
Parameter | Description
|
pcode | Contains the code block being checked against the code pattern.
|
opadr | Specifies the offset of the start of the actual operation codes in the code block.
|
operation | contains the code pattern to be matched.
|
If a match is made, then the method returns the offset of the first byte in the code block
beyond the end of the match. If no match is made, the method returns zero.
The method CodePattern_Read
Prototype
int CodePattern_Read(char* source,UBYTE* operation);
The
CodePattern_Read method reads a simplified representation of a code pattern. Its
parameters are:
Parameter | Description
|
source | Contains the source representation of the code pattern in null-terminated form.
|
operation | receives the code pattern itself in operation code form.
|
If all goes well, the method returns the length of the compiled code pattern; else it returns
one of the following negative error codes:
code | Meaning
|
-1 | An unrecognized opcode operation (OPO subcode) was encountered.
|
-2 | The subcode identifier associated with an opcode was not recognized.
|
-3 | The closing square bracket ending a bracketed identifier was missing.
|
-4 | A source code identifier was not found.
|