PIPS
genSML.c
Go to the documentation of this file.
1 /*
2 
3  $Id: genSML.c 1357 2016-03-02 08:18:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of NewGen.
8 
9  NewGen is free software: you can redistribute it and/or modify it under the
10  terms of the GNU General Public License as published by the Free Software
11  Foundation, either version 3 of the License, or any later version.
12 
13  NewGen is distributed in the hope that it will be useful, but WITHOUT ANY
14  WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16  License for more details.
17 
18  You should have received a copy of the GNU General Public License along with
19  NewGen. If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 #ifdef HAVE_CONFIG_H
23  #include "config.h"
24 #endif
25 
26 #include <stdio.h>
27 #include <ctype.h>
28 #include <string.h>
29 #include "newgen_include.h"
30 #include "genC.h"
31 
32 #undef GEN_HEADER
33 /* For simplicity, the tabulation slot is always here */
34 #define GEN_HEADER 2
35 
36 #define IS_NON_INLINABLE_BASIS(f) (strcmp(f,"chunk")==0)
37 #define UPPER(c) ((islower( c )) ? toupper( c ) : c )
38 #define TYPE(bp) (bp-Domains-Number_imports-Current_start)
39 
40 #define OR_TAG_OFFSET 2
41 
42 static char start[ 1024 ] ;
43 
45 
47 
48 /* GEN_SIZE returns the size (in gen_chunks) of an object of type defined by
49  the BP type. */
50 
51 int
52 gen_size( bp )
53 struct gen_binding *bp ;
54 {
55  int overhead = GEN_HEADER ;
56 
57  switch( bp->domain->ba.type ) {
58  case BASIS_DT:
59  case ARRAY_DT:
60  case LIST_DT:
61  case SET_DT:
62  return( overhead + 1 ) ;
63  case CONSTRUCTED_DT:
64  if( bp->domain->co.op == OR_OP )
65  return( overhead + 2 ) ;
66  else {
67  int size ;
68  struct domainlist *dlp = bp->domain->co.components ;
69 
70  for( size=0 ; dlp != NULL ; dlp=dlp->cdr, size++ )
71  ;
72  return( overhead + size ) ;
73  }
74  default:
75  fatal( "gen_size: Unknown type %s\n", i2a( bp->domain->ba.type )) ;
76  /*NOTREACHED*/
77  }
78 }
79 
80 /* PRIMITIVE_FIELD returns the appropriate field to acces an object in BP.
81  Note how inlined types are managed (see genC.h comments). */
82 
83 static char *
85  union domain *dp ;
86 {
87  static char buffer[ 1024 ];
88 
89  switch( dp->ba.type ) {
90  case BASIS_DT: {
91  struct gen_binding *bp = dp->ba.constructand ;
92 
93  if( IS_INLINABLE( bp )) {
94  sprintf( buffer, "%s", bp->name ) ;
95  }
96  else if( IS_EXTERNAL( bp )) {
97  fprintf(stderr, "primitive_field not implemented\n");
98  }
99  else sprintf( buffer, "chunk" ) ;
100  break ;
101  }
102  case LIST_DT:
103  sprintf( buffer, "list" ) ;
104  break ;
105  case SET_DT:
106  sprintf( buffer, "set" ) ;
107  break ;
108  case ARRAY_DT:
109  sprintf( buffer, "vector" ) ;
110  break ;
111  default:
112  fatal( "primitive_field: Unknown type %s\n", i2a( dp->ba.type )) ;
113  /*NOTREACHED*/
114  }
115  return( buffer ) ;
116 }
117 
118 /* GEN_MEMBER generates a member access functions for domain DP and
119  OFFSET. NAME is the domain of the defined domain. */
120 
121 static void
123 char *name ;
124 union domain *dp ;
125 int offset ;
126 {
127  char *field = primitive_field( dp ) ;
128 
129  if( dp->ba.type == BASIS_DT &&
130  strcmp( dp->ba.constructand->name, UNIT_TYPE_NAME ) == 0 )
131  return ;
132 
133  (void) printf( "fun %s_%s (vector node) = ", name, dp->ba.constructor ) ;
134  (void) printf("case (sub (node,%d)) of (%s x) => x;\n",
135  offset, field) ;
136 }
137 
138 /* GEN_ARG returns the constructor name of domain DP. */
139 
140 static char *
141 gen_arg( dp )
142 union domain *dp ;
143 {
144  return( (dp->ba.type == BASIS_DT) ? dp->ba.constructor :
145  (dp->ba.type == LIST_DT) ? dp->li.constructor :
146  (dp->ba.type == SET_DT) ? dp->se.constructor :
147  (dp->ba.type == ARRAY_DT) ? dp->ar.constructor :
148  (fatal( "gen_arg: Unknown type %s\n", i2a( dp->ba.type )),
149  (char *)NULL) ) ;
150 }
151 
152 /* GEN_ARGS returns a comma-separated list of constructor names for the list
153  of domains DLP. */
154 
155 static char *
156 gen_args( dlp )
157 struct domainlist *dlp ;
158 {
159  static char buffer[ 1024 ] ;
160 
161  for( sprintf( buffer, "" ) ; dlp->cdr != NULL ; dlp = dlp->cdr ) {
162  strcat( buffer, gen_arg( dlp->domain )) ;
163  strcat( buffer, ", " ) ;
164  }
165  strcat( buffer, gen_arg( dlp->domain )) ;
166  return( buffer ) ;
167 }
168 
169 static char *
170 gen_update_arg( dp, index )
171 struct domain *dp ;
172 int index ;
173 {
174  static char arg[ 1024 ] ;
175 
176  sprintf(arg, "update(gen_v, %d, %s %s);", index,
177  primitive_field(dp), gen_arg(dp));
178  return(arg) ;
179 }
180 
181 /* GEN_UPDATE_ARGS returns a comma-separated list of constructor names
182 for the list of domains DLP. */
183 
184 static char *
186 struct domainlist *dlp ;
187 {
188  static char buffer[ 1024 ] ;
189  int index = GEN_HEADER ;
190 
191  for( sprintf(buffer, "") ; dlp->cdr!=NULL ; dlp=dlp->cdr, index++ ) {
192  strcat(buffer, gen_update_arg(dlp->domain, index)) ;
193  }
194  strcat(buffer, gen_update_arg(dlp->domain, index)) ;
195  return( buffer ) ;
196 }
197 
198 /* GEN_MAKE generates the gen_alloc call for gen_bindings BD with SIZE user
199  members and ARGS as list of arguments. */
200 
201 static void
202 gen_make( bp, size, args, updated_args, option_name )
203 struct gen_binding *bp ;
204 int size ;
205 char *args, *updated_args, *option_name ;
206 {
207  extern int printf();
208 
209  (void) printf("fun make_%s%s%s (%s) =", bp->name,
210  (strcmp(option_name, "") == 0 ? "" : "_"), option_name,
211  args) ;
212  (void) printf(" let val gen_v = array(%d+%d, undefined) in\n",
213  GEN_HEADER, size);
214  (void) printf(" update(gen_v, 0, int (%s+%d));\n", start, TYPE(bp)) ;
215  (void) printf(" %s\n", updated_args);
216 
217  if( IS_TABULATED( bp )) {
218  fprintf(stderr, "enter_tabulated not called\n");
219  }
220  (void) printf(" vector gen_v end:%s;\n", bp->name) ;
221 
222  if( IS_TABULATED( bp )) {
223  printf( "val %s_domain = %s+%d;\n", bp->name, start, TYPE( bp )) ;
224  }
225 }
226 
227 /* GEN_AND generates the manipulation functions for an AND type BP. */
228 
229 void
230 gen_and( bp )
231  struct gen_binding *bp ;
232 {
233  union domain *dom = bp->domain ;
234  struct domainlist *dlp ;
235  int size ;
236 
237  gen_make(bp, gen_size(bp)-GEN_HEADER,
238  gen_args(dom->co.components),
240  "") ;
241  size = GEN_HEADER ;
242 
243  for( dlp=dom->co.components ; dlp != NULL ; dlp=dlp->cdr )
244  gen_member( bp->name, dlp->domain, size++ ) ;
245 }
246 
247 /* GEN_OR generates the manipulation function for an OR_OP type BP. Note
248  that for a UNIT_TYPE_NAME, no access function is defined since the value is
249  meaningless. */
250 
251 void
252 gen_or( bp )
253 struct gen_binding *bp ;
254 {
255  extern int printf();
256  char *name = bp->name ;
257  union domain *dom = bp->domain ;
258  struct domainlist *dlp ;
259  int offset ;
260 
261  (void) printf("fun %s_tag (vector or) = ", name ) ;
262  (void) printf("case (sub (or,%d)) of (int x) => x;\n",
263  GEN_HEADER) ;
264 
265  for( dlp=dom->co.components,offset=dom->co.first ;
266  dlp != NULL ;
267  dlp=dlp->cdr, offset++ ) {
268  union domain *dp = dlp->domain ;
269  static char args[ 1024 ] ;
270  static char updated_args[ 1024 ] ;
271 
272  sprintf(args, "tag, %s", dp->ba.constructor ) ;
273  strcpy(updated_args, "update(gen_v, 2, int tag);") ;
274  gen_make(bp, 2,args ,
275  strcat(updated_args, gen_update_arg(dp, 3)),
276  dp->ba.constructor);
277  (void) printf("val is_%s_%s = %d;\n",
278  name, dp->ba.constructor, offset ) ;
279  (void) printf("fun %s_%s_p or = ((%s_tag or)=is_%s_%s);\n",
280  name, dp->ba.constructor, name,
281  name, dp->ba.constructor ) ;
282  gen_member( name, dp, OR_TAG_OFFSET ) ;
283  }
284 }
285 
286 /* GEN_LIST defines the manipulation functions for a list type BP. */
287 
288 void
289 gen_list( bp )
290 struct gen_binding *bp ;
291 {
292  extern int printf();
293  char *name = bp->name ;
294  union domain *dom = bp->domain ;
295  int data = GEN_HEADER ;
296 
297  gen_make(bp, 1, dom->li.constructor, gen_update_arg(dom, 2), "") ;
298  (void) printf("fun %s_%s (vector li) = ", name, dom->li.constructor ) ;
299  (void) printf("(sub (li,%d));\n", data) ;
300 }
301 
302 /* GEN_SET defines the manipulation functions for a set type BP. */
303 
304 void
305 gen_set( bp )
306 struct gen_binding *bp ;
307 {
308  fprintf( stderr, "Set: too be implemented\n" ) ;
309 }
310 
311 /* GEN_ARRAY defines the manipulation functions for an array type BP. */
312 
313 void
315  struct gen_binding *bp ;
316 {
317  extern int printf();
318  char *name = bp->name ;
319  union domain *dom = bp->domain ;
320  int data = GEN_HEADER ;
321 
322  gen_make(bp, 1, dom->ar.constructor, gen_update_arg(dom, 2), "");
323  (void) printf("fun %s_%s (vector ar) = ", name, dom->ar.constructor ) ;
324  (void) printf("(sub (ar,%d));\n", data) ;
325 }
326 
327 /* GEN_EXTERNAL defines the acces functions for an external type BP.
328  The TYPEDEF has to be added by the user, but should be castable to a
329  string (char *). */
330 
331 void
333 struct gen_binding *bp ;
334 {
335  fprintf( stderr, "External: too be implemented\n" ) ;
336 }
337 
338 /* GEN_DOMAIN generates the manipulation functions for a type BP. This is
339  manily a dispatching function. */
340 
341 void
343 struct gen_binding *bp ;
344 {
345  extern int printf();
346  union domain *dp = bp->domain ;
347  char *s = bp->name ;
348 
349  if( !IS_EXTERNAL( bp )) {
350  (void) printf( "type %s = chunk;\n", bp->name ) ;
351  (void) printf( "val %s_undefined = (undefined:%s);\n",
352  bp->name, bp->name ) ;
353  (void) printf( "fun write_%s fd obj = gen_write fd obj;\n",
354  bp->name ) ;
355  (void) printf( "fun read_%s fd = (gen_read fd):%s;\n",
356  bp->name, bp->name ) ;
357  }
358  switch( dp->ba.type ) {
359  case CONSTRUCTED_DT:
360  switch( dp->co.op ) {
361  case AND_OP:
362  gen_and( bp ) ;
363  break ;
364  case OR_OP:
365  gen_or( bp ) ;
366  break ;
367  default:
368  fatal( "gen_domain: Unknown constructed %s\n", i2a( dp->co.op )) ;
369  }
370  break ;
371  case LIST_DT:
372  gen_list( bp ) ;
373  break ;
374  case SET_DT:
375  gen_set( bp ) ;
376  break ;
377  case ARRAY_DT:
378  gen_array( bp ) ;
379  break ;
380  case EXTERNAL_DT:
381  gen_external( bp ) ;
382  break ;
383  default:
384  fatal( "gen_domain: Unknown type %s\n", i2a( dp->ba.type )) ;
385  }
386 }
387 
388 /* GENCODE generates the code necessary to manipulate every internal and
389  non-inlinable type in the Domains table. */
390 
391 void
392 gencode( file )
393 char *file ;
394 {
395  struct gen_binding *bp = Domains ;
396 
397  sprintf( start, "gen_%s_start", file ) ;
398 
399  for( ; bp < &Domains[ MAX_DOMAIN ] ; bp++ ) {
400  if(bp->name == NULL || IS_INLINABLE( bp ) || IS_IMPORT( bp ) ||
401  bp == Tabulated_bp )
402  continue ;
403 
404  gen_domain( bp ) ;
405  }
406 }
407 
static Value offset
Definition: translation.c:283
static char * gen_arg(dp)
GEN_ARG returns the constructor name of domain DP.
Definition: genSML.c:141
int gen_size(bp)
GEN_SIZE returns the size (in gen_chunks) of an object of type defined by the BP type.
Definition: genSML.c:52
static char * primitive_field(dp)
PRIMITIVE_FIELD returns the appropriate field to acces an object in BP.
Definition: genSML.c:84
static char start[1024]
Definition: genSML.c:42
#define TYPE(bp)
Definition: genSML.c:38
void gen_external(bp)
GEN_EXTERNAL defines the acces functions for an external type BP.
Definition: genSML.c:332
#define GEN_HEADER
For simplicity, the tabulation slot is always here.
Definition: genSML.c:34
static void gen_make(bp, size, char *args, char *updated_args, char *option_name)
GEN_MAKE generates the gen_alloc call for gen_bindings BD with SIZE user members and ARGS as list of ...
Definition: genSML.c:202
static void gen_member(name, dp, offset)
GEN_MEMBER generates a member access functions for domain DP and OFFSET.
Definition: genSML.c:122
struct gen_binding * Tabulated_bp
Definition: genSML.c:46
void gen_list(bp)
GEN_LIST defines the manipulation functions for a list type BP.
Definition: genSML.c:289
void gen_or(bp)
GEN_OR generates the manipulation function for an OR_OP type BP.
Definition: genSML.c:252
#define OR_TAG_OFFSET
Definition: genSML.c:40
void gen_and(bp)
GEN_AND generates the manipulation functions for an AND type BP.
Definition: genSML.c:230
void gen_array(bp)
GEN_ARRAY defines the manipulation functions for an array type BP.
Definition: genSML.c:314
void gencode(file)
GENCODE generates the code necessary to manipulate every internal and non-inlinable type in the Domai...
Definition: genSML.c:392
static char * gen_update_args(dlp)
GEN_UPDATE_ARGS returns a comma-separated list of constructor names for the list of domains DLP.
Definition: genSML.c:185
void gen_set(bp)
GEN_SET defines the manipulation functions for a set type BP.
Definition: genSML.c:305
static char * gen_update_arg(dp, index)
Definition: genSML.c:170
int Read_spec_mode
extern int Current_first ;
Definition: genSML.c:44
void gen_domain(bp)
GEN_DOMAIN generates the manipulation functions for a type BP.
Definition: genSML.c:342
static char * gen_args(dlp)
GEN_ARGS returns a comma-separated list of constructor names for the list of domains DLP.
Definition: genSML.c:156
struct gen_binding Domains[MAX_DOMAIN]
in build.c
Definition: genspec_yacc.c:114
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121
@ OR_OP
@ AND_OP
#define IS_EXTERNAL(bp)
#define IS_INLINABLE(bp)
Different kinds of BINDING structure pointers.
@ EXTERNAL_DT
@ SET_DT
@ ARRAY_DT
@ LIST_DT
@ BASIS_DT
@ CONSTRUCTED_DT
#define MAX_DOMAIN
MAX_DOMAIN is the maximum number of entries in the DOMAINS table.
void fatal(char *,...)
#define IS_IMPORT(bp)
#define IS_TABULATED(bp)
#define UNIT_TYPE_NAME
The UNIT_TYPE_NAME is the used to type expressions which only perform side-effects.
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
int printf()
return(s1)
static string buffer
Definition: string.c:113
union domain * domain
A DOMAIN union describes the structure of a user type.
char * constructor
enum domain_operator op
struct domainlist * components
struct domain::@7 co
struct domain::@5 se
int type
EXTERNAL.
struct domain::@3 ba
struct domain::@4 li
struct gen_binding * constructand
struct domain::@6 ar