[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Marst Algol 60 compiler

From: Andrew Makhorin
Subject: Re: Marst Algol 60 compiler
Date: Tue, 26 Jan 2016 15:44:48 +0300

> I believe I am making progress. I followed your suggestion and after a
> lot of studying! have successfully called three different procedures
> from gsl that take one, two and three real value inputs and deliver a
> real output. I've edited the algol.h header file to add #include
> statements for the gsl procedures. I notice the procedures I have
> called use odd sequence numbering ( ie E_1 for the first procedure
> declared , E_3 for the second declared and so on). It is safe to
> continue using this number sequencing?
> I guess I need to move onto how to deal with:
> 1) Integer arguments
> 2) Arrays
> Any tips?
> Also will this mechanism allow arrays to be returned - or does Algol
> 60 not support that capability?

Probably the most relevant way to call external C functions in your case
is to write a wrapper for each C function to be called as if it (the
wrapper) were produced by Marst. For example, let you need to call the
following C function:

int foo(int n, double a[], double x[]);

If you would write a wrapper in Algol 60, it could looks like follows
(it is assumed that it is a separately translated procedure, so in the
main Algol 60 program there should be its "code" declaration):

integer procedure foo(n, a, x);
value n;
integer n;
real array a, x;

Marst would produce the following code (note that all formal parameters
are implemented as struct arg objects, and foo_0 means that procedure
foo is declared on level 0, i.e. outside any block):

struct desc foo_0 /* precompiled integer procedure */
(     struct arg n_1 /* by value integer */,
      struct arg a_1 /* by name real array */,
      struct arg x_1 /* by name real array */

So, if you need to obtain the value of n, you could use the following

int n = get_int((global_dsa = n_1.arg2, 
   (*(struct desc (*)(void))n_1.arg1)()));

(global_dsa specifies a context, in which corresponding actual parameter
is evaluated, because it is considered an expression passed by name).

Similarly, if you need to obtain a[i,j] or x[j], you could write

struct dv *a = a_1.arg1;
struct dv *x = x_1.arg1;

where struct dv is the Algol array descriptor (so called dope vector),
declared in algol.h as follows:

struct dv
{     /* array dope vector */
      void *base;
      /* address of the first array element */
      int n;
      /* number of subscripts (1 <= n <= 9) */
      {  int lo;
         /* lower bound of subscript */
         int up;
         /* upper bound of subscript (if lo > up, the array is empty
            and in this case base is NULL) */
      }  d[9];
      /* subscript bounds for each dimension (actually d[n] is used) */

This allows you performing all necessary checks and obtain a pointer to
a[i,j] or x[j].

To return an integer value from foo_0 you need to return the value of
struct desc (declared in algol.h) which is the return value descriptor.

Thus, finally, the wrapper could look like follows:

struct desc foo_0 /* precompiled void procedure */
(     struct arg n_1 /* by value integer */,
      struct arg a_1 /* by name real array */,
      struct arg x_1 /* by name real array */
{  struct desc retv; 
   int n = get_int((global_dsa = n_1.arg2, 
      (*(struct desc (*)(void))n_1.arg1)()));
   struct dv *a = a_1.arg1;
   struct dv *x = x_1.arg1;
      ...prepare arguments and call C function...
    retv.lval = 0;
    retv.type = 0;
    retv.u.int_val = ...return value...;
    return retv;

To determine how formal parameters of an Algol 60 procedure can be
accessed/assigned, you may look at the output code produced by Marst.

Hope this helps.

Best regards,

Andrew Makhorin

reply via email to

[Prev in Thread] Current Thread [Next in Thread]