145 lines
4.3 KiB
Plaintext
145 lines
4.3 KiB
Plaintext
/*
|
||
* $Id$
|
||
*/
|
||
|
||
/*
|
||
* Las siguientes partes son derechos adquiridos de sus autores individuales.
|
||
* www - http://www.harbour-project.org
|
||
*
|
||
* Copyright 2001 Antonio Linares
|
||
* Documentaci¢n en Ingl‚s
|
||
*
|
||
* Copyright 2001 Alejandro de G rate <alex_degarate@hotmail.com>
|
||
* Traducci¢n al Espa¤ol de pcode.txt
|
||
*
|
||
* Vea doc/license.txt por los t‚rminos de la licencia.
|
||
*
|
||
*/
|
||
|
||
|
||
El OBJ de Clipper y el modelo pcode (GNU|Open|Clipper project)
|
||
==============================================================
|
||
|
||
Consideremos el siguiente ejemplo de Clipper, test.prg:
|
||
|
||
function Main()
|
||
|
||
? "Hola mundo!"
|
||
|
||
return nil
|
||
|
||
Una vez que esto se compila dentro de un OBJ, qu‚ es lo que hay dentro
|
||
de ‚l ?
|
||
En efecto, lo que nosostros tenemos es un equivalente a la siguiente
|
||
aplicaci¢n de lenguaje C:
|
||
|
||
SYMBOL symbols[] = { ... };
|
||
|
||
void MAIN( void )
|
||
{
|
||
BYTE pcode[] = { ... };
|
||
|
||
VirtualMachine( pcode, symbols );
|
||
}
|
||
|
||
B sicamente, el c¢digo fuente de test.prg ha sido convertido en una
|
||
secuencia de bytes pcode contenidos en el array pcode[] = {...}
|
||
Todo lo que nuestra funci¢n MAIN hace es invocar, en tiempo de ejecuci¢n
|
||
a la funci¢n de VirtualMachine() que procesar aquellos bytes de pcodes.
|
||
|
||
Vamos a revisar la estructura de pcodes de test.prg con m s detalle:
|
||
|
||
0000 (2A) LINE 0 2A 00 00
|
||
0003 (2A) LINE 3 2A 03 00
|
||
0006 (13) SYMF [QOUT] 13 02 00
|
||
0009 (01) PUSHC "Hello world!" 01 ...
|
||
0018 (27) DO(1) 27 01 00
|
||
001B (2A) LINE 5 2A 05 00
|
||
001E (7B) UNDEF 7B
|
||
001F (79) SAVE_RET 79
|
||
0020 (1E) JMP 0023 1E 00 00
|
||
0023 (60) ENDPROC 60
|
||
|
||
Nosotros podemos definir un archivo hbpcode.h para leer mejor aquellos
|
||
pcode:
|
||
|
||
----------------------
|
||
hbpcode.h
|
||
|
||
#define LINE 0x2A
|
||
#define SYMF 0x13
|
||
#define PUSHC 0x01
|
||
#define DO 0x27
|
||
#define UNDEF 0x7B
|
||
...
|
||
----------------------
|
||
|
||
As¡ finalmente esto quedar¡a como:
|
||
|
||
BYTE pcode[] =
|
||
{ LINE, 0, 0,
|
||
LINE, 3, 0,
|
||
SYMF, 2, 0,
|
||
PUSHC, 'H', 'o', 'l', 'a', ' ', 'm', 'u', 'n', 'd', 'o', '!', '0',
|
||
DO, 1, 0,
|
||
LINE, 5, 0,
|
||
UNDEF,
|
||
SAVE_RET,
|
||
JMP, 0, 0,
|
||
ENDPROC };
|
||
|
||
Y qu‚ es SYMBOL symbols[] ?
|
||
Cliper crea una tabla de s¡mbolos en el archivo OBJ que luego ser usada
|
||
para crear una tabla din mica de s¡mbolos compartida por la aplicaci¢n
|
||
entera. cada uno de esos s¡mbolos tiene la siguiente estructura:
|
||
|
||
typedef struct
|
||
{
|
||
char * szName; // Clipper de hecho mantiene un array aqu¡ (11 bytes)
|
||
BYTE bScope;
|
||
LPVOID pVoid;
|
||
} SYMBOL;
|
||
|
||
#define PUBLIC 0 // el alcance de la funci¢n !
|
||
|
||
SYMBOL symbols[] = { { "MAIN", PUBLIC, MAIN },
|
||
{ "QQOUT", PUBLIC, QQOUT } };
|
||
|
||
Recordemos que el nombre de una funci¢n (MAIN, QQOUT) es la direcci¢n de
|
||
la funci¢n, as¡ nuestra tabla de s¡mbolos estar lista para usarla para
|
||
saltar y ejecutar cualquier funci¢n enlazada (linkeada).
|
||
|
||
De hecho, el pcode SYMF 2, 0 en nuestro ejemplo, instruir a la funci¢n
|
||
VirtualMachine(), para usar el 2do s¡mbolo que es QQOUT.
|
||
|
||
Vamos a leer el pcode:
|
||
|
||
LINE 0, 0 => Nosotros estamos ubicados en la l¡nea 0
|
||
LINE 3, 0 => Nosotros estamos ubicados en la l¡nea 3
|
||
SYMF 2, 0 => Vamos a llamar a QQOUT desde nuestra tabla de s¡mbolos
|
||
PUSHC ... => Esta cadena va a ser usada como un par metro
|
||
DO 1, 0 => ok, saltemos a QQOUT y recordemos que le dimos 1 par metro
|
||
LINE 5, 0 => Estamos de vuelta desde QQOUT y estamos ubicados en l¡nea 5
|
||
UNDEF => Nosotros vamos a retornar este valor (NIL)
|
||
SAVE_RET => Ok, retornemoslo
|
||
JMP 0 => No saltamos dondequiera, continuamos con el pr¢ximo pcode
|
||
ENDPROC => Es el fin. hemos completado la ejecuci¢n de esta funci¢n
|
||
|
||
Todas estas funciones ser n evaluadas desde nuestra funci¢n
|
||
VirtualMachine(), (Clipper la llama _plankton() ). Todas las funciones
|
||
terminan usando ENDPROC, as¡ cuando VirtualMachine() encuentra ENDPROC
|
||
sabe que ha alcanzado el final de una funci¢n pcode.
|
||
|
||
Ahora que nosotros entendemos claramente el modelo b sico, nosotros
|
||
estamos en condiciones de comenzar a implementar "reglas de producci¢n"
|
||
en nuestra sintaxis yacc (harbour.y) para generar el archivo de salida
|
||
espec¡fico (test.c) con la estructura de arriba (¢ nosotros podemos
|
||
f cilmente generar el archivo OBJ para ‚l).
|
||
|
||
Continuar ...
|
||
|
||
Antonio Linares
|
||
|
||
|
||
|