Pristine Ack-5.5
[Ack-5.5.git] / lang / pc / comp / main.c
1 /* M A I N   P R O G R A M */
2
3 #include        "debug.h"
4
5 #include        <em.h>
6 #include        <em_mes.h>
7 #include        <system.h>
8 #include        <stb.h>
9
10 #include        "LLlex.h"
11 #include        "Lpars.h"
12 #include        "class.h"
13 #include        "const.h"
14 #include        "def.h"
15 #include        "f_info.h"
16 #include        "idf.h"
17 #include        "input.h"
18 #include        "main.h"
19 #include        "node.h"
20 #include        "required.h"
21 #include        "tokenname.h"
22 #include        "type.h"
23 #include        "scope.h"
24 #include        "dbsymtab.h"
25
26 char            options[128];
27 char            *ProgName;
28 char            *input = "input";
29 char            *output = "output";
30
31 label           data_label;
32 label           text_label;
33
34 struct def      *program;
35 extern int      fp_used;        /* set if floating point used */
36
37
38 main(argc, argv)
39         register char **argv;
40 {
41         register int Nargc = 1;
42         register char **Nargv = &argv[0];
43
44         ProgName = *argv++;
45
46         while( --argc > 0 )     {
47                 if( **argv == '-' )
48                         DoOption((*argv++) + 1);
49                 else
50                         Nargv[Nargc++] = *argv++;
51         }
52         Nargv[Nargc] = 0;       /* terminate the arg vector     */
53         if( Nargc < 2 ) {
54                 fprint(STDERR, "%s: Use a file argument\n", ProgName);
55                 sys_stop(S_EXIT);
56         }
57         if(!Compile(Nargv[1], Nargv[2])) sys_stop(S_EXIT);
58         sys_stop(S_END);
59 }
60
61 Compile(src, dst)
62         char *src, *dst;
63 {
64         extern struct tokenname tkidf[];
65         extern struct tokenname tkstandard[];
66         int tk;
67
68         if( !InsertFile(src, (char **) 0, &src) )       {
69                 fprint(STDERR, "%s: cannot open %s\n", ProgName, src);
70                 return 0;
71         }
72         LineNumber = 1;
73         FileName = src;
74         init_idf();
75         InitCst();
76         reserve(tkidf);
77         reserve(tkstandard);
78
79         CheckForLineDirective();
80         tk = LLlex();                   /* Read the first token and put */
81         aside = dot;                    /* it aside. In this way, options */
82         asidetype = toktype;            /* inside comments will be seen */
83         dot.tk_symb = tk;               /* before the program starts. */
84         tokenseen = 1;
85
86         InitScope();
87         InitTypes();
88
89         if( options['c'] ) tkclass['"'] = STSTR;
90         if( options['u'] || options['U'] ) {
91                 class('_') = STIDF;
92                 inidf['_'] = 1;
93         }
94         if( tk == '"' || tk == '_' ) {
95                 PushBack();
96                 ASIDE = 0;
97         }
98
99 #ifdef DEBUG
100         if( options['l'] )      {
101                 LexScan();
102                 return 0;       /* running the optimizer is not very useful */
103         }
104 #endif /* DEBUG */
105         C_init(word_size, pointer_size);
106         if( !C_open(dst) )
107                 fatal("couldn't open output file");
108         C_magic();
109         C_ms_emx(word_size, pointer_size);
110 #ifdef DBSYMTAB
111         if (options['g']) {
112                 C_ms_std(FileName, N_SO, 0);
113         }
114 #endif /* DBSYMTAB */
115         AddRequired();
116         C_df_dlb(++data_label);
117         C_rom_scon(FileName,(arith) strlen(FileName) + 1);
118         LLparse();
119         C_ms_src((int)LineNumber - 1, FileName);
120         if( fp_used ) C_ms_flt();
121         C_close();
122 #ifdef DEBUG
123         if( options['I'] ) Info();
124 #endif /* DEBUG */
125         return !err_occurred;
126 }
127
128 #ifdef DEBUG
129 LexScan()
130 {
131         register struct token *tkp = &dot;
132         extern char *symbol2str();
133
134         while( LLlex() > 0 )    {
135                 print(">>> %s ", symbol2str(tkp->tk_symb));
136                 switch( tkp->tk_symb )  {
137                         case IDENT:
138                                 print("%s\n", tkp->TOK_IDF->id_text);
139                                 break;
140
141                         case INTEGER:
142                                 print("%ld\n", tkp->TOK_INT);
143                                 break;
144
145                         case REAL:
146                                 print("%s\n", tkp->TOK_REL);
147                                 break;
148
149                         case STRING:
150                                 print("'%s'\n", tkp->TOK_STR);
151                                 break;
152
153                         default:
154                                 print("\n");
155                 }
156         }
157 }
158 #endif
159
160 AddRequired()
161 {
162         register struct def *df;
163         extern struct def *Enter();
164         static struct node maxintnode = { 0, 0, Value, 0, { INTEGER, 0 } };
165
166         /* PROCEDURES */
167
168         /* File handling procedures, Read(ln) & Write(ln) are handled
169          * in the grammar
170          */
171
172         df = Enter("false", D_ENUM, bool_type, 0);
173         df->enm_val = 0;
174         df->df_flags |= D_SET;
175         bool_type->enm_enums = df;
176         df->enm_next = Enter("true", D_ENUM, bool_type, 0);
177         df->enm_next->enm_val = 1;
178         df->df_flags |= D_SET;
179         df->enm_next->enm_next = NULLDEF;
180
181         (void) Enter("rewrite", D_PROCEDURE, std_type, R_REWRITE);
182         (void) Enter("put", D_PROCEDURE, std_type, R_PUT);
183         (void) Enter("reset", D_PROCEDURE, std_type, R_RESET);
184         (void) Enter("get", D_PROCEDURE, std_type, R_GET);
185         (void) Enter("page", D_PROCEDURE, std_type, R_PAGE);
186
187         /* DYNAMIC ALLOCATION PROCEDURES */
188         (void) Enter("new", D_PROCEDURE, std_type, R_NEW);
189         (void) Enter("dispose", D_PROCEDURE, std_type, R_DISPOSE);
190         if( !options['s'] ) {
191                 (void) Enter("mark", D_PROCEDURE, std_type, R_MARK);
192                 (void) Enter("release", D_PROCEDURE, std_type, R_RELEASE);
193         }
194
195         /* MISCELLANEOUS PROCEDURE(S) */
196         if( !options['s'] )
197                 (void) Enter("halt", D_PROCEDURE, std_type, R_HALT);
198
199         /* TRANSFER PROCEDURES */
200         (void) Enter("pack", D_PROCEDURE, std_type, R_PACK);
201         (void) Enter("unpack", D_PROCEDURE, std_type, R_UNPACK);
202
203         /* FUNCTIONS */
204
205         /* ARITHMETIC FUNCTIONS */
206         (void) Enter("abs", D_FUNCTION, std_type, R_ABS);
207         (void) Enter("sqr", D_FUNCTION, std_type, R_SQR);
208         (void) Enter("sin", D_FUNCTION, std_type, R_SIN);
209         (void) Enter("cos", D_FUNCTION, std_type, R_COS);
210         (void) Enter("exp", D_FUNCTION, std_type, R_EXP);
211         (void) Enter("ln", D_FUNCTION, std_type, R_LN);
212         (void) Enter("sqrt", D_FUNCTION, std_type, R_SQRT);
213         (void) Enter("arctan", D_FUNCTION, std_type, R_ARCTAN);
214
215         /* TRANSFER FUNCTIONS */
216         (void) Enter("trunc", D_FUNCTION, std_type, R_TRUNC);
217         (void) Enter("round", D_FUNCTION, std_type, R_ROUND);
218
219         /* ORDINAL FUNCTIONS */
220         (void) Enter("ord", D_FUNCTION, std_type, R_ORD);
221         (void) Enter("chr", D_FUNCTION, std_type, R_CHR);
222         (void) Enter("succ", D_FUNCTION, std_type, R_SUCC);
223         (void) Enter("pred", D_FUNCTION, std_type, R_PRED);
224
225         /* BOOLEAN FUNCTIONS */
226         (void) Enter("odd", D_FUNCTION, std_type, R_ODD);
227         (void) Enter("eof", D_FUNCTION, std_type, R_EOF);
228         (void) Enter("eoln", D_FUNCTION, std_type, R_EOLN);
229
230         /* TYPES */
231         (void) Enter("char", D_TYPE, char_type, 0);
232         (void) Enter("integer", D_TYPE, int_type, 0);
233         (void) Enter("real", D_TYPE, real_type, 0);
234         (void) Enter("boolean", D_TYPE, bool_type, 0);
235         (void) Enter("text", D_TYPE, text_type, 0);
236         (void) Enter("(void)", D_TYPE, void_type, 0);
237
238         if( options['d'] )
239                 (void) Enter("long", D_TYPE, long_type, 0);
240         if( options['c'] )
241                 (void) Enter("string", D_TYPE, string_type, 0);
242
243         /* DIRECTIVES */
244         (void) Enter("forward", D_FORWARD, error_type, 0);
245         (void) Enter("extern", D_EXTERN, error_type, 0);
246
247         /* CONSTANTS */
248         /* nil is TOKEN and thus part of the grammar */
249
250         maxintnode.nd_type = int_type;
251         maxintnode.nd_INT = max_int;            /* defined in cstoper.c */
252         df = define(str2idf("maxint", 0), CurrentScope, D_CONST);
253         df->df_type = int_type;
254         df->con_const = &maxintnode;
255         df->df_flags |= D_SET;
256 #ifdef DBSYMTAB
257         if (options['g']) stb_string(df, D_CONST);
258 #endif /* DBSYMTAB */
259 }
260
261 #ifdef DEBUG
262         int cntlines;
263
264 Info()
265 {
266         extern int cnt_def, cnt_node, cnt_paramlist, cnt_type, cnt_scope,
267                         cnt_scopelist, cnt_tmpvar, cnt_withdesig,
268                         cnt_case_hdr, cnt_case_entry;
269
270         print("\
271 %6d def\n%6d node\n%6d paramlist\n%6d type\n%6d scope\n%6d scopelist\n\
272 %6d lab\n%6d tmpvar\n%6d withdesig\n%6d casehdr\n%6d caseentry\n",
273 cnt_def, cnt_node, cnt_paramlist, cnt_type, cnt_scope, cnt_scopelist, cnt_lab, cnt_tmpvar, cnt_withdesig, cnt_case_hdr, cnt_case_entry);
274 print("\nNumber of lines read: %d\n", cntlines);
275 }
276 #endif