| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
TPL_MAIN.CPP
main interpreter
/*-------------------------------------------------------------------*
T Interpreter
Interprets assignment statements, procedures, and functions
Use the large memory model when compiling.
File: tpl_main.cpp
Link to: scn_main.cpp, sym_tabl.cpp,
prs_main.cpp, prs_stmt.cpp, prs_decl.cpp,
prs_expr.cpp, prs_stnd.cpp, prs_emit.cpp,
exc_main.cpp, exc_stnd.cpp, exc_dbug.cpp
Usage: ti filename.ext [debug]
by: Stephen R. Schmitt
*-------------------------------------------------------------------*/
#include "tpl_data.h"
#include <assert.h>
#include <conio.h>
#include <dos.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* External variables
*/
/* in scn_main.cpp */
extern int Line_count;
extern token_struct Token;
/*
* Global declarations
*/
char Srce_file[FILE_NAME_LENGTH]; // source file name
char Err_msg_file[FILE_NAME_LENGTH]; // for error messages
char Command[32]; // interpret command
bool Debug_flag; // call debug if true
char *User_screen; // full screen buffer
char *Debug_screen; // full screen buffer
int User_col, User_lin; // cursor location
int Error_count = 0; // number of errors
int Video_mode; // of system
FILE *Error_file; // for error messages
#ifdef DEBUG
FILE *c_out; // subprogram segments
FILE *d_out; // data segment
#endif
/*-------------------------------------------------------------------*
Code Section
*-------------------------------------------------------------------*/
void main(int argc, char *argv[])
{
init_interpreter(argc, argv[1], argv[2]);
if (!init_scanner(Srce_file))
{
printf("Error: cannot open source file.\n");
exit(-1); // failure
}
list_fopen(); // open analysis file
errm_fopen(); // open error msg file
pass_one(); // do first pass
quit_scanner();
if (Error_count == 0)
{
init_scanner(Srce_file);
pass_two(); // do second pass
quit_scanner();
}
errm_fclose(); // close error msg file
list_fclose(); // close analysis file
if (Error_count == 0) // call interpreter
interpret();
exit_interpreter(); // cleanup
}
/*
* "init_interpreter" sets interpreter mode
*
* returns: nothing
*/
void init_interpreter(int argc, char *arg1, char *arg2)
{
Debug_flag = false; // default
save_video_mode();
if (argc == 1)
{
printf("\n\n");
printf("\t\t T Interpreter\n\n");
printf("\t\t Usage: ti filename.ext [debug]\n\n");
printf("\t\t Esc key halts interpreter\n\n\n");
#ifndef DEBUG
exit(0);
#else
printf("Test file: ");
scanf("%s", Srce_file);
fflush(stdin);
Debug_flag = true;
#endif
}
else if (argc == 2)
strcpy(Srce_file, arg1);
else if (argc == 3)
{
strcpy(Srce_file, arg1);
strcpy(Command, arg2);
if (!strcmp(Command, "debug")) // match?
{
Debug_flag = true;
printf("debug mode set\n");
}
else
Debug_flag = false;
}
if (Debug_flag == true)
{
Debug_screen = new char[4000];
User_screen = new char[4000];
User_col = wherex() - 1; // user screen data
User_lin = wherey() - 1;
gettext(1, 1, 80, 25, User_screen);
}
}
/*
* "exit_interpreter" closes files and sets program return value
*
* returns: nothing
*/
void exit_interpreter()
{
restore_video_mode();
if (Debug_flag == true)
{
_setcursortype(_NORMALCURSOR); // restore user screen
window(1, 1, 80, 25);
puttext(1, 1, 80, 25, User_screen);
gotoxy(User_col + 1, User_lin + 1);
assert(User_screen != NULL);
delete User_screen;
assert(Debug_screen != NULL);
delete Debug_screen;
}
else if (Error_count != 0) // note errors if any
{
fprintf(stderr, "%20d Source lines. \n", Line_count);
fprintf(stderr, "%20d Total errors. \n", Error_count);
}
exit(Error_count);
}
/*
* Error messages keyed to enumerated error codes in tpl_data.h
*/
char *M_word[] =
{
" ",
" , ", " . ", " ... ",
" (", ") ", " : ", " := ",
"argument", "array", "assignment",
"by",
"case", "code", "constant", "context",
"data", "deep", "division", "do",
"end", "error",
"failed", "field", "file",
"for", "function",
"identifier", "if", "incompatible",
"integer", "invalid", "item",
"label", "labels", "large", "loop",
"many", "memory", "missing",
"nesting", "not", "number",
"of", "open", "out", "overflow",
"parameter", "parameters", "program",
"range", "real", "record", "redefined", "return",
"segment", "stack", "subscripts", "syntax",
"then", "too", "type", "types",
"undefined", "underflow", "union", "usage",
"value", "variable",
"wrong",
"zero",
};
/*
* "compile_error" prints an error message to an error file.
* Codes are defined in tpl_data.h and correspond to elements
* of "M_word[]".
*
* returns: nothing
*/
void compile_error(MSG_CODE code, ...) // message code(s)
{
va_list ap;
MSG_CODE arg;
char message[80];
Error_count++; // update global
strcpy(message, M_word[code]);
va_start(ap, code);
arg = va_arg(ap, MSG_CODE);
while (arg != M_0)
{
strcat(message, " ");
strcat(message, M_word[arg]);
arg = va_arg(ap, MSG_CODE);
}
va_end(ap);
fprintf(Error_file, "%s %03d %06d %03d %s\n",
Token.file, Error_count, Token.line, Token.column, message);
if (Error_count >= 25)
{
Error_count++;
fprintf(Error_file, "%03d %06d %03d Too many errors\n",
Error_count, Token.line, Token.column);
errm_fclose();
list_fclose();
exit_interpreter();
}
}
/*
* "runtime_error" prints a run-time error message and then
* halts program execution.
* Codes are defined in tpl_data.h and correspond to elements
* of "M_word[]".
*
* returns: nothing
*/
void runtime_error(MSG_CODE code, ...) // of error message(s)
{
va_list ap;
MSG_CODE arg;
char message[80];
strcpy(message, M_word[code]);
va_start(ap, code);
arg = va_arg(ap, MSG_CODE);
while (arg != M_0)
{
strcat(message, " ");
strcat(message, M_word[arg]);
arg = va_arg(ap, MSG_CODE);
}
va_end(ap);
Error_count++;
if (Debug_flag)
{
// send message to the debug screen
textattr(RED*16 + WHITE);
gotoxy(1, SCREEN_BOTTOM);
clreol();
cputs(" ERROR: ");
cputs(message);
getch(); // wait for key press
errm_fclose();
list_fclose();
exit_interpreter();
}
else
{
// print error message and exit program
restore_video_mode();
fprintf(stderr, "RUN-TIME ERROR: %s \n", message);
errm_fclose();
list_fclose();
exit(Error_count); // failure
}
}
/*
* "errm_fopen" opens the error message file which is used by the
* editor program.
*
* returns: nothing
*/
void errm_fopen()
{
char *str_ptr; // to '.'
// convert source file name into error message file name
// then open error file with this name
strcpy(Err_msg_file, Srce_file);
str_ptr = strchr(Err_msg_file, '.');
strcpy(str_ptr, ".ERR");
Error_file = fopen(Err_msg_file, "w");
}
/*
* "errm_fclose" closes the error message file which is used by the
* editor program.
*
* returns: nothing
*/
void errm_fclose()
{
fclose(Error_file);
if (Error_count == 0) // delete the file
unlink(Err_msg_file);
}
/*
* "save_video_mode" saves the system's video mode
*
* returns: nothing
*/
void save_video_mode()
{
union REGS inr, outr;
inr.h.ah = 0x0F; // get video mode
int86(16, &inr, &outr); // call bios
Video_mode = outr.h.al;
}
/*
* "restore_video_mode" restores the system's video mode if
* it was changed by a T program and not restored
*
* returns: nothing
*/
void restore_video_mode()
{
union REGS inr, outr;
inr.h.ah = 0x0F; // get video mode
int86(16, &inr, &outr); // call bios
if (Video_mode != outr.h.al)
{
inr.h.ah = 0x00; // set video mode
inr.h.al = Video_mode;
int86(16, &inr, &outr); // call bios
}
}
#ifdef DEBUG
/*
* "list_fopen" creates files for debugging.
*
* returns: nothing
*/
void list_fopen()
{
c_out = fopen("c.out", "w");
d_out = fopen("d.out", "w");
}
/*
* "list_fclose" closes debugging files and
* creates a file for the path log.
*
* returns: nothing
*/
void list_fclose()
{
fclose(c_out);
fclose(d_out);
}
#endif
| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
Copyright © 2004, Stephen R. Schmitt