Basic types
Basic types in TempLuator are direct equivalents of fundamental types of standard 32-bit C compiler. In addition, some typedef'ed types are supported just to make the output look familiar. The following basic types are supported by default:
/* floating point types */ float FLOAT double longdouble /* 8 bit types */ unsignedchar BYTE __int8 unsigned__int8 char CHAR UCHAR /* 16 bit types */ short unsignedshort __int16 unsigned__int16 WORD SHORT USHORT /* 32 bit types */ int unsignedint __int32 unsigned__int32 long unsignedlong LONG ULONG DWORD BOOL INT UINT WPARAM LPARAM LRESULT COLORREF LONG32 UINT32 DWORD32 INT32 LONG32 /* 64 bit types */ __int64 unsigned__int64 LONG64 LONGLONG ULONG64 ULONGLONG DWORD64 UINT64 INT64 /* special character types */ char__ unsignedchar__ BYTE__
Each of the types above are ordinary Lua function. Usually, name of a type function is equal to the corresponsing type. When name of a type consists of two separate words (like "unsigned int") then the separator space is omitted in the name of the function ("unsignedint()"). This limitation arises from the fact that function names in Lua cannot have spaces.
All of these functions expect three parameters: INT32(Name, Comment, NumberOfItems). The first parameter (Name) is mandatory and gives the name of the type instance. The second parameter (Comment) defines the single-line comment that will be associated with the type instance. The third parameter (NumberOfItems) if present tells the type that it must be shown as an array of given type with the given number of elements.
Internally, all type related functions know how many bytes are necessary for its type, read this amount of bytes from the input file using the ReadBytes() function, print name of the type, print name of the instance, the "=" sign and then show the numeric value of the type using the proper Print...() function. Next, the type function prints the ";" delimiter and types the comment if requested to do so.
In case when you pass only one parameter to a type function (Name), according to Lua rules you don't have to enclose the parameter in parenthesis. If you pass more than one parameter, the parenthesis in function call become necessary:
-- two equivalent ways to use a type with single Name parameter LONG "left" LONG("left") -- when we pass more parameters, we must use parenthesis LONG("left", "x-coordinate of the upper-left corner")
All of the basic types can be represented as an inline array. In order to do this, you pass the NumberOfItems parameter, which must evaluate to a number. In case when you want to pass the NumberOfItems and want to skip the Comment parameter, just pass nil as the Comment parameter. Here is an example and its output:
int("Scaler", "Scaling coefficient") int("Scalers", "Scaling coefficients", 3) -- when we define an array but don't want to type comment, we use nil for Comment int("Adders", nil, 3)
int Scaler = 1; // Scaling coefficient int Scalers[3] = { 1, 2, 3 }; // Scaling coefficients int Adders[3] = { 4, 5, 6 };
Please note that there is a limit for the size of an inline array which is set through the MaxInlineElements global variable. By default its value is 64 but you can assign any value you want to this variable. When number of array elements is greater than the value of this variable, only the first MaxInlineElements are printed followed by an ellipsis:
int Scalers[128] = { 1, 2, 3, ... };
Processing of inline arrays is accomplished through the internal inlinearray() function.
Most of the types are defined through type generators so if you need an additional type you can easily generate it.
A few types (namely, those with names ending with "__", that is char__(), unsignedchar__(), and BYTE__()) are somewhat special. All of them are intended for convenient representation of strings of characters. The main difference is that these types expect an additional (fourth) optional boolean parameter which, if set to true, tells the type that the string they represent is not zero terminated. In this case, all these types produce results which are not entirely correct in the C sense. However, in some cases such representation of strings is much more convenient than strong C compliance. For example, in ZIP template we use the following representation:
char__("FileName", "name of the file (without terminating zero)", NameLen, true)
The output in this case is
char FileName[8] = "TEST.LUA"; // name of the file (without terminating zero)
It is easy to see that in the C sense this definition is not entirely correct (just think of the terminating zero character). However, don't you agree that this representation is much better and graphic than, say
char FileName[8] = { 'T', 'E', 'S', 'T', '.', 'L', 'U', 'A' }; // name of the file (without terminating zero)