home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programming
/
powerprogramming1994.iso
/
progtool
/
microcrn
/
issue_40.arc
/
DAIMS.ARC
/
COMMANDS.CPP
< prev
next >
Wrap
Text File
|
1988-02-10
|
7KB
|
258 lines
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <stream.h>
#include <string.h>
#include "chbuffer.hxx"
#include "daims.hxx"
/*
**
** Routines to do the commands in yyparse.y
*/
extern int yyparse();
char * progname; /* for error messages */
char * source_name; /* current source file name */
int lineno; /* to say where they occurred */
jmp_buf begin; /* place to return to on error */
extern int ydebug_f;
extern int ldebug_f;
int debug_f;
int trace_f;
int sstep_f;
void error(char *s, char * s2)
{
cerr << s << " " << s2 << "\n";
exit(1);
}
void prompt()
{
cout << "DAIMS> ";
cout.flush();
}
/*
-*++ help(): get help inside the DAIMS interpreter
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed: The help file contains a general message (printed when
** "help" is typed by itself) followed by specific messages. Each specific
** message begins with the subject name(s) surrounded by curly braces. If a
** name within the curly braces is matched, the following text is printed out,
** until the next '{'
** ++*)
*/
void help(char * subject)
{
char ch;
char stg[80];
int NOT_FOUND = 1;
filebuf helpfile;
if (helpfile.open(HELP_FILE,input) == 0)
error("cannot open help file",HELP_FILE);
istream help(&helpfile);
if (debug_f) cerr << "subject `" << (int)subject << "'\n";
if(subject) {
if (debug_f) cerr << "looking for a subject: " << subject << "\n";
/* find the subject */
while (NOT_FOUND) {
while(help.get(ch)) {
if (debug_f) cerr.put(ch);
if (ch == '{') break; /* subject names in "{}" */
}
if (debug_f) cerr << "found left brace\n";
if (help.eof()) {
cerr << "subject \"" << subject << "\" not found\n";
return;
}
do {
help >> stg; /* this is a nifty feature */
if (debug_f) cerr << "checking : " << stg << "\n";
NOT_FOUND = strcmp(stg,subject); /* zero if equal */
if(!NOT_FOUND) break;
if (debug_f) cerr << "NOT_FOUND = " << NOT_FOUND << "\n";
} while (*stg != '}');
if (debug_f) if (*stg == '}') cerr << " found right brace\n";
}
while(help.get(ch))
if (ch == '}') break; /* find the other "subject" brace */
if (debug_f) cerr << "dumping subject text:\n";
while(help.get(ch)) {
if (ch == '{') break;
cout.put(ch); /* dump the subject text */
}
}
else {
if (debug_f) cerr << "subject help";
while(help.get(ch)) {
if (ch == '{') break;
cout.put(ch); /* dump the help subjects */
}
}
cout << "\n";
}
/*
-*++ source(): get input from a new file, saving the old environment
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed: You can source files to any level, since the current
** environment is saved on the stack and restored when the end of the sourced
** file is encountered.
** ++*)
*/
void source(char * filename)
{
char dummy[10];
int tmp_lineno = lineno; /* save current line count */
filebuf sourcefile;
istream tmpcin(cin); /* to hold cin while sourcing */
char * oldname = source_name; /* remember what file called us */
source_name = filename; /* source_name is global */
if (sourcefile.open(filename,input) == 0)
error("cannot open input file",filename);
istream source(&sourcefile);
cin = source;
lineno = 1; /* start counting lines in the new file */
if(oldname && trace_f) { /* if this file was called from another file */
cout << "trace: open new source file:\n ";
buf.dump();
cout << "\n";
}
else if (trace_f) buf.erase();
while(yyparse()) { /* parse the sourced file */
lineno++;
if(trace_f) { /* if tracing and sourcing a file, echo */
cout << "trace: previous output generated by line " << lineno -1;
cout << " in sourced file " << "\"" << source_name << "\"" << ":\n ";
buf.dump();
}
if (sstep_f) { cout << "press RET to continue "; gets(dummy); }
}
cin = tmpcin; /* reset the input */
sourcefile.close();
lineno = tmp_lineno; /* reset line number counting */
source_name = oldname; /* so the error messages work right */
}
/*
-*++ option(): parses command line options
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed:
** ++*)
*/
int option(char * opt)
{
/* Returns true if more options may be in the string */
switch (*opt) {
case 'y': /* Yacc debug flag */
ydebug_f = 1;
return(1);
case 'l': /* Lex debug flag */
ldebug_f = 1;
return(1);
case 'd': /* general debug flag */
debug_f = 1;
return(1);
case 't': /* source file trace flag */
trace_f = 1;
return(1);
case 's': /* source file single-step flag */
sstep_f = 1;
return(1);
case '\0': /* End of string */
return(0);
default:
printf("%s: bad option (%c)\n",*opt);
break;
}
return(0);
}
void warning (char * s, char * t)
{
cerr << progname << ": " << s;
if (t) cerr << " " << t;
if (source_name)
cerr << " near line " << lineno << " in sourced file: " << source_name;
cerr << "\n";
}
void execerror(char * s, char * t)
{
warning(s,t);
longjmp(begin,0);
}
SIG_PF fpecatch() /* catch floating-point exceptions */
{
execerror("floating point exceptions", (char *)0 );
return (SIG_PF)0;
}
/*
-*++ main(): The main interpreter loop for daims
**
** (*++ history:
** 7 Dec 87 Bruce Eckel Creation date
** ++*)
**
** (*++ detailed: Sets up to catch control-C's, Floating-point exceptions (not
** functional yet) parses the command line switches and starts sourcing a file
** if one was requested on the command line.
** ++*)
*/
main(int argc, char *argv[])
{
progname = argv[0];
int yreturn;
char * opt;
char **av = argv;
int ac = argc;
debug_f = ydebug_f = ldebug_f = 0;
/* Parse the command line */
while (--ac > 0 && (*++av)[0] == '-') {
for (opt = av[0]+1; option(opt); opt++)
;
cout << "option " << av[0] << "\n";
}
if (argc > 1 && (*av)[0] != '-') { source(av[0]); }
cout << "type \"help\" for help\n";
setjmp(begin);
// signal(SIGFPE, fpecatch);
do {
prompt();
if(debug_f) cerr << "entering yyparse()\n";
yreturn = yyparse();
if (trace_f) buf.erase();
if(debug_f) cerr << "leaving yyparse()\n";
if (debug_f) cerr << " yyparse returned " << yreturn << "\n";
} while (yreturn);
}