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

One method for implementing real numbers in Centaur




Hello,
     this is a summary of the method I used to implement some real
number arithmetic in a language with semantics defined in Typol
(Thanks to Thierry Despeyroux for his help with this). 

I will use a real example to illustrate:

 I want to implement a function to add a real number to an integer.
 Mu Prolog can handle integer arithmetic directly but not real 
 arithmetic. So the actual addition must be performed by a routine
 that can be called by mu-prolog that is written in another language
 (I chose Le-lisp because the appropriate predicates already exist).

 Mu Prolog has only pointers, integers and strings as base types
 so we must use strings for real numbers. The metal code for 
 the 'int' and 'real' abstract syntax objects is:
              .
              .
    int -> implemented as INTEGER;
    real -> implemented as STRING;

 
 The typol rule to handle the addition of real and integer would 
 resemble:

    import add_real_int(_,_,_) from func;
              .
              .
    add_real_int(AV, BV, CV)
    ------------------------
    (plus(), real AV, int BV -> real CV);

  where the file 'func.pg' contains the routine add_real_int and 
  plus() is a symbol in the abstract synatax of the source language.
  The variable CV will eventually contain the result.

  The code for the routine add_real_int() in the func.pg file (in
  the same directory) is:


    $func$add_real_int(A,B,C) :- getsym('l-add-real-int',F),
     pusharg(3,A), pusharg(1,B), lispcall(3,2,F,C).


  Where, getsym() is a built-in predicate to find the address of 
  the lisp routine corresponding to its first argument and place
  it in the second argument. 

  pusharg() places its second argument onto the lisp call stack. The 
  first argument is the type of its second argument (1 is integer, 
  3 is string). 

  lispcall() calls the lisp routine pointed to by its third argument
  with the number of arguments specified by its second argument.
  It returns a value with the type of its first argument and it
  places the value in the variable which is its last argument.
  A full description of these routines is contained in the
  Prolog/Lisp section near the end of the typol manual (section 6.4).

  Now we have to write the lisp routine. It has to be visible to 
  centaur during interpretation of the source language. It can be
  loaded in manually or loaded in when the source language
  environment is loaded. I chose to load it when the environment is
  loaded so I placed it in my <language>.env file. It contains...


      (defun strnum (x)(stratom (slen x) x ()))      

      (defun l-add-real-int (x y)
             (string (+ (strnum x) y)))


  where stratom, slen and string are built-in conversion functions
  in Le-lisp. stratom will convert a string of the length of its 
  first argument which resides in its second argument to a lisp atom
  (the third argument is for specifying a specific type for the
   result, not needed in this case). slen returns the length of its
   input argument. And string() converts a number back to a string.

  Make sure that your routine names haven't been prefixed (packaged)
  by testing them at the centaur prompt.

  The typol rule should now return a string with the correct 
  result of the addition.

  Hope this may be of some use.. Write back if theres any questions.

  Brad Alexander.