cfad47cfa3/t3compiler/tads3/test/test_prs_top.cpp

4b825dc642cb6eb9a060e54bf8d69288fbee4904cfad47cfa334b206c65f22086bcc5d63e6f70944
1
#ifdef RCSID
2
static char RCSid[] =
3
"$Header: d:/cvsroot/tads/tads3/test/test_prs_top.cpp,v 1.1 1999/07/11 00:47:03 MJRoberts Exp $";
4
#endif
5
6
/* 
7
 *   Copyright (c) 1999, 2002 Michael J. Roberts.  All Rights Reserved.
8
 *   
9
 *   Please see the accompanying license file, LICENSE.TXT, for information
10
 *   on using and copying this software.  
11
 */
12
/*
13
Name
14
  test_prs.cpp - parser test: test parsing from the top level
15
Function
16
  
17
Notes
18
  
19
Modified
20
  05/01/99 MJRoberts  - Creation
21
*/
22
23
#include <stdlib.h>
24
#include <stdio.h>
25
26
#include "os.h"
27
#include "t3std.h"
28
#include "tctok.h"
29
#include "resload.h"
30
#include "tcmain.h"
31
#include "tchostsi.h"
32
#include "tcglob.h"
33
#include "tcprs.h"
34
#include "tctarg.h"
35
#include "vmfile.h"
36
#include "tcunas.h"
37
#include "tct3unas.h"
38
#include "tcmake.h"
39
#include "vmimage.h"
40
#include "vmrunsym.h"
41
#include "t3test.h"
42
43
44
static void errexit(const char *msg)
45
{
46
    printf("%s\n", msg);
47
    exit(1);
48
}
49
50
int main(int argc, char **argv)
51
{
52
    CResLoader *res_loader;
53
    CTcHostIfc *hostifc;
54
    int curarg;
55
    int fatal_error_count = 0;
56
    osfildef *fpout = 0;
57
    CVmFile *imgfile = 0;
58
    CTcUnasSrcCodeStr *unas_in;
59
    CTcUnasOutStdio unas_out;
60
    CTPNStmProg *node;
61
    const char *image_fname;
62
    int success;
63
    int unasm = FALSE;
64
    uchar xor_mask = 0;
65
    char pathbuf[OSFNMAX];
66
67
    /* initialize for testing */
68
    test_init();
69
70
    /* create the host interface object */
71
    hostifc = new CTcHostIfcStdio();
72
73
    /* create a resource loader */
74
    os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_RES);
75
    res_loader = new CResLoader(pathbuf);
76
77
    /* initialize the compiler */
78
    CTcMain::init(hostifc, res_loader, "us-ascii");
79
80
    /* use test reporting mode */
81
    G_tok->set_test_report_mode(TRUE);
82
    G_tcmain->set_test_report_mode(TRUE);
83
84
    /* create the disassembler input stream */
85
    unas_in = new CTcUnasSrcCodeStr(G_cs);
86
87
    err_try
88
    {
89
        static const char tool_data[4] = { 't', 's', 't', 'P' };
90
            
91
        /* scan options */
92
        for (curarg = 1 ; curarg < argc ; ++curarg)
93
        {
94
            char *p;
95
            
96
            /* get the argument string for easy reference */
97
            p = argv[curarg];
98
            
99
            /* if it's not an option, we're done */
100
            if (*p != '-')
101
                break;
102
            
103
            /* if it's a -I argument, use it */
104
            if (*(p + 1) == 'I')
105
            {
106
                char *path;
107
                
108
                /* 
109
                 *   if it's with this argument, read it, otherwise move
110
                 *   on to the next argument 
111
                 */
112
                if (*(p + 2) == '\0')
113
                    path = argv[++curarg];
114
                else
115
                    path = p + 2;
116
                
117
                /* add the directory to the include path list */
118
                G_tok->add_inc_path(path);
119
            }
120
            else if (*(p + 1) == 'v')
121
            {
122
                /* set verbose mode */
123
                G_tcmain->set_verbosity(TRUE);
124
            }
125
            else if (*(p + 1) == 'u')
126
            {
127
                /* note unassembly mode */
128
                unasm = TRUE;
129
            }
130
            else
131
            {
132
                /* 
133
                 *   invalid usage - consume all the arguments and fall
134
                 *   through to the usage checker 
135
                 */
136
                curarg = argc;
137
                break;
138
            }
139
        }
140
        
141
        /* check arguments */
142
        if (curarg + 2 != argc)
143
        {
144
            /* terminate the compiler */
145
            CTcMain::terminate();
146
            
147
            /* delete our objects */
148
            delete res_loader;
149
            
150
            /* exit with an error */
151
            errexit("usage: test_prs [options] <source-file> <image-file>\n"
152
                    "options:\n"
153
                    "   -Idir  - add dir to include path\n"
154
                    "   -v     - verbose error messages");
155
        }
156
157
        /* add the default system include directory to the include path */
158
        os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_INC);
159
        G_tok->add_inc_path(pathbuf);
160
        
161
        /* set up the tokenizer with the main input file */
162
        if (G_tok->set_source(argv[curarg], argv[curarg]))
163
            errexit("unable to open source file");
164
165
        /* set up an output file */
166
        image_fname = argv[curarg+1];
167
        fpout = osfopwb(image_fname, OSFTT3IMG);
168
        if (fpout == 0)
169
            errexit("unable to open image file");
170
        imgfile = new CVmFile();
171
        imgfile->set_file(fpout, 0);
172
173
        /* read the first token */
174
        G_tok->next();
175
        
176
        /* parse at the top level */
177
        node = G_prs->parse_top();
178
179
        /* if errors occurred during parsing, stop here */
180
        if (G_tcmain->get_error_count() != 0 || node == 0)
181
            goto done;
182
        
183
        /* fold symbolic constants for all nodes */
184
        node->fold_constants(G_prs->get_global_symtab());
185
186
        /* if errors occurred during constant folding, stop now */
187
        if (G_tcmain->get_error_count() != 0)
188
            goto done;
189
190
        /* generate code and write the image file */
191
        node->build_image(imgfile, xor_mask, tool_data);
192
            
193
        /* if errors occurred during code generation, stop now */
194
        if (G_tcmain->get_error_count() != 0)
195
            goto done;
196
197
        /* disassemble the result if desired */
198
        if (unasm)
199
            CTcT3Unasm::disasm(unas_in, &unas_out);
200
201
    done: ;
202
    }
203
    err_catch(exc)
204
    {
205
        /* 
206
         *   if it's not a general internal or fatal error, log it; don't
207
         *   log general errors, since these will have been logged as
208
         *   specific internal errors before being thrown 
209
         */
210
        if (exc->get_error_code() != TCERR_INTERNAL_ERROR
211
            && exc->get_error_code() != TCERR_FATAL_ERROR)
212
            G_tok->log_error(TC_SEV_FATAL, exc->get_error_code());
213
214
        /* count the fatal error */
215
        ++fatal_error_count;
216
    }
217
    err_end;
218
219
    /* report errors */
220
    fprintf(stderr,
221
            "Warnings: %d\n"
222
            "Errors:   %d\n"
223
            "Longest string: %d, longest list: %d\n",
224
            G_tcmain->get_warning_count(),
225
            G_tcmain->get_error_count() + fatal_error_count,
226
            G_cg->get_max_str_len(), G_cg->get_max_list_cnt());
227
228
    /* 
229
     *   note whether or not the compilation was successful - it succeeded
230
     *   if we had no errors or fatal errors 
231
     */
232
    success = (G_tcmain->get_error_count() + fatal_error_count == 0);
233
234
    /* delete the image file object (this closes the file) */
235
    delete imgfile;
236
237
    /* 
238
     *   if any errors occurred, delete the image file in the external
239
     *   file system - this prevents us from leaving around an incomplete
240
     *   or corrupted image file when compilation fails, and helps
241
     *   'make'-type tools realize that they must generate the image file
242
     *   target again on the next build, even if source files didn't
243
     *   change 
244
     */
245
    if (!success)
246
        osfdel(image_fname);
247
248
    /* delete the disassembler input object */
249
    delete unas_in;
250
251
    /* shut down the compiler */
252
    CTcMain::terminate();
253
254
    /* done with the res loader */
255
    delete res_loader;
256
257
    /* delete the host interface */
258
    delete hostifc;
259
260
    /* show any unfreed memory */
261
    t3_list_memory_blocks(0);
262
263
    /* 
264
     *   terminate - exit with a success indication if we had no errors
265
     *   (other than warnings); exit with an error indication otherwise 
266
     */
267
    return (success ? OSEXSUCC : OSEXFAIL);
268
}
269
270
/*
271
 *   dummy 'make' object implementation 
272
 */
273
void CTcMake::write_build_config_to_sym_file(class CVmFile *)
274
{
275
}
276
277
/* ------------------------------------------------------------------------ */
278
/*
279
 *   dummy implementation of runtime symbol table 
280
 */
281
void CVmRuntimeSymbols::add_sym(const char *, size_t,
282
                                const vm_val_t *)
283
{
284
}