home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / harbb30g.zip / DOC / pcode.txt < prev    next >
Text File  |  1999-05-15  |  4KB  |  127 lines

  1. The Clipper OBJ and pcode model (GNU|Open|Clipper project)
  2. ==========================================================
  3.  
  4. Lets consider the following Clipper sample Test.prg:
  5.  
  6.  
  7. function Main()
  8.  
  9.    ? "Hello world!"
  10.  
  11. return nil
  12.  
  13.  
  14. Once it gets compiled into a OBJ, what is there inside it ?
  15. In fact, what we get is the equivalent to the following C language
  16. application:
  17.  
  18.  
  19. SYMBOL symbols[] = { ... };
  20.  
  21. void MAIN( void )
  22. {
  23.    BYTE pcode[] = { ... };
  24.  
  25.    VirtualMachine( pcode, symbols );
  26. }
  27.  
  28.   
  29. Basically, Test.prg source code has been converted into a sequence
  30. of pcode bytes contained into the array pcode[] = { ... } and all our MAIN()
  31. function does is invoke, at run-time, a Clipper VirtualMachine() that will 
  32. process those pcode bytes.
  33.  
  34. Lets review the Test.prg pcode structure in more detail:
  35.  
  36. 0000 (2A) LINE 0                    2A 00 00
  37. 0003 (2A) LINE 3                    2A 03 00
  38. 0006 (13)   SYMF [QOUT]             13 02 00
  39. 0009 (01)   PUSHC "Hello world!"    01 ...
  40. 0018 (27)   DO(1)                   27 01 00
  41. 001B (2A) LINE 5                    2A 05 00 
  42. 001E (7B)   UNDEF                   7B
  43. 001F (79)   SAVE_RET                79
  44. 0020 (1E)   JMP 0023                1E 00 00 
  45. 0023 (60) ENDPROC                   60
  46.  
  47.  
  48. We could define a pcode.h file to better read that pcode:
  49.  
  50. pcode.h
  51.  
  52. #define  LINE    0x2A
  53. #define  SYMF    0x13
  54. #define  PUSHC   0x01
  55. #define  DO      0x27
  56. #define  UNDEF   0x7B
  57. ...
  58.  
  59.  
  60. So finally it may looks like:
  61.  
  62. BYTE pcode[] = { LINE, 0, 0, 
  63.                  LINE, 3, 0, 
  64.                  SYMF, 2, 0,
  65.                  PUSHC, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', '0',
  66.                  DO,   1, 0,
  67.                  LINE, 5, 0,
  68.                  UNDEF,
  69.                  SAVE_RET,
  70.                  JMP, 0, 0,
  71.                  ENDPROC };
  72.  
  73.  
  74. And what is it SYMBOL symbols[] ? Clipper creates a symbol table into
  75. the OBJ that later on will be used to create a dynamic symbol table 
  76. shared by the entire application. Each of those symbols have the following 
  77. structure:
  78.  
  79.    typedef struct
  80.    {
  81.       char * szName;   // Clipper infact keeps an array here (11 bytes).
  82.       BYTE   bScope;
  83.       LPVOID pVoid;
  84.    } SYMBOL; 
  85.  
  86. #define PUBLIC 0    // the scope of the function!
  87.  
  88. SYMBOL symbols[] = { { "MAIN",  PUBLIC, MAIN },
  89.                      { "QQOUT", PUBLIC, QQOUT } };
  90.  
  91.  
  92. Lets remember that the name of a function (MAIN, QQOUT) it is the address of the
  93. function, so our symbol table will be ready to use it to jump and execute any 
  94. linked function.
  95.  
  96. In fact, the pcode SYMF 2, 0 in our sample, will instruct the VirtualMachine()
  97. to use the 2 symbol which it is QQOUT.
  98.  
  99. Lets read the pcode:
  100.  
  101. LINE 0, 0   =>  We are located at line 0
  102. LINE 3, 0   =>  We are located at line 3
  103. SYMF 2, 0   =>  We are going to call QQOUT from our symbol table
  104. PUSHC ...   =>  This string is going to be used as a parameter
  105. DO   1, 0   =>  ok, jump to QQOUT and remember we have just suplied 1 parameter
  106. LINE 5, 0   =>  We are back from QQOUT and we are located at line 5
  107. UNDEF       =>  we are going to return this value (NIL)
  108. SAVE_RET    =>  Ok, return it
  109. JMP  0      =>  We don't jump to elsewhere, just continue to next pcode byte
  110. ENDPROC     =>  This is the end. We have completed this function execution
  111.  
  112. All these instructions will be evaluated from our VirtualMachine() function 
  113. (Clipper names it _plankton()). All functions end using ENDPROC, so when 
  114. the VirtualMachine() finds ENDPROC it knows it has reached the end of a 
  115. function pcode.
  116.  
  117. Now that we clearly understand this basic model we are ready to start
  118. implementing 'production rules' on our yacc (clipper.y) syntax to generate
  119. the specific output file (test.c) with the above structure (or we could 
  120. easily just generate the OBJ file for it).
  121.  
  122. to be continued...
  123.  
  124. Antonio Linares
  125. www.fivetech.com
  126.  
  127.