3
"$Header: d:/cvsroot/tads/tads3/test/TEST_PRS.CPP,v 1.4 1999/07/11 00:47:03 MJRoberts Exp $";
7
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
9
* Please see the accompanying license file, LICENSE.TXT, for information
10
* on using and copying this software.
14
test_prs.cpp - parser test
20
05/01/99 MJRoberts - Creation
44
static void errexit(const char *msg)
50
static void show_const(int level, CTcPrsNode *result)
55
for (i = level*3 ; i != 0 ; --i)
62
else if (result->is_const())
64
switch(result->get_const_val()->get_type())
80
result->get_const_val()->get_val_int());
84
printf("sstr = %.*s\n",
85
(int)result->get_const_val()->get_val_str_len(),
86
result->get_const_val()->get_val_str());
90
printf("list: %d elements\n",
91
result->get_const_val()->get_val_list()
93
for (ele = result->get_const_val()->get_val_list()->get_head() ;
94
ele != 0 ; ele = ele->get_next())
95
show_const(level + 1, ele->get_expr());
99
printf("object: %ld\n", result->get_const_val()->get_val_obj());
103
printf("property id: %d\n",
104
result->get_const_val()->get_val_prop());
108
printf("function pointer: %.*s\n",
109
(int)result->get_const_val()->get_val_funcptr_sym()
111
result->get_const_val()->get_val_funcptr_sym()
115
case TC_CVT_ANONFUNCPTR:
116
printf("anonymous function pointer\n");
124
printf("Non-constant value\n");
132
node_entry(CTcPrsNode *n, CTcTokFileDesc *d, long l)
139
/* top-level parse node for this line */
142
/* file and line of source where node started */
143
CTcTokFileDesc *desc;
146
/* next entry in list */
150
int main(int argc, char **argv)
152
CResLoader *res_loader;
155
int fatal_error_count = 0;
156
node_entry *node_head = 0;
157
node_entry *node_tail = 0;
159
CVmFile *imgfile = 0;
160
ulong next_obj_id = 1;
161
uint next_prop_id = 1;
163
CTcTokFileDesc *desc;
165
CTcUnasSrcCodeStr *unas_in;
166
CTcUnasOutStdio unas_out;
167
char pathbuf[OSFNMAX];
169
/* initialize for testing */
172
/* create the host interface object */
173
hostifc = new CTcHostIfcStdio();
175
/* create a resource loader */
176
os_get_special_path(pathbuf, sizeof(pathbuf), argv[0], OS_GSP_T3_RES);
177
res_loader = new CResLoader(pathbuf);
179
/* initialize the compiler */
180
CTcMain::init(hostifc, res_loader, 0);
182
/* create the disassembler input stream */
183
unas_in = new CTcUnasSrcCodeStr(G_cs);
187
/* scan -I arguments */
188
for (curarg = 1 ; curarg < argc ; ++curarg)
192
/* get the argument string for easy reference */
195
/* if it's not an option, we're done */
199
/* if it's a -I argument, use it */
205
* if it's with this argument, read it, otherwise move
206
* on to the next argument
208
if (*(p + 2) == '\0')
209
path = argv[++curarg];
213
/* add the directory to the include path list */
214
G_tok->add_inc_path(path);
216
else if (*(p + 1) == 'v')
218
/* set verbose mode */
219
G_tcmain->set_verbosity(TRUE);
224
* invalid usage - consume all the arguments and fall
225
* through to the usage checker
232
/* check arguments */
233
if (curarg + 2 != argc)
235
/* terminate the compiler */
236
CTcMain::terminate();
238
/* delete our objects */
241
/* exit with an error */
242
errexit("usage: test_prs [options] <source-file> <image-file>\n"
244
" -Idir - add dir to include path\n"
245
" -v - verbose error messages");
248
/* set up the tokenizer with the main input file */
249
if (G_tok->set_source(argv[curarg], argv[curarg]))
250
errexit("unable to open source file");
252
/* set up an output file */
253
fpout = osfopwb(argv[curarg+1], OSFTT3IMG);
255
errexit("unable to open image file");
256
imgfile = new CVmFile();
257
imgfile->set_file(fpout, 0);
259
/* read the first token */
262
/* parse expressions */
268
/* if we're at end of file, we're done */
269
if (G_tok->getcur()->gettyp() == TOKT_EOF)
272
/* check for our fake declarations */
273
switch(G_tok->getcur()->gettyp())
276
/* add an object symbol */
278
entry = new CTcSymObj(G_tok->getcur()->get_text(),
279
G_tok->getcur()->get_text_len(),
280
FALSE, next_obj_id++, FALSE,
282
G_prs->get_global_symtab()->add_entry(entry);
284
/* skip the object name */
289
/* add a function symbol */
291
entry = new CTcSymFunc(G_tok->getcur()->get_text(),
292
G_tok->getcur()->get_text_len(),
293
FALSE, 0, FALSE, TRUE,
294
FALSE, FALSE, FALSE);
295
G_prs->get_global_symtab()->add_entry(entry);
297
/* skip the function name */
302
/* add a local variable symbol */
304
entry = new CTcSymLocal(G_tok->getcur()->get_text(),
305
G_tok->getcur()->get_text_len(),
306
FALSE, FALSE, next_local++);
307
G_prs->get_global_symtab()->add_entry(entry);
309
/* skip the function name */
314
/* note the starting line */
315
desc = G_tok->get_last_desc();
316
linenum = G_tok->get_last_linenum();
318
/* parse an expression */
319
result = G_prs->parse_expr();
321
/* add it to our list */
326
/* create a new list entry */
327
cur = new node_entry(result, desc, linenum);
329
/* link it at the end of our list */
332
node_tail->nxt = cur;
339
/* parse a semicolon */
340
if (G_prs->parse_req_sem())
345
* if there were no parse errors, run through our node list and
348
if (G_tcmain->get_error_count() == 0)
351
* loop through our node list; generate code and then delete
354
while (node_head != 0)
358
/* remember the next entry */
359
nxt = node_head->nxt;
362
* set this line's descriptor as current, for error
365
G_tok->set_line_info(node_head->desc, node_head->linenum);
367
/* fold symbolic constants */
370
->fold_constants(G_prs->get_global_symtab());
372
/* if it's a constant value, display it */
373
show_const(0, node_head->node);
376
* generate code; for testing purposes, don't discard
377
* anything, to ensure we perform all generation
379
node_head->node->gen_code(FALSE, FALSE);
381
/* disassemble this much */
382
unas_out.print("// line %lu\n", node_head->linenum);
383
CTcT3Unasm::disasm(unas_in, &unas_out);
385
/* delete this entry */
388
/* move on to the next entry */
396
* if it's not a general internal or fatal error, log it; don't
397
* log general errors, since these will have been logged as
398
* specific internal errors before being thrown
400
if (exc->get_error_code() != TCERR_INTERNAL_ERROR
401
&& exc->get_error_code() != TCERR_FATAL_ERROR)
402
G_tok->log_error(TC_SEV_FATAL, exc->get_error_code());
404
/* count the fatal error */
413
"Longest string: %d, longest list: %d\n",
414
G_tcmain->get_warning_count(),
415
G_tcmain->get_error_count() + fatal_error_count,
416
G_cg->get_max_str_len(), G_cg->get_max_list_cnt());
418
/* delete the disassembler input object */
421
/* shut down the compiler */
422
CTcMain::terminate();
424
/* done with the res loader */
427
/* delete the image file */
430
/* delete the host interface */
433
/* show any unfreed memory */
434
t3_list_memory_blocks(0);
441
* dummy 'make' object implementation
443
void CTcMake::write_build_config_to_sym_file(class CVmFile *)
449
/* ------------------------------------------------------------------------ */
451
* dummy implementation of runtime symbol table
453
void CVmRuntimeSymbols::add_sym(const char *, size_t,