Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / gen / logen.c
1 /*     Loglan82 Compiler&Interpreter
2      Copyright (C) 1993 Institute of Informatics, University of Warsaw
3      Copyright (C)  1993, 1994 LITA, Pau
4      
5      This program is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published by
7      the Free Software Foundation; either version 2 of the License, or
8      (at your option) any later version.
9      
10      This program is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13      GNU General Public License for more details.
14      
15
16 =======================================================================
17 */
18
19 #include "glodefs.h"
20 #include <unistd.h>
21
22 #ifndef NO_PROTOTYPES
23
24 static void code(void);
25 static void putstmode(stmode,int *);
26 static void segments(void);
27
28 #else
29
30 static void code();
31 static void putstmode();
32 static void segments();
33
34 #endif
35
36 /* cas dodalem deklaracje zmiennej qcurr */
37 /* DO CELOW URUCHOMIENIOWYCH */
38 static address zmienna;
39 int qcurr;
40
41 static void putstmode(s,i) stmode s; int *i;{
42   (*i) &= 255 ; /* CLEAR LEFT BYTE */;
43   s  <<= 8 ;
44   (*i) |= s ;
45 }
46
47 void makeproclist(){
48    int p, len ;
49
50    len  =  0  ;
51    do
52    {
53      p  =  next() ;
54      if (p)
55      {
56        len ++ ;
57        if (p > 0)
58          proclist[ len ]  =  ipmem[ p-1 ] ;
59        else
60          proclist[ len ]  =  -ipmem[ -p-1 ] ;
61      }
62    } while ( ! ( (p == 0) || (len == MAXPROCLIST) )) ;
63    
64    if (p)
65      generror(PROCLTL) ;
66    
67      tuple[ qcurr ].arg[ 1 ]  =  len ;
68 }
69
70
71
72
73 static void segments(){
74  /* COMPLETES THE QUADRUPLES SEGMENT */
75  /* LABEL 100 ; EXIT AT END-MARKER */
76         bool stop ; /* segment completed */
77 /*!!*/   static int op    ; /* opcode */ /* static for debugging purposes */
78 /*!!*/   static  int a, b  ; /* first and second argument */
79      int trck2 ;
80 /*     int n ; */
81      quadruple * curr ; /* gsg for PASCAL WITH translation */
82
83  while (TRUE)  /* EXIT ONLY AT END-MARKER */
84  {
85    stop = FALSE ; /* COMPLETE THE SEGMENT */
86    qcurr = 1 ;
87    do      /*  WITH tuple[ qcurr ] DO BEGIN */
88    { curr = tuple + qcurr ; /* gsg PASCAL WITH statement translation */
89
90      op = next() ;  /* Fetch operator */
91
92 #if (TALK > 15)
93      printf("                                op = %d\n", op) ;
94 #endif
95 if( op==210 || op==211 ){ printf("|opcode %d|\n",op); getchar(); }
96     if ( (op <= 194) || (op >= 220) )
97     {
98
99       stop = ( ((172 <= op) && (op <= 176)) || ((178 <= op) && (op <= 227)) ) ;
100       /* op in  [172..176, 178..227] */
101       curr->opcode = op ;
102       /* Now fetch arguments */
103       switch (opdescr[ op ])
104       {
105         case 0 : break ;
106
107         case 1 :
108         case 2 :
109         case 8 : curr->arg[ 1 ] = next() ;
110                  break ;
111
112         case 3 :
113         case 5 :
114         case 9 :
115        case 11 :
116        case 15 : curr->arg[ 1 ] = next() ; 
117                  curr->arg[ 2 ] = next() ;
118                  break ;
119
120         case 4 :
121         case 6 :
122         case 7 :
123         case 10 :
124         case 12 :
125         case 13 :
126         case 14 : curr->arg[ 1 ] = next() ; 
127                   curr->arg[ 2 ] = next() ; 
128                   curr->arg[ 3 ] = next() ;
129                   break ;
130       
131       } /* switch */
132  
133      if ( ((223 <= op) && (op <= 225)) || (op == 227) ) /*op in [223..225,227]*/
134         makeproclist() ;
135       qcurr ++ ;
136     }
137     else  /* op in 195..219 */
138       if (op == 200)
139         goto label100 ; /* end-marker */
140       else /* SPECIAL CARE OPCODES */
141       {
142         a = next() ;
143         ipmem[ a + 2 ] = 0 ;
144         if ((op < 201 ) || (op > 204))
145         { 
146           b = next() ; 
147           ipmem[ a+1 ] = b ;
148         }
149         else
150           ipmem[ a+1 ] = 0 ;
151                /* SET DEFAULT VALUES */
152                /*SLOCAL = FALSE; SLIVE = FALSE; SMODE = TEMPVAR; SAP = APINT; */
153         putslocal(FALSE,notrick) ;
154         putslive(FALSE,notrick) ;
155         putstmode(TEMPVAR, &notrick) ; 
156         putsap(APINT,notrick) ;
157         
158         switch (op)
159         {       /* TEMPORARY VARIABLES */
160                case 201 : break ;
161
162                case 202 : putsap(APFMTYPE,notrick) ; /* == apreal */
163                           break ;
164
165                case 203 : putsap(APFMPROC,notrick) ;
166                           break ;
167
168                case 204 :  /* reference */
169                            putsap(APVIRT,notrick) ;
170                            putslocal(TRUE,notrick) ;
171                            break ;
172
173                /* declared variables */
174                case 205 : putstmode(VARGLOB, &notrick) ;
175                           putsap(apet(b),notrick) ;
176                           putslive(TRUE,notrick) ;
177                           break ;
178
179                case 206 : putstmode(VARMID, &notrick) ;  
180                           putsap(apet(b),notrick) ;
181                           putslive(TRUE,notrick) ;
182                           break ;
183  
184                case 207 : putstmode(VARLOC, &notrick) ;  
185                           putsap(apet(b),notrick) ;
186                           putslive(TRUE,notrick) ;
187                           break ;
188  
189                /* real or integer constant */
190                case 197 : putstmode(REALCONST, &notrick) ; 
191                           putsap(APREAL,notrick) ;
192                           break ;
193
194                case 198 :
195                case 199 : putstmode(INTCONST, &notrick) ;
196                           break ;
197
198                /* temporary but live */
199                 case 195 :
200                 case 208 : putslocal(TRUE,notrick) ;
201                            if (op==195)
202                            { /* move&save */
203                              trck2   = ipmem[ b ] ;
204                              putsap(sap(trck2),notrick) ;
205                            }
206                           else /* live temporary */
207                             putslive(TRUE,notrick) ;
208                           curr->opcode =  60  ; /* #limove */
209                            /* proper opcode will be chosen further */
210                           curr->arg[ 1 ] = a ;
211                           curr->arg[ 2 ] = b ;
212                           qcurr ++ ;
213                           break ;
214         } /* switch */
215
216         ipmem[ a ] = notrick ;
217       } /* SPECIAL CARE OPCODES */
218    } while ( ! (stop || (qcurr > QMAX)) ) ;
219
220    qlast = qcurr - 1 ;
221    if (! stop) 
222      generror(STSEQTL) ;
223    back() ; /* establish 'next-use' information */
224    gen() ;
225 } /* while true */
226  label100: ; /* end-marker : all has been done */
227
228 }
229
230
231
232 static void code(){
233      /* TRANSFORMS L-CODE TO L'-CODE BY REDUCTION OF NUMBER OF OPCODES */
234      /* ALLOCATES TEMPORARY VARIABLES                                    */
235
236   /* INSERT 'NONE' INTO THE SYMBOL TABLE */
237   /*cdsw&ail  NONE = LMEM-3 ;  */
238    none  =  addrnone ;
239  /* WITH TRICK.STI DO {  */ /* CTRP
240                  SAP = APVIRT ;
241                    SMODE = REALCONST ;
242                    SLOCAL = TRUE ;
243                    SLIVE = TRUE ;
244                    } ;  */
245   putsap(APVIRT,notrick) ;
246   putstmode(REALCONST,&notrick) ;
247   putslocal(TRUE,notrick) ;
248   putslive(TRUE,notrick) ;
249   ipmem [ none   ]  =  notrick ;
250   ipmem [ none+1 ]  =  0 ; /* --> m [realbase] */
251   ipmem [ none+2 ]  =  0 ;
252
253
254  /* CLEAR THE DICTIONARY OF LABELS */
255
256 /*  memset(m + fre, (char) 0, (MEMLIMIT - fre + 1) * sizeof(address)) ;  */
257    for(zmienna = fre; zmienna <= MEMLIMIT; zmienna ++)
258      m[zmienna] = 0 ;
259   /* zerowanie pamieci */
260   /* n = MEMLIMIT ;*/
261
262   segments() ;
263
264  /* END OF CODE PREPARING */
265 }
266
267  
268 void main(argc,argv) int argc; char *argv[];{
269
270 /*
271   log = fopen("gen.log", "w") ;
272   if (log == NULL)
273     printf("cannot open dump file\n") ;
274 */
275   base = 0 ;
276
277   m = (address *) calloc(sizeof(address), MEMLIMIT + 1) ;
278
279    puts("") ;
280    puts(" LOGLAN-82  Compiler  Version 4.00") ;
281    puts(" January 10, 1993") ;
282    puts(" (C)Copyright  Institute of Informatics, University of Warsaw") ;
283    puts(" (C)Copyleft   LITA Universite de Pau");
284    puts("\n Pass Two\n") ; fflush(stdout);
285    if(argc < 2){ printf("Usage : %s filename\n",argv[0]); exit(8); }
286 #if (TALK >= 1)
287    puts("Setting files...") ; fflush(stdout);
288 #endif
289    setfiles(argv[1]) ;
290   fre  =  2 ;                      /* SKIP TWO WORDS RESERVED FOR DUMMY VIRT. */
291   m[fre++]  =  0 ; /* dsw*//* free == currfile */
292   m[fre++]  =  0 ; /* place for file virtual address */ /*dsw*/
293   strings  =  fre ;                    /* START STRING AREA */
294 #if (TALK >= 1)
295   puts("Putting strings...") ; fflush(stdout);
296 #endif
297   putstrings() ;                         /* WRITE STRINGS INTO MEMORY */
298   realbase  =  fre ;                     /* BASE FOR REAL CONSTANTS */
299 #if (TALK >= 1)
300   puts("Initiating...") ; fflush(stdout);
301 #endif
302   initiate() ;                           /* READ IPMEM AND OTHER VARIABLES */
303 #if (TALK >= 3)
304   {
305      long seek=ftell(lfile);
306      dump_lcode(argv[1]);
307      fseek(lfile,seek,SEEK_SET);
308   }
309 #endif
310 #if (TALK >= 1)
311   puts("Putting reals...") ; fflush(stdout);
312 #endif
313   putreals() ;                           /* WRITE REAL CONSTANTS INTO MEMORY */
314 #if (TALK >= 1)
315   puts("Generating prototypes...") ; fflush(stdout);
316 #endif
317   genprot() ;
318   /* PROTOTYPES ARE NUMBERED MAINBLOCK..LASTPROT */
319  
320 temporary  =  base+fre ;
321 fre  +=  MAXCOMTEMP + 1 ;
322
323 /* mb removed some unimportant comments to improve readability ; cf text2.gen */
324
325 #if (TALK >= 1)
326  puts("Outputing...") ; fflush(stdout);
327 #endif
328 #if (TALK >= 70)
329  for(zmienna = 0; zmienna < fre ; zmienna ++)
330    printf("M DUMP WORD # %lu VALUE %lu\n",
331           (unsigned long int)zmienna,(unsigned long int)(m[zmienna]));
332 #endif
333
334  out() ;                                   /*CBC*/
335
336
337 /* fre == 0 */
338
339 #if (TALK >= 1)
340  puts("Code preparation...") ; fflush(stdout);
341 #endif
342  code() ; /* CODE PREPARING */
343
344
345 #if (TALK >= 1)
346  puts("Putting debug info...") ; fflush(stdout);
347 #endif
348
349 /*
350  ts3(argv[1]);
351 */
352
353 #if (TALK >= 1)
354  puts("Putting prototypes...") ; fflush(stdout);
355 #endif
356
357  outprot() ; /* PUT PROTOTYPES ONTO THE FILE */
358
359 /* fclose(log) ;*/
360 /* *((int *)0xccL) = 0x1445 ;*/
361
362 #if (TALK >= 1)
363  puts("Generation ok.") ; fflush(stdout);
364 #endif
365
366 }
367
368