gmslIntrinsics

The gmSL Intrinsics

The gmSL language contains a few intrinsic methods and enumerations.

OPC Enumeration

Opcodes are defined in the metalanguage file Opcode.xml. The intrinsic enumeration OPC allows the code to reference the entries in this file. Note that in the current version of opcodes.xml there are 189 opcodes and over 4100 opcode.subcode combinations. The OPC enumeration has two forms -- opcode and subcode. The opcode form is written OPC.opc where opc is one of the 189 defined opcodes. The subcode form is written OPC.opc.subcode where opc.subcode is one of the 4100 valid combinations defined. Note that gmSL is not case sensitive, but by convention upper case is used for the opcodes here to make them easier to see in the code.


Consider the following opcode definition from the opcode.xml metalanguage file.


 <opcode id="CNV" opc="55"  type="DoubleByte" role="convert" subcodes="65" >
   <subcode id="ToChar" value="0" />
   <subcode id="ToDateTime" value="1" />
   <subcode id="ToString" value="2" />
      ...
The numbers defined by the opc and value attributes are referred to as the "emission" value, since they are the actual numbers emitted for the codes in the intermediate language. The OPC enumeration value is the emission value. If an undefined identifier is used then its value is -1. The code below demonstrates this


System.LogMessage("Emission of opcode CNV is " + OPC.CNV);
System.LogMessage("Emission of subcode ToString of CNV is " + OPC.CNV.ToString);
System.LogMessage("Value of undefined subcode myString is " + OPC.CNV.myString);


The output shows the emission or undefined value. Note that emissions are always greater than or equal to zero.


Emission of opcode CNV is 55
Emission of subcode ToString of CNV is 2
Value of undefined subcode myString is -1

mask Method

gmSL: int mask(int seqNumb)


The method mask is used to convert a sequence number between 0 and 31 into a power of 2 mask value that can be used as a boolean flag. As an example consider the PropertyStatus enumeration that combines various ContextFlags enumeration entries under single identifiers.


<Enumeration id="PropertyStatus" >
   <Entry id="SetByRef"      value="(%= Mask(ContextFlags.ByRef) + Mask(ContextFlags.UseGet) %)" />
   <Entry id="GetSet"        value="(%= Mask(ContextFlags.UseGet) %)" />
       ...
   <Entry id="AsNew"         value="(%= Mask(ContextFlags.ByRef) + Mask(ContextFlags.New) %)" />
</Enumeration>
The following code shows how these values are computed, combined, and used.


int SetByRef;
int AsNew;

   SetByRef = Mask(ContextFlags.ByRef) + Mask(ContextFlags.UseGet);
   AsNew = Mask(ContextFlags.ByRef) + Mask(ContextFlags.New);
   System.LogMessage("ContextFlags.ByRef = " + ContextFlags.ByRef);
   System.LogMessage("mask(ContextFlags.ByRef) = " + Mask(ContextFlags.ByRef));
   System.LogMessage("ContextFlags.UseGet = " + ContextFlags.UseGet);
   System.LogMessage("mask(ContextFlags.UseGet) = " + Mask(ContextFlags.UseGet));
   System.LogMessage("ContextFlags.New = " + ContextFlags.New);
   System.LogMessage("mask(ContextFlags.New) = " + Mask(ContextFlags.New));
   System.LogMessage("SetByRef = " + SetByRef);
   System.LogMessage("AsNew = " + AsNew);
   if(SetByRef & mask(ContextFlags.ByRef)) System.LogMessage("SetByRef has ByRef flag");
   else System.LogMessage("SetByRef does not have ByRef flag");
   if(SetByRef & mask(ContextFlags.New)) System.LogMessage("SetByRef has New flag");
   else System.LogMessage("SetByRef does not have New flag");


The output shows the initial enumeration values and their power of 2 mask values.


ContextFlags.ByRef = 7
mask(ContextFlags.ByRef) = 64
ContextFlags.UseGet = 10
mask(ContextFlags.UseGet) = 512
ContextFlags.New = 19
mask(ContextFlags.New) = 262144
SetByRef = 576
AsNew = 262208
SetByRef has ByRef flag
SetByRef does not have New flag
Though the mask method is used extensively in the metalanguage definitions to ensure the enumeration entries and their associated attribute flags are consistent, the if statements shows a typical use of mask to determine if a specified flag is set in some field.

sizeof Method

gmSL: int sizeof(object attributeClass)


The method sizeof is used to determine the size of the gmSL attribute classes. This size value is needed when storing or allocating room for instances of these classes. The parameter className can only refer to one of these language classes, not to an arbitrary binary type or component. A typical use of this method might be


iRefer = Store.FindVector(basName,0);
if(iRefer == 0)
{
   iRefer = Store.Vector(basName,0,sizeof(tVbName),ObjectType.Vb_Name);
}
Another type of information vector associated with gmSL are the opcode emissions whose sizes vary from one byte to five bytes depending upon the type of the opcode. For example consider code that might insert a conversion operation into a codeblock


pcnt = Opcode.ExpandCode(iRefer,pcnt,sizeof(OPC.CNV));
Opcode.SetOperation(codptr,iRefer,OPC.CNV,OPC.CNV.ToString);
The logic must first expand the code block by the length of the CNV emission and then it can insert it. The sizeof(opcode) provides the length of the emission associated with the opcode.


The code below shows how these sizes are referenced and their values.


System.LogMessage("sizeof(tMigInfo)  = " + sizeof(tMigInfo));
System.LogMessage("sizeof(tInfoFile) = " + sizeof(tInfoFile));
System.LogMessage("sizeof(tVbName)   = " + sizeof(tVbName));
System.LogMessage("sizeof(tVariable) = " + sizeof(tVariable));
System.LogMessage("sizeof(tOpcInfo)  = " + sizeof(tOpcInfo));
System.LogMessage("sizeof(OPC.LDA)   = " + sizeof(OPC.LDA));
System.LogMessage("sizeof(OPC.LIC)   = " + sizeof(OPC.LIC));
System.LogMessage("sizeof(OPC.CBN)   = " + sizeof(OPC.CBN));
System.LogMessage("sizeof(OPC.USC)   = " + sizeof(OPC.USC));
The size values reported are as follows.


sizeof(tMigInfo)  = 28
sizeof(tInfoFile) = 72
sizeof(tVbName)   = 36
sizeof(tVariable) = 60
sizeof(tOpcInfo)  = 17
sizeof(OPC.LDA)   = 5
sizeof(OPC.LIC)   = 3
sizeof(OPC.CBN)   = 1
sizeof(OPC.USC)   = 2
Table of Contents