Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / cint.c
1 /*     Loglan82 Compiler&Interpreter\r
2      Copyright (C) 1993 Institute of Informatics, University of Warsaw\r
3      Copyright (C)  1993, 1994 LITA, Pau\r
4      \r
5      This program is free software; you can redistribute it and/or modify\r
6      it under the terms of the GNU General Public License as published by\r
7      the Free Software Foundation; either version 2 of the License, or\r
8      (at your option) any later version.\r
9      \r
10      This program is distributed in the hope that it will be useful,\r
11      but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13      GNU General Public License for more details.\r
14      \r
15              You should have received a copy of the GNU General Public License\r
16              along with this program; if not, write to the Free Software\r
17              Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
18 \r
19  contacts:  Andrzej.Salwicki@univ-pau.fr\r
20 \r
21 or             Andrzej Salwicki\r
22                 LITA   Departement d'Informatique\r
23                 Universite de Pau\r
24                 Avenue de l'Universite\r
25                 64000 Pau   FRANCE\r
26                  tel.  ++33 59923154    fax. ++33 59841696\r
27 \r
28 =======================================================================\r
29 */\r
30 \r
31 #include "depend.h"\r
32 #include "genint.h"\r
33 #include "int.h"\r
34 #include "process.h"\r
35 #include "intproto.h"\r
36 \r
37 #if DLINK\r
38 #include "dlink.h"\r
39 #elif TCPIP\r
40 #include "tcpip.h"\r
41 #endif\r
42 \r
43 \r
44 /* IIUW LOGLAN-82 Executor                                            */\r
45 /* Written in PASCAL by P.Gburzynski and A.Litwiniuk.                 */\r
46 /* Modified by J.Findeisen, T.Przytycka, D.Szczepanska, B.Ciesielski. */\r
47 /* Hand translated to C by B. Ciesielski.                             */\r
48
49
50 #ifndef NO_PROTOTYPES
51 static void load(char *);
52 static void initiate(int,char **);
53 int main(int,char **);
54 #else
55 static void load();
56 static void initiate();
57 int main();
58 #endif
59 \r
60 \r
61 /* Macro to decode addressing modes : */\r
62 #define getargument(a, argnr)                                       \\r
63     switch (eop->args[ argnr ])                                     \\r
64     {                                                               \\r
65         case GLOBAL     : a = M[ ic++ ];             break;         \\r
66         case LOCAL      : a = c1+M[ ic++ ];          break;         \\r
67         case TEMPLOCAL  : a = c2+M[ ic++ ];          break;         \\r
68         case REMOTE     : a = M[ M[ ic+1 ] ]+M[ ic ];  ic+=2; break;\\r
69         case INDIRECT   : a = M[ M[ ic++ ] ];                 break;\\r
70         case IMMEDIATE  : a = ic++;                           break;\\r
71         case CONSTANT  : a = M[ ic++ ];                       break;\\r
72         case DOTACCESS : a = M[ display+M[ ic+1 ] ]+M[ ic ];  ic += 2; break;\\r
73         case NOARGUMENT : return;                          \\r
74     }\r
75 \r
76 \r
77 static void load(_filename)     /* Load code and prototypes from file */\r
78    char *_filename;\r
79 {\r
80     FILE *fp;\r
81     char *cp;\r
82     word n, left;\r
83     char filename[100]; /* should suffice on all systems */\r
84 \r
85     strcpy( filename, _filename );\r
86 \r
87     M = mallocate(memorysize+1);        /* allocate main memory array */\r
88     if (M == NULL) abend("Memory size too large (use /m option)\n");\r
89 \r
90     addext(filename, ".ccd");\r
91     if ((fp = fopen(filename, BINARYREAD)) == NULL)\r
92         abend("Cannot open .ccd file\n");\r
93 \r
94     ic = 0;              /* read static data and code */\r
95     left = memorysize+1;               /* from .ccd file */\r
96     do\r
97     {\r
98         if (left == 0) abend("Memory size too small (use /m option)\n");\r
99         n = min(IOBLOCK/sizeof(word), left);\r
100         n = fread((char *) &M[ ic ], sizeof(word), (int) n, fp);\r
101         ic += n;\r
102         left -= n;\r
103     } while (n != 0);      /* now ic = number of words read */\r
104 \r
105     fclose(fp);\r
106     /* Get various addresses passed by GENERATOR */\r
107     ipradr    = M[ ic-5 ];           /* primitive type desctriptions */\r
108     temporary = M[ ic-4 ];           /* global temporary variables */\r
109     strings   = M[ ic-3 ];           /* string constants */\r
110     lastprot  = M[ ic-2 ];           /* last prototype number */\r
111     freem     = M[ ic-1 ];           /* first free word in memory */\r
112 \r
113     /* Read prototypes from .pcd file */\r
114     addext(filename, ".pcd");\r
115     if ((fp = fopen(filename, BINARYREAD)) == NULL)\r
116         abend("Cannot open .pcd file\n");\r
117     for (n = MAINBLOCK;  n <= lastprot;  n++ )\r
118     {\r
119         cp = ballocate(sizeof(protdescr));\r
120         if (cp == NULL) abend("Memory size too large (use /m option)\n");\r
121         prototype[ n ] = (protdescr *) cp;\r
122         if (fread(cp, sizeof(protdescr), 1, fp) != 1)\r
123             abend("Cannot read .pcd file\n");\r
124     }\r
125     fclose(fp);\r
126 \r
127     /* Open trace file */\r
128     if (debug)\r
129     {\r
130         addext(filename, ".trd");\r
131         if ((tracefile = fopen(filename, "w")) == NULL)\r
132             abend("Cannot open .trd file\n");\r
133     }\r
134 } /* end load */\r
135 \r
136 \r
137 static void initiate(argc, argv)        /* Establish configuration parameters */\r
138 int argc;\r
139 char **argv;\r
140 {\r
141     long m;\r
142     int c;\r
143     char *filename=NULL;\r
144 \r
145     fprintf(stderr,"\n LOGLAN-82  Concurrent Executor  Version 4.51\n");\r
146     fprintf(stderr," January 21, 1993\n");\r
147     fprintf(stderr,\r
148             " (C) Copyright Institute of Informatics University of Warsaw\n");\r
149     fprintf(stderr," (C) Copyleft LITA  Universite de Pau\n");\r
150 #if DLINK\r
151     fprintf(stderr," D-LINK version 3.21\n\n");\r
152 #elif TCPIP\r
153     fprintf(stderr," TCPIP version 0.9\n\n");\r
154 #else\r
155     fprintf(stderr,"\n");\r
156 #endif\r
157     fflush(stderr);\r
158 \r
159 #if DLINK\r
160     ournode = net_logon(msginterrupt);\r
161     if (ournode >= 0)      /* network driver installed */\r
162         network = TRUE;\r
163     else                          /* network driver not installed */\r
164     {\r
165         network = FALSE;\r
166         ournode = 0;                  /* only node 0 is available */\r
167     }\r
168 #else\r
169     network = FALSE;\r
170     ournode = 0;\r
171 #endif\r
172     argc--,argv++;\r
173 \r
174     for( ; argc>0; argc--,argv++ ){\r
175        if( filename != NULL )  usage();\r
176        if( (*argv)[0]=='-' )\r
177           switch( (*argv)[1] ){\r
178 \r
179              case 'i' :\r
180                infmode = TRUE;\r
181                break;\r
182 \r
183              case 'd' :\r
184                debug = TRUE;\r
185                break;\r
186 \r
187              case 'r' :\r
188 #if DLINK\r
189                if (!network)\r
190                abend("D-Link Network Driver Version 3.21 must be installed\n");\r
191                 argv++,argc--;\r
192                 if( argc==0 )  usage();\r
193                if( sscanf( *argv, "%d", &c ) != 1 )  usage();\r
194                if( c < 0 || c >= 255 || c == ournode )\r
195                    abend("Invalid console node number\n");\r
196                console = c;\r
197                remote = TRUE;\r
198 #elif TCPIP\r
199                argv++,argc--;\r
200                if( argc==0 )  usage();\r
201                if( sscanf( *argv, "%d", &c ) != 1 )  usage();\r
202                if( c < 0 || c >= 255 )\r
203                    abend("Invalid my console node number\n");\r
204                ournode = console = c;\r
205                argv++,argc--;\r
206                if( argc==0 )  usage();\r
207                /* here we test if we are remote */\r
208                /* master will have number of slaves to wait for */\r
209                /* slave - internet full address of master */\r
210                if( strchr(*argv,':') ){\r
211                    /* internet address of master nn.nn.nn.nn:port */\r
212                    remote = TRUE;\r
213                    tcpip_connect_to_master( *argv );\r
214                }else{\r
215                    /* # of slaves to wait for */\r
216                    if( sscanf( *argv, "%d", &c ) != 1 )  usage();\r
217                    if( c < 0  ||  c >= 254  )  usage();\r
218                    tcpip_wait_for_slaves( c );\r
219                    remote = FALSE;\r
220                }\r
221                puts("");\r
222                network = TRUE;\r
223 #else\r
224                usage();\r
225 #endif\r
226                break;\r
227 \r
228              case 'm' :\r
229                 argv++,argc--;\r
230                 if( argc==0 )  usage();\r
231                if (sscanf( *argv, "%ld", &m ) != 1) usage();\r
232                if (m <= 0 || m > MAXMEMSIZE)\r
233                    abend("Invalid memory size specified\n");\r
234                memorysize = m;\r
235                break;\r
236 \r
237              default :\r
238            usage();\r
239            break;\r
240 \r
241           }     /*  end of switch */\r
242        else{  /* this is not option */\r
243           if( filename != NULL )  usage();\r
244           filename = *argv ;\r
245        }\r
246     }  /* end of for */\r
247 \r
248     if( filename!=NULL )\r
249        load(filename);                     /* load code and prototypes */\r
250     else\r
251        usage();\r
252 }\r
253 \r
254 \r
255 void decode(){\r
256     extopcode *eop;\r
257     eop = (extopcode *)(M+ic);   /* pointer to extended opcode in M */\r
258     lastic = ic;                     /* save ic for possible redecoding */\r
259     ic += APOPCODE;\r
260     opcode = ((int) eop->opcode ) & 0xFF ;\r
261     getargument(a1, 0);\r
262     getargument(a2, 1);\r
263     getargument(a3, 2);\r
264 }\r
265 \r
266 \r
267 int main(argc, argv)\r
268 int argc;\r
269 char **argv;\r
270 {\r
271     initiate(argc, argv);             /* initialize executor */\r
272     runsys();              /* initialize running system */\r
273     init_scheduler();\r
274     setjmp(contenv);         /* set label for continue long jump */\r
275     while (TRUE)                     /* repeat until exit() is called */\r
276     {\r
277         schedule();         /* reschedule current process */\r
278         decode();               /* fetch instruction */\r
279         execute();            /* and execute it */\r
280     }\r
281     return 0;\r
282 } /* end main */\r
283 \r