Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

The Clipper pcode model

159 views
Skip to first unread message

Antonio Linares

unread,
Mar 25, 1999, 3:00:00 AM3/25/99
to
Lets consider the following Clipper sample Test.prg:


function Main()

? "Hello world!"

return nil


Once it gets compiled into a OBJ, what is there inside it ?
In fact, what we get is the equivalent to the following C language
application:


SYMBOL symbols[] = { ... };

void MAIN( void )
{
BYTE pcode[] = { ... };

VirtualMachine( pcode, symbols );
}


Basically, Test.prg source code has been converted into a sequence
of pcode bytes contained into the array pcode[] = { ... } and all our MAIN()
function does is invoke, at run-time, a Clipper VirtualMachine() that will
process those pcode bytes.

Lets review the Test.prg pcode structure in more detail:

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


We could define a pcode.h file to better read that pcode:

pcode.h

#define LINE 0x2A
#define SYMF 0x13
#define PUSHC 0x01
#define DO 0x27
#define UNDEF 0x7B
...


So finally it may looks like:

BYTE pcode[] = { LINE, 0, 0,
LINE, 3, 0,
SYMF, 2, 0,
PUSHC, 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l',
'd', '!', '0',
DO, 1, 0,
LINE, 5, 0,
UNDEF,
SAVE_RET,
JMP, 0, 0,
ENDPROC };

And what is it SYMBOL symbols[] ? Clipper creates a symbol table into
the OBJ that later on will be used to create a dynamic symbol table
shared by the entire application. Each of those symbols have the following
structure:

typedef struct
{
char * szName; // Clipper infact keeps an array here (11 bytes).
BYTE bScope;
LPVOID pVoid;
} SYMBOL;

#define PUBLIC 0 // the scope of the function!

SYMBOL symbols[] = { { "MAIN", PUBLIC, MAIN },
{ "QQOUT", PUBLIC, QQOUT } };


Lets remember that the name of a function (MAIN, QQOUT) it is the address of
the
function, so our symbol table will be ready to use it to jump and execute
any
linked function.

In fact, the pcode SYMF 2, 0 in our sample, will instruct the
VirtualMachine()
to use the 2 symbol which it is QQOUT.

Lets read the pcode:

LINE 0, 0 => We are located at line 0
LINE 3, 0 => We are located at line 3
SYMF 2, 0 => We are going to call QQOUT from our symbol table (symbol nº
2)
PUSHC ... => This string is going to be used as a parameter
DO 1, 0 => ok, jump to QQOUT and remember we have just suplied 1
parameter
LINE 5, 0 => We are back from QQOUT and we are located at line 5
UNDEF => we are going to return this value (NIL)
SAVE_RET => Ok, return it
JMP 0 => We don't jump to elsewhere, just continue to next pcode byte
ENDPROC => This is the end. We have completed this function execution

All these instructions will be evaluated from our VirtualMachine() function
(Clipper names it _plankton()). All functions end using ENDPROC, so when
the VirtualMachine() finds ENDPROC it knows it has reached the end of a
function pcode.

Now that we clearly understand this basic model we are ready to start
implementing 'production rules' on our yacc (clipper.y) syntax to generate
the specific output file (test.c) with the above structure (or we could
easily just generate the OBJ file for it).

Antonio Linares
www.fivetech.com

Antonio Linares

unread,
Mar 25, 1999, 3:00:00 AM3/25/99
to
This is our pcode C model. It compiles fine.

Test.c

typedef unsigned char BYTE;
typedef void * LPVOID;

typedef struct
{
char * szName;

BYTE bScope;
LPVOID pVoid;
} SYMBOL;

#define PUBLIC 0

void MAIN( void );
void QOUT( void );
void VirtualMachine( BYTE * pcode, SYMBOL * symbols );

SYMBOL symbols[] = { { "MAIN", PUBLIC, MAIN },

{ "QOUT", PUBLIC, QOUT } };

void MAIN( void )
{
BYTE pcode[] = { 0, 1, 2, 3 };

VirtualMachine( pcode, symbols );
}

regards,

Antonio Linares
www.fivetech.com

Manuel Ruiz Tienza

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to

>All these instructions will be evaluated from our VirtualMachine() function
>(Clipper names it _plankton()). All functions end using ENDPROC, so when
>the VirtualMachine() finds ENDPROC it knows it has reached the end of a
>function pcode.
>

What is the better, generate pcode o generate a portable framework
across multiple plataforms (using api/library). For example:

function Main()

? "Hello world!"

return nil

will be transformed in

#include <clipper_api.h>

int main(int argc,char **argv)
{
clipper__init_environment(argc,argv);

clipper__init_call_environment();
clipper__add_string_parameter( "Hello world!" );
clipper__call_function( "QQOUT", plist );
...
clipper__destroy_call_environment();
...
...
}

clipper__xxxxxxxx function will be at library libclipper.a (for
example) and we will run

gnu-clipper miprog.prg // generate miprog.c
gcc miprog.c -o miprog -llibclipper.so // generate miprog (executable)

to get a executable program.

>Now that we clearly understand this basic model we are ready to start
>implementing 'production rules' on our yacc (clipper.y) syntax to generate
>the specific output file (test.c) with the above structure (or we could
>easily just generate the OBJ file for it).

If we generate the OBJ file we need to generate it for each
diferent plataform (msdos,linux,...), if we generate ANSI C code only
one time is required for all plataforms.

>Antonio Linares
>www.fivetech.com
>
>

Manuel Ruiz Tienza
mr...@joca.es
-- Sorry for my english it's very bad :( --


Antonio Linares

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to
Manuel,

> What is the better, generate pcode o generate a portable framework
> across multiple plataforms (using api/library).

The pcode is 100% portable to all platforms. The same for the virtual
machine.

regards,

Antonio Linares
www.fivetech.com

Manuel Ruiz Tienza

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to
On Fri, 26 Mar 1999 13:45:16 +0100, "Antonio Linares"
<alin...@fivetech.com> wrote:

>Manuel,
>
>> What is the better, generate pcode o generate a portable framework
>> across multiple plataforms (using api/library).
>
>The pcode is 100% portable to all platforms. The same for the virtual
>machine.

Sure, It's more portable, but isn't more efficient.
Using a VM working over pcode you can't get benefits from
optimization.

Using a VM embebed in a set of C function
you can get benefits in optmization phase and
C/C++ compiler can do for you.

In another hand, I'm thinking about extend library.
Using approach that I propose will be easy
to extend clipper using another languajes as
C/C++, Pascal, (in a production system, of course)

That you think about this ?

Manuel Ruiz Tienza.
mr...@joca.es

Dave Pearson

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to
On Fri, 26 Mar 1999 13:45:16 +0100, Antonio Linares <alin...@fivetech.com> wrote:

> > What is the better, generate pcode o generate a portable framework
> > across multiple plataforms (using api/library).
>
> The pcode is 100% portable to all platforms. The same for the virtual
> machine.

Out of interest, which platforms has it been tested on?

--
Take a look in Hagbard's World: | w3ng - The WWW Norton Guide reader.
http://www.acemake.com/hagbard/ | eg - Norton Guide reader for Linux.
http://www.hagbard.demon.co.uk/ | weg - Norton Guide reader for Windows.
Free software, including........| dgscan - DGROUP scanner for Clipper.


Manuel Ruiz Tienza

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to

OpenClipper/GNU Clipper parser from
ftp://ftp.iag.net/pub/clipper/general/cliparse.zip
don't compile under Linux.

A modified version compiling under linux is in

ftp://central.joca.es/pub/OpenClipper/cliparse-6.tar.gz

Bye!

Manuel Ruiz Tienza.
mr...@joca.es


Dave Pearson

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to
On Fri, 26 Mar 1999 14:53:40 GMT, Manuel Ruiz Tienza <mr...@joca.es> wrote:
> On Fri, 26 Mar 1999 14:15:58 GMT, davep...@hagbard.demon.co.uk (Dave
> Pearson) wrote:
>
> >On Fri, 26 Mar 1999 13:45:16 +0100, Antonio Linares <alin...@fivetech.com> wrote:
> >
> >> The pcode is 100% portable to all platforms. The same for the virtual
> >> machine.
> >
> >Out of interest, which platforms has it been tested on?
>
> OpenClipper/GNU Clipper parser from
> ftp://ftp.iag.net/pub/clipper/general/cliparse.zip
> don't compile under Linux.

You'll notice that I wasn't talking about the parser, I was talking about
the pcode (Antonio has a virtual machine kicking around).

> A modified version compiling under linux is in
>
> ftp://central.joca.es/pub/OpenClipper/cliparse-6.tar.gz

Interesting, I'll take a look. I did point out to Antonio that the lex/yacc
code in the parser didn't make it thru flex/bison but I never got a
response. I take it you are sending your fixes back to Antonio so that the
"original" cut can be made cross-platform?

Antonio Linares

unread,
Mar 26, 1999, 3:00:00 AM3/26/99
to
Dave, Manuel,

The virtual machine is written using standard C language, this is why I
assume is completely portable to other systems.

> I did point out to Antonio that the lex/yacc
> code in the parser didn't make it thru flex/bison but I never got a
> response

Jesus Salas is using Bison. I tried it and clipper.y was compiled fine.
Anyhow, I have been working with byacc.exe for a long time and I like it
very much.

regards,

Antonio Linares
www.fivetech.com

Dave Pearson

unread,
Mar 27, 1999, 3:00:00 AM3/27/99
to
On Fri, 26 Mar 1999 18:30:27 +0100, Antonio Linares <alin...@fivetech.com> wrote:

> > I did point out to Antonio that the lex/yacc code in the parser didn't
> > make it thru flex/bison but I never got a response
>
> Jesus Salas is using Bison. I tried it and clipper.y was compiled fine.
> Anyhow, I have been working with byacc.exe for a long time and I like it
> very much.

Note that I'm not attempting to dictate tools, just suggesting that if the
code can build, "out if the box", on what is arguably the most popular
"alternative" operating system at the moment, all the better.

0 new messages