next up previous
Next: About this document ...

NewGen

Pierre Jouvelot

CRI, Ecole des Mines (France)
LCS, MIT (U.S.A.)

Conférence GRECO de Programmation  
Paris, 28 Novembre 1991

$\copyright$ Pierre Jouvelot (1991)

Qu'est-ce que NewGen

NewGen en résumé

Plan

Problématique

Interopérabilité

Atouts

Langage de Description de Domaines

Fonctions de Manipulation:
Création

Fonctions de Manipulation:
Accès

Fonctions de Manipulation:
Modification

Fonctions de Manipulation:
Opérations I/O

Fonctions de Manipulation:
Libération

Bibliothèques

Bibliothèque:
Listes

Bibliothèque:
Ensembles

Bibliothèque:
Tables de hachage

Un Premier Exemple

Frontal pour SIMPLE

%{

#include <stdio.h>       /* Unix standard IO */
#include <string.h>      /* String managt. */
#include "genC.h"        /* Newgen basic 
                            C library */
#include "expression.h"  /* Newgen-generated 
                            header files */ 

expression Top ;
%}

%token LP RP 
%token LET 

%term INT
%term STRING

%union {
    expression expression ;
    let let ;
    list list ;
    identifier identifier ;
    string string ;
}

%type <expression> Axiom Expression
%type <let> Let
%type <identifier> Identifier

%type <list> Bindings
%type <string> String 

%% 
Axiom   : Expression {
            Top = $1 ;
        }
        ;

Expression  
        : INT {
            $$ = make_expression(
                 is_expression_constant, 
                 atoi( yytext )) ;
        } 
        | Identifier {
            $$ = make_expression( 
                 is_expression_identifier,$1);
        } 
        | LP String Expression Expression RP {
            binary b = 
            make_binary( $2, $3, $4 ) ; 
               
            $$ = make_expression(
                 is_expression_binary, b );
        }

        | Let {
            $$ = make_expression( 
                 is_expression_let, $1 ) ;
        } 
        ; 
 
Let     : LP LET LP Bindings RP Expression RP {
            $$ = make_let( $4, $6 ) ;
        } 
        ; 
 
Bindings   
        : {
            $$ = NIL ;
        } 
        | Bindings LP String Expression RP {
            $$ = CONS( BINDING,
                       make_binding( $3, $4 ), 
                       $1 ) ;
        } 
        ; 
 
Identifier  
        : String {
            $$ = make_identifier( $1 ) ;
        }
        ;

String  : STRING {
            $$ = strdup( yytext ) ;
        }
        ;
%%

Commande newgen

#include <stdio.h>       
#include "genC.h"        
#include "expression.h"  

expression Top ; 


main() 
{ 
    gen_read_spec( "expression.spec", 
                   (char*) NULL) ; 
    yyparse() ; 
    fprintf( stdout, "%d\n", 
             constant_fold( Top )) ; 
    free_expression( Top ) ;
}

int
constant_fold( e )
expression e ;
{
    int value ;
    tag t ;

    switch( t = expression_tag( e )) {
    case is_expression_constant:
        value = expression_constant( e ) ;      
        break ;
    case is_expression_binary:
        binary b = expression_binary( e ) ;
        int lhs = constant_fold(binary_lhs(b));
        int rhs = constant_fold(binary_rhs(b));

        value = 
           eval_primitive( binary_operator(b), 
                           lhs, rhs ) ;
        break ;
    default:
        fprintf( stderr, 
                 "Unimplemented %d\n",
                  t ) ;
        exit( 1 ) ;
    }
    return( value ) ;
}

int
eval_primitive( op, lhs, rhs )
char *op ;
int lhs, rhs ;
{
    if( strcmp( op, "+" ) == 0 ) 
        return( lhs+rhs ) ;
    if( strcmp( op, "-" ) == 0 ) 
        return( lhs-rhs ) ;
    if( strcmp( op, "*" ) == 0 )
        return( lhs*rhs ) ;
    if( strcmp( op, "/" ) == 0 )
        return( lhs/rhs ) ;

    fprintf( stderr, "Primitive %s unknown\n", 
             op ) ;
    exit( 1 ) ;
}

Aspects Avancés
Tabulation

Aspects Avancés
Importation

Aspects Avancés
Externes

Retour sur l'exemple

NewGen et CommonLISP

Changements

Evaluateur pour SIMPLE

Top Level

(require "genLisplib")    ; Newgen basic 
                          ; Lisp library 
(require "identifier")    ; Newgen-generated 
                          ; header files 
(require "expression") 
 
(use-package '(:newgen 
               :identifier 
               :expression))

(defun test (&optional (file *standard-input*))
  "FILE contains the parser output."
  (gen-read-spec) 
  (let ((*standard-input* (open file))) 
    (eval-expression (read-expression) '())))

Boucle d'évaluation

(defun eval-expression (e env) 
  (gen-switch e 
    ((is-expression-constant c) c) 
    ((is-expression-identifier i) 
     (eval-identifier i env)) 
    ((is-expression-binary b) 
     (eval-binary b env))
    ((is-expression-let l) 
      (eval-let l env))))

(defun eval-identifier (i env) 
  (let ((var-val (assoc (identifier-name i) env 
                        :test #'string-equal))) 
    (if (null var-val) 
        (error "~%Unbound identifier ~S" 
               (identifier-name i)) 
        (cdr var-val))))

(defparameter operators 
  `((,"add" . ,\#'+) 
    (,"sub" . ,\#'-) 
    (,"times" . ,\#'*) 
    (,"cons" . ,\#'cons) 
    (,"eq" . ,\#'eq)))

(defun eval-binary (b env) 
  (let ((op (assoc (binary-operator b) 
                   operators 
                   :test #'string-equal))) 
    (if (null op) 
        (error "~\%Incorrect op code ~S" 
               (binary-operator b)) 
        (funcall 
           (cdr op) 
           (eval-expression (binary-lhs b) 
                            env) 
           (eval-expression (binary-rhs b) 
                            env)))))
 
(defun eval-let (l env) 
  (let ((new-env
           (mapcar 
               #'(lambda (b) 
                    `(,(binding-name b) . 
                      ,(eval-expression
                          (binding-value b) 
                          env))) 
               (let-bindings l)))) 
    (eval-expression (let-expression l) 
                     (append new-env env))))

Aspects avancés
Exemples

(defun gensym () 
  "Generate a brand new identifier."
  (do ((i 0 (+ i 1))) 
      ((gen-find-tabulated 
           (format nil "gensym-~D" i)
           identifier-domain)
       (make-identifier 
           :name (format nil "gensym-~D"
                         i)))))

Aspects de l'implémentation

PIPS: Un exemple ``vraie grandeur''

Autres systèmes

Conclusion




next up previous
Next: About this document ...
Fabien COELHO 2003-04-29