parser.c
Before a program is compiled, Palmphi parses every source code and
makes some substitutions and add some functions depending on what you
wrote. For example : It can be so easy as Form1.Show()
becomes FrmGotoForm(_Form1) or as difficult as
Label3.Caption="hello" where the label is deleted and created again
with the new text. This parsing is made according a master file called
parser.c
Following lines can be found in the file edit.ppc (a file included by parser.c). These here are
only examples, the real file can differ from this one. You can also
change this file to add new methods or pseudo-classes if you want. Be
warned though that an error on this file can mean that the program is
not usable or that your code will behave different. I would appreciate
that you send me modified versions of this file, if you find your
modifications useful for other people.
You may be asking your self, why not use C++ to make this and get full
C++ classes?. The two key reasons for me have been the following:
- C produces smaller executables than C++
- C++ doesn't allow lvalues. (I know with a little effort you can simulate this, but is anyway not as easy as here)
Think of this parser.c as a class library definition, it allows to write programs at a level somewhat higher
than plain C sometimes like C++ or Object Pascal.
Let's start with an example. The code :
Edit1.Text="Hello World";
Will be parsed according to the part of "parser.c" which defines a
TEdit class (I assume, that Edit1 is a TEdit). This part is marked in
red in following code:
class TEdit=FieldPtr {
char* Text_() return FldGetTextPtr(THIS);
char* Text() return $$##$$Edit_TextS(THIS);
void Copy() FldCopy(THIS);
void Paste() FldPaste(THIS);
void Cut() FldCut(THIS);
void Delete(PAR1,PAR2) FldDelete(THIS,PAR1,PAR2);
void Draw() FldDrawField(THIS);
void Empty() FldEraseField(THIS);
int SelStart() return $$##$$Edit_SelStart(THIS);
int SelLength() return $$##$$Edit_SelLength(THIS);
void SetFocus() FldGrabFocus(THIS);
int Visible() return $$##$$Edit_Visible(THIS);
int Width() return THIS_width;
int Top() return THIS_top;
int Left() return THIS_left;
int Height() return THIS_height;
char Enabled() return CtlEnabled(THIS);
lvalues:
Enabled CtlSetEnabled(THIS,RVALUE);
Text $$##$$Edit_SetText(THIS,RVALUE);
SelStart FldSetSelection(THIS,RVALUE,RVALUE);
SelLength Edit_SetSelLength(THIS,RVALUE);
Visible $$##$$Assign_Visible(_THIS,PARENTFORM,RVALUE);
}
This "$$##$$" means that the following function must be add for the
program to be successfully compiled. The parser will get in this case
the function Edit_SetText, because in our code Text is a lvalue. Edit_SetText will automatically added to the generated code.
The parser would search for a line "Function Edit_SetText" in parser.c
and included files. Once it finds it, it would add all following lines
until the line which contains a "}".
The values RVALUE and THIS are automatically substituted with the right
part of the assignation and the object used respectively. The portion
$$##$$ is, of course, also removed in the resulting parsed program. So
that means we get following code:
Edit_SetText(Edit1,"Hello World");
Edit1 is automatically defined as a FieldPtr if you have added Edit1 as
a TEdit on the Form. This is defined at the very first line of the
class :
class TEdit=FieldPtr {
You can also use such definitions. So it is also possible to do following :
TEdit TmpEdit;
if (val)
TmpEdit=Edit1;
else
TmpEdit=Edit2;
TmpEdit.Text="Hello";
You can use the property Text at the other part of the assignation. So following code is allowed:
Edit1.Text=Edit2.Text;
This would be changed in :
Edit_SetText(Edit1,Edit_TextS(Edit2));