| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
EXC_MAIN.CPP
main executor
/*-------------------------------------------------------------------*
T interpreter execution module
File: exc_main.cpp
Module: interpreter
by: Stephen R. Schmitt
*-------------------------------------------------------------------*/
#include "tpl_data.h"
#include <assert.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <values.h>
/*
* External variables
*/
/* in tpl_main.cpp */
extern bool Debug_flag; // true in debug mode
extern char *User_screen; // full screen buffer
extern char *Debug_screen; // full screen buffer
extern int User_col, User_lin; // cursor location
#ifdef DEBUG
extern char *Op[];
#endif
/* in exc_dbug.cpp */
extern bool Trace_flag;
extern bool Set_no_trace;
/*
* Global declarations
*/
OPCODE Operator; // current opcode
MEMORY_PTR *CSeg, // code segments
DSeg, // stack segment
SSeg; // data segment
int IPtr, // instruction pointer
SNum, // segment number
SPtr, // stack pointer
BPtr; // base pointer
double DEAX; // real number register
long EAX; // integer register
long EBX; // integer register
long ECX; // integer register
char AL; // byte value register
int AX, // index value register
BX, // base index register
CX; // count register
char String[MAX_STRING_LENGTH]; // string buffer
FILE *File_ptr; // for turing i/o
int Skip_base_ptr; // at which skip set
/*-------------------------------------------------------------------*
Code Section
*-------------------------------------------------------------------*/
/*
* "interpret" processes intermediate code by calling appropriate
* interpreter routines.
*
* returns: nothing
*/
void interpret()
{
int line_num;
if (Debug_flag == true)
init_debugger();
// Initialize the interpreter
SSeg = new MEMORY[MAX_STACK_SIZE]; // create runtime stack
if (SSeg == NULL)
runtime_error(M_OUT, M_OF, M_MEMORY, M_0);
else
memset(SSeg, '\0', MAX_STACK_SIZE * sizeof(MEMORY));
SPtr = 0; // set stack pointer
BPtr = 0; // set base pointer
SNum = 0; // set code segment
IPtr = 0; // set code pointer
Operator = CSeg[SNum][IPtr].op.code1; // first instruction
// main interpreter loop
while ((Operator != RETP )&& // end of program
(Operator != NO_CODE)) // end of segment
{
switch (Operator)
{
case STATEMENT:
line_num = CSeg[SNum][IPtr].op.offset;
IPtr++;
if ((Debug_flag)&&(Trace_flag)&&(SNum != 0 ))
{
trace_statement_execution(
CSeg[SNum][IPtr].string.ptr, line_num);
}
break;
case EXITZ:
line_num = CSeg[SNum][IPtr].op.offset;
if (SSeg[SPtr].index == 0)
{
if (!Debug_flag)
printf("assert false on line: %d\n", line_num);
goto interpret_exit;
}
decr_sptr();
break;
case SKIP:
if (Set_no_trace)
{
Trace_flag = false;
Set_no_trace = false;
Skip_base_ptr = BPtr;
}
break;
case UNSKIP:
if (BPtr == Skip_base_ptr)
Trace_flag = true;
break;
case PUSH:
push();
break;
case POP:
pop();
break;
case CALL:
incr_sptr();
SSeg[SPtr].address.segment = SNum;
SSeg[SPtr].address.offset = IPtr;
SSeg[SPtr].address.ax = AX;
SSeg[SPtr].address.bx = BX;
SNum = CSeg[SNum][IPtr].op.segment;
IPtr = -1;
break;
case RETF:
SNum = SSeg[SPtr].address.segment;
IPtr = SSeg[SPtr].address.offset;
AX = SSeg[SPtr].address.ax;
BX = SSeg[SPtr].address.bx;
decr_sptr();
break;
case INC_sp:
incr_sptr();
break;
case INC_sp_string:
incr_sptr();
new_string();
break;
case DEC_sp:
decr_sptr();
break;
case DEC_sp_string:
delete_string();
decr_sptr();
break;
case ADD_xi_offset:
add_xi_offset();
break;
case ADD_xi_imm:
SSeg[SPtr].integer += CSeg[SNum][IPtr].op.offset;
break;
case MOV_ax_imm:
AX = CSeg[SNum][IPtr].op.offset;
break;
case MOV_bx_imm:
BX = CSeg[SNum][IPtr].op.offset;
break;
case MOV_bp_sp:
BPtr = SPtr;
break;
case PUT_str:
put_str();
break;
case GET_str:
get_str();
break;
case GET_item:
get_item();
break;
case FORMAT_STR:
format_str();
break;
case FORMAT_CHR:
format_chr();
break;
case FORMAT_INDEX:
format_index();
break;
case SET_file_ptr:
real_to_int();
File_ptr = (FILE *) SSeg[SPtr].integer;
decr_sptr();
break;
case SET_stdin:
File_ptr = stdin;
break;
case SET_stdout:
File_ptr = stdout;
break;
case FLUSH_stdin:
fflush(stdin);
break;
case RMUL:
SSeg[SPtr - 1].real = SSeg[SPtr - 1].real * SSeg[SPtr].real;
decr_sptr();
break;
case RDIV:
if (SSeg[SPtr].real == 0.0)
runtime_error(M_DIVISION, M_BY, M_ZERO, M_0);
SSeg[SPtr - 1].real = SSeg[SPtr - 1].real / SSeg[SPtr].real;
decr_sptr();
break;
case RADD:
SSeg[SPtr - 1].real = SSeg[SPtr - 1].real + SSeg[SPtr].real;
decr_sptr();
break;
case RSUB:
SSeg[SPtr - 1].real = SSeg[SPtr - 1].real - SSeg[SPtr].real;
decr_sptr();
break;
case RNEG:
SSeg[SPtr].real = - SSeg[SPtr].real;
break;
case RPOW:
if (SSeg[SPtr - 1].real <= 0.0)
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
SSeg[SPtr - 1].real = pow(SSeg[SPtr - 1].real, SSeg[SPtr].real);
decr_sptr();
break;
case IMUL:
real_to_int();
EAX = SSeg[SPtr].integer;
decr_sptr();
real_to_int();
SSeg[SPtr].integer = SSeg[SPtr].integer * EAX;
int_to_real();
break;
case IDIV:
real_to_int();
EAX = SSeg[SPtr].integer;
decr_sptr();
real_to_int();
if (EAX == 0)
runtime_error(M_DIVISION, M_BY, M_ZERO, M_0);
SSeg[SPtr].integer = SSeg[SPtr].integer / EAX;
int_to_real();
break;
case IADD:
real_to_int();
EAX = SSeg[SPtr].integer;
decr_sptr();
real_to_int();
SSeg[SPtr].integer = SSeg[SPtr].integer + EAX;
int_to_real();
break;
case ISUB:
real_to_int();
EAX = SSeg[SPtr].integer;
decr_sptr();
real_to_int();
SSeg[SPtr].integer = SSeg[SPtr].integer - EAX;
int_to_real();
break;
case INEG:
real_to_int();
SSeg[SPtr].integer = - SSeg[SPtr].integer;
int_to_real();
break;
case IPOW:
ipow();
break;
case IMOD:
real_to_int();
EAX = SSeg[SPtr].integer;
decr_sptr();
real_to_int();
if (EAX == 0)
runtime_error(M_DIVISION, M_BY, M_ZERO, M_0);
SSeg[SPtr].integer = SSeg[SPtr].integer % EAX;
int_to_real();
break;
case STRCAT:
str_cat();
break;
case TEST_NUMBER:
case TEST_INDEX:
case TEST_STRING:
case TEST_CHAR:
test();
break;
case LOGIC_NOT:
case LOGIC_OR:
case LOGIC_AND:
case LOGIC_NOR:
case LOGIC_NAND:
case LOGIC_XOR:
logic();
break;
case JMP:
IPtr = CSeg[SNum][IPtr].op.offset - 1;
break;
case JNZ:
AX = SSeg[SPtr].index;
decr_sptr();
if (AX != 0)
IPtr = CSeg[SNum][IPtr].op.offset - 1;
break;
case JZ:
AX = SSeg[SPtr].index;
decr_sptr();
if (AX == 0)
IPtr = CSeg[SNum][IPtr].op.offset - 1;
break;
case CALL_stnd:
standard_routine();
break;
default:
SNum = SNum;
assert(0);
break;
}
if (kbhit())
{
if (getch() == 27) /* Esc */
goto interpret_exit;
}
IPtr++;
Operator = CSeg[SNum][IPtr].op.code1;
}
interpret_exit:
return;
}
/*
* "push" interprets push command by calling appropriate
* interpreter routines.
*
* returns: nothing
*/
void push()
{
int xi;
Operator = CSeg[SNum][IPtr].op.code2;
int segment = CSeg[SNum][IPtr].op.segment;
int offset = CSeg[SNum][IPtr].op.offset;
switch (Operator)
{
case REG_BP:
incr_sptr();
SSeg[SPtr].index = BPtr;
break;
case IMM_64:
IPtr++;
incr_sptr();
SSeg[SPtr].real = CSeg[SNum][IPtr].real;
break;
case IMM_32:
IPtr++;
incr_sptr();
SSeg[SPtr].integer = CSeg[SNum][IPtr].integer;
int_to_real();
break;
case IMM_16:
IPtr++;
incr_sptr();
SSeg[SPtr].index = CSeg[SNum][IPtr].index;
break;
case IMM_8:
IPtr++;
incr_sptr();
SSeg[SPtr].byte = CSeg[SNum][IPtr].byte;
break;
case IMM_STR:
IPtr++;
incr_sptr();
new_string();
strcpy(SSeg[SPtr].string.ptr, CSeg[SNum][IPtr].string.ptr);
break;
case ADDR:
if (segment != 0)
offset = offset + BPtr; // abs stack address
incr_sptr();
SSeg[SPtr].address.segment = segment;
SSeg[SPtr].address.offset = offset;
break;
case ADDR_ADDR:
if (segment != 0)
offset = offset + BPtr; // abs stack address
incr_sptr();
SSeg[SPtr].address.segment = SSeg[offset].address.segment;
SSeg[SPtr].address.offset = SSeg[offset].address.offset;
break;
case MEM_64:
incr_sptr();
if (segment == 0)
SSeg[SPtr].real = DSeg[offset].real;
else
SSeg[SPtr].real = SSeg[offset + BPtr].real;
break;
case MEM_32:
incr_sptr();
if (segment == 0)
{
SSeg[SPtr].integer = DSeg[offset].integer;
int_to_real();
}
else
SSeg[SPtr].real = SSeg[offset + BPtr].real;
break;
case MEM_16:
incr_sptr();
if (segment == 0)
SSeg[SPtr].index = DSeg[offset].index;
else
SSeg[SPtr].index = SSeg[offset + BPtr].index;
break;
case MEM_8:
incr_sptr();
if (segment == 0)
SSeg[SPtr].byte = DSeg[offset].byte;
else
SSeg[SPtr].byte = SSeg[offset + BPtr].byte;
break;
case MEM_STR:
incr_sptr();
new_string();
if (segment == 0)
strcpy(SSeg[SPtr].string.ptr, DSeg[offset].string.ptr);
else
strcpy(SSeg[SPtr].string.ptr, SSeg[offset + BPtr].string.ptr);
break;
case MEM_64_xi:
xi = (int)SSeg[SPtr].integer; // replace XI instead of incr SPtr
if (segment == 0)
SSeg[SPtr].real = DSeg[offset + xi].real;
else
SSeg[SPtr].real = SSeg[offset + xi + BPtr].real;
break;
case MEM_32_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
{
SSeg[SPtr].integer = DSeg[offset + xi].integer;
int_to_real();
}
else
SSeg[SPtr].real = SSeg[offset + xi + BPtr].real;
break;
case MEM_16_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
SSeg[SPtr].index = DSeg[offset + xi].index;
else
SSeg[SPtr].index = SSeg[offset + xi + BPtr].index;
break;
case MEM_8_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
SSeg[SPtr].byte = DSeg[offset + xi].byte;
else
SSeg[SPtr].byte = SSeg[offset + xi + BPtr].byte;
break;
case MEM_STR_8_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
SSeg[SPtr].byte = DSeg[offset].string.ptr[xi];
else
SSeg[SPtr].byte = SSeg[offset + BPtr].string.ptr[xi];
break;
case MEM_STR_xi:
xi = (int)SSeg[SPtr].integer;
new_string();
if (segment == 0)
strcpy(SSeg[SPtr].string.ptr, DSeg[offset + xi].string.ptr);
else
strcpy(SSeg[SPtr].string.ptr, SSeg[offset + xi + BPtr].string.ptr);
break;
case PTR_64:
case PTR_32:
case PTR_16:
case PTR_8:
case PTR_STR:
case PTR_64_xi:
case PTR_32_xi:
case PTR_16_xi:
case PTR_8_xi:
case PTR_STR_8_xi:
case PTR_STR_xi:
if (segment == 0)
{
segment = DSeg[offset].address.segment;
offset = DSeg[offset].address.offset;
}
else
{
segment = SSeg[offset + BPtr].address.segment;
offset = SSeg[offset + BPtr].address.offset;
}
switch (Operator)
{
case PTR_64:
incr_sptr();
if (segment == 0)
SSeg[SPtr].real = DSeg[offset].real;
else
SSeg[SPtr].real = SSeg[offset].real;
break;
case PTR_32:
incr_sptr();
if (segment == 0)
{
SSeg[SPtr].integer = DSeg[offset].integer;
int_to_real();
}
else
SSeg[SPtr].real = SSeg[offset].real;
break;
case PTR_16:
incr_sptr();
if (segment == 0)
SSeg[SPtr].index = DSeg[offset].index;
else
SSeg[SPtr].index = SSeg[offset].index;
break;
case PTR_8:
incr_sptr();
if (segment == 0)
SSeg[SPtr].byte = DSeg[offset].byte;
else
SSeg[SPtr].byte = SSeg[offset].byte;
break;
case PTR_STR:
incr_sptr();
new_string();
if (segment == 0)
strcpy(SSeg[SPtr].string.ptr, DSeg[offset].string.ptr);
else
strcpy(SSeg[SPtr].string.ptr, SSeg[offset].string.ptr);
break;
case PTR_64_xi:
xi = (int)SSeg[SPtr].integer; // replace XI instead of incr SPtr
if (segment == 0)
SSeg[SPtr].real = DSeg[offset + xi].real;
else
SSeg[SPtr].real = SSeg[offset + xi].real;
break;
case PTR_32_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
{
SSeg[SPtr].integer = DSeg[offset + xi].integer;
int_to_real();
}
else
SSeg[SPtr].real = SSeg[offset + xi].real;
break;
case PTR_16_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
SSeg[SPtr].index = DSeg[offset + xi].index;
else
SSeg[SPtr].index = SSeg[offset + xi].index;
break;
case PTR_8_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
SSeg[SPtr].byte = DSeg[offset + xi].byte;
else
SSeg[SPtr].byte = SSeg[offset + xi].byte;
break;
case PTR_STR_8_xi:
xi = (int)SSeg[SPtr].integer;
if (segment == 0)
SSeg[SPtr].byte = DSeg[offset].string.ptr[xi];
else
SSeg[SPtr].byte = SSeg[offset].string.ptr[xi];
break;
case PTR_STR_xi:
xi = (int)SSeg[SPtr].integer;
new_string();
if (segment == 0)
strcpy(SSeg[SPtr].string.ptr, DSeg[offset + xi].string.ptr);
else
strcpy(SSeg[SPtr].string.ptr, SSeg[offset + xi].string.ptr);
break;
}
break;
default:
assert(0);
break;
}
}
/*
* "pop" interprets pop command by calling appropriate
* interpreter routines.
*
* returns: nothing
*/
void pop()
{
int xi;
Operator = CSeg[SNum][IPtr].op.code2;
int offset = CSeg[SNum][IPtr].op.offset;
int segment = CSeg[SNum][IPtr].op.segment;
switch (Operator)
{
case REG_BP:
BPtr = SSeg[SPtr].index;
decr_sptr();
break;
case MEM_64:
if (segment == 0)
DSeg[offset].real = SSeg[SPtr].real;
else
SSeg[offset + BPtr].real = SSeg[SPtr].real;
decr_sptr();
break;
case MEM_32:
real_to_int();
if (segment == 0)
DSeg[offset].integer = SSeg[SPtr].integer;
else
SSeg[offset + BPtr].real = (double) SSeg[SPtr].integer;
decr_sptr();
break;
case MEM_16:
if (segment == 0)
DSeg[offset].index = SSeg[SPtr].index;
else
SSeg[offset + BPtr].index = SSeg[SPtr].index;
decr_sptr();
break;
case MEM_8:
if (segment == 0)
DSeg[offset].byte = SSeg[SPtr].byte;
else
SSeg[offset + BPtr].byte = SSeg[SPtr].byte;
decr_sptr();
break;
case MEM_STR:
strcpy(String, SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
if (segment == 0)
{
assert(DSeg[offset].string.sig == SIGNATURE);
if (strlen(String) < DSeg[offset].string.len)
strcpy(DSeg[offset].string.ptr, String);
else
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
}
else
{
assert(SSeg[offset + BPtr].string.sig == SIGNATURE);
strcpy(SSeg[offset + BPtr].string.ptr, String);
}
break;
case MEM_64_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset + xi].real = SSeg[SPtr].real;
else
SSeg[offset + xi + BPtr].real = SSeg[SPtr].real;
decr_sptr();
decr_sptr();
break;
case MEM_32_xi:
xi = (int)SSeg[SPtr-1].integer; // XI is below data
real_to_int();
if (segment == 0)
DSeg[offset + xi].integer = SSeg[SPtr].integer;
else
SSeg[offset + xi + BPtr].real = (double) SSeg[SPtr].integer;
decr_sptr();
decr_sptr(); // need additional pop to remove XI
break;
case MEM_16_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset + xi].index = SSeg[SPtr].index;
else
SSeg[offset + xi + BPtr].index = SSeg[SPtr].index;
decr_sptr();
decr_sptr();
break;
case MEM_8_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset + xi].byte = SSeg[SPtr].byte;
else
SSeg[offset + xi + BPtr].byte = SSeg[SPtr].byte;
decr_sptr();
decr_sptr();
break;
case MEM_STR_8_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset].string.ptr[xi] = SSeg[SPtr].byte;
else
SSeg[offset + BPtr].string.ptr[xi] = SSeg[SPtr].byte;
decr_sptr();
decr_sptr();
break;
case MEM_STR_xi:
xi = (int)SSeg[SPtr-1].integer;
strcpy(String, SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
decr_sptr();
if (segment == 0)
{
assert(DSeg[offset + xi].string.sig == SIGNATURE);
if (strlen(String) < DSeg[offset + xi].string.len)
strcpy(DSeg[offset + xi].string.ptr, String);
else
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
}
else
{
assert(SSeg[offset + xi + BPtr].string.sig == SIGNATURE);
strcpy(SSeg[offset + xi + BPtr].string.ptr, String);
}
break;
case PTR_64:
case PTR_32:
case PTR_16:
case PTR_8:
case PTR_STR:
case PTR_64_xi:
case PTR_32_xi:
case PTR_16_xi:
case PTR_8_xi:
case PTR_STR_8_xi:
case PTR_STR_xi:
if (segment == 0)
{
segment = DSeg[offset].address.segment;
offset = DSeg[offset].address.offset;
}
else
{
segment = SSeg[offset + BPtr].address.segment;
offset = SSeg[offset + BPtr].address.offset;
}
switch (Operator)
{
case PTR_64:
if (segment == 0)
DSeg[offset].real = SSeg[SPtr].real;
else
SSeg[offset].real = SSeg[SPtr].real;
decr_sptr();
break;
case PTR_32:
real_to_int();
if (segment == 0)
DSeg[offset].integer = SSeg[SPtr].integer;
else
SSeg[offset].real = (double) SSeg[SPtr].integer;
decr_sptr();
break;
case PTR_16:
if (segment == 0)
DSeg[offset].index = SSeg[SPtr].index;
else
SSeg[offset].index = SSeg[SPtr].index;
decr_sptr();
break;
case PTR_8:
if (segment == 0)
DSeg[offset].byte = SSeg[SPtr].byte;
else
SSeg[offset].byte = SSeg[SPtr].byte;
decr_sptr();
break;
case PTR_STR:
strcpy(String, SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
if (segment == 0)
{
assert(DSeg[offset].string.sig == SIGNATURE);
if (strlen(String) < DSeg[offset].string.len)
strcpy(DSeg[offset].string.ptr, String);
else
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
}
else
{
assert(SSeg[offset].string.sig == SIGNATURE);
strcpy(SSeg[offset].string.ptr, String);
}
break;
case PTR_64_xi:
xi = (int)SSeg[SPtr-1].integer; // XI is below data
if (segment == 0)
DSeg[offset + xi].real = SSeg[SPtr].real;
else
SSeg[offset + xi].real = SSeg[SPtr].real;
decr_sptr();
decr_sptr(); // need additional pop to remove XI
break;
case PTR_32_xi:
xi = (int)SSeg[SPtr-1].integer;
real_to_int();
if (segment == 0)
DSeg[offset + xi].integer = SSeg[SPtr].integer;
else
SSeg[offset + xi].real = (double) SSeg[SPtr].integer;
decr_sptr();
decr_sptr();
break;
case PTR_16_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset + xi].index = SSeg[SPtr].index;
else
SSeg[offset + xi].index = SSeg[SPtr].index;
decr_sptr();
decr_sptr();
break;
case PTR_8_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset + xi].byte = SSeg[SPtr].byte;
else
SSeg[offset + xi].byte = SSeg[SPtr].byte;
decr_sptr();
decr_sptr();
break;
case PTR_STR_8_xi:
xi = (int)SSeg[SPtr-1].integer;
if (segment == 0)
DSeg[offset].string.ptr[xi] = SSeg[SPtr].byte;
else
SSeg[offset].string.ptr[xi] = SSeg[SPtr].byte;
decr_sptr();
decr_sptr();
break;
case PTR_STR_xi:
xi = (int)SSeg[SPtr-1].integer;
strcpy(String, SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
decr_sptr();
if (segment == 0)
{
assert(DSeg[offset + xi].string.sig == SIGNATURE);
if (strlen(String) < DSeg[offset + xi].string.len)
strcpy(DSeg[offset].string.ptr, String);
else
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
}
else
{
assert(SSeg[offset + xi].string.sig == SIGNATURE);
strcpy(SSeg[offset + xi].string.ptr, String);
}
break;
}
break;
default:
assert(0);
break;
}
}
/*
* "test" interprets test commands which compare the top two
* stack values.
*
* returns: nothing
*/
void test()
{
switch (Operator)
{
case TEST_INDEX:
AX = SSeg[SPtr].index;
decr_sptr();
AX = SSeg[SPtr].index - AX;
if (AX == 0)
SSeg[SPtr].index = 0;
else if (AX > 0)
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = -1;
break;
case TEST_NUMBER:
DEAX = SSeg[SPtr].real;
decr_sptr();
DEAX = SSeg[SPtr].real - DEAX;
if (DEAX == 0.0)
SSeg[SPtr].index = 0;
else if (DEAX > 0.0)
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = -1;
break;
case TEST_STRING:
strcpy(String, SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
AX = strcmp(SSeg[SPtr].string.ptr, String);
delete_string();
SSeg[SPtr].index = AX;
break;
case TEST_CHAR:
AL = SSeg[SPtr].byte;
decr_sptr();
AL = SSeg[SPtr].byte - AL;
if (AL == 0)
SSeg[SPtr].index = 0;
else if (AL > 0)
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = -1;
break;
}
Operator = CSeg[SNum][IPtr].op.code2;
switch (Operator)
{
case TEST_EQ:
if (SSeg[SPtr].index == 0)
SSeg[SPtr].index = 1; // true
else
SSeg[SPtr].index = 0; // false
break;
case TEST_NE:
if (SSeg[SPtr].index != 0)
SSeg[SPtr].index = 1; // true
else
SSeg[SPtr].index = 0; // false
break;
case TEST_GT:
if (SSeg[SPtr].index > 0)
SSeg[SPtr].index = 1; // true
else
SSeg[SPtr].index = 0; // false
break;
case TEST_GE:
if (SSeg[SPtr].index >= 0)
SSeg[SPtr].index = 1; // true
else
SSeg[SPtr].index = 0; // false
break;
case TEST_LT:
if (SSeg[SPtr].index < 0)
SSeg[SPtr].index = 1; // true
else
SSeg[SPtr].index = 0; // false
break;
case TEST_LE:
if (SSeg[SPtr].index <= 0)
SSeg[SPtr].index = 1; // true
else
SSeg[SPtr].index = 0; // false
break;
default:
assert(0);
break;
}
}
/*
* "add_xi_offset" adds array index value to offset for
* data structure element
*
* returns: nothing
*/
void add_xi_offset()
{
real_to_int(); // index at SP
// XI is at SP-1 now
if( 0 <= SSeg[SPtr].integer && SSeg[SPtr].integer <= AX )
SSeg[SPtr-1].integer += SSeg[SPtr].integer * BX;
else
runtime_error(M_INTEGER, M_OUT, M_OF, M_RANGE, M_0);
decr_sptr();
}
void put_str()
{
if ((Debug_flag == true) && (File_ptr == stdout))
write_to_user_screen(SSeg[SPtr].string.ptr);
else
fprintf(File_ptr, "%s", SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
}
void get_str()
{
int get_width;
char *eol_ptr;
get_width = SSeg[SPtr].real;
decr_sptr();
if ((get_width < 0) || (get_width > MAX_STRING_LENGTH))
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
if (Debug_flag && (File_ptr == stdin)) // swap screens
debug_to_user_screen();
fgets(String, get_width + 1, File_ptr);
if (Debug_flag && (File_ptr == stdin)) // re-swap screens
user_to_debug_screen();
// remove any new line character
eol_ptr = strchr(String, '\n');
if (eol_ptr)
*eol_ptr = NULL;
incr_sptr();
new_string();
strcpy(SSeg[SPtr].string.ptr, String);
}
void get_item()
{
if (Debug_flag && (File_ptr == stdin)) // swap screens
debug_to_user_screen();
fscanf(File_ptr, "%s", String);
if (Debug_flag && (File_ptr == stdin)) // re-swap screens
user_to_debug_screen();
incr_sptr();
new_string();
strcpy(SSeg[SPtr].string.ptr, String);
}
void format_str()
{
int str_width = (int)SSeg[SPtr].real;
decr_sptr();
if (str_width > MAX_STRING_LENGTH)
str_width = MAX_STRING_LENGTH;
sprintf(String, "%-*s", str_width, SSeg[SPtr].string.ptr);
strcpy(SSeg[SPtr].string.ptr, String);
}
void format_chr()
{
int str_width = (int)SSeg[SPtr].real;
decr_sptr();
if (str_width > MAX_STRING_LENGTH)
str_width = MAX_STRING_LENGTH;
char byte = SSeg[SPtr].byte;
new_string();
SSeg[SPtr].string.ptr[0] = byte;
SSeg[SPtr].string.ptr[1] = NULL;
sprintf(String, "%-*s", str_width, SSeg[SPtr].string.ptr);
strcpy(SSeg[SPtr].string.ptr, String);
}
void format_index()
{
int str_width = (int) SSeg[SPtr].real;
decr_sptr();
if (str_width > MAX_STRING_LENGTH)
str_width = MAX_STRING_LENGTH;
int index = SSeg[SPtr].index;
new_string();
sprintf(String, "%-*d", str_width, index);
strcpy(SSeg[SPtr].string.ptr, String);
}
void new_string()
{
// already allocated?
assert(SSeg[SPtr].string.sig != SIGNATURE);
char *ptr = new char[MAX_STRING_LENGTH];
if (ptr)
{
SSeg[SPtr].string.ptr = ptr;
SSeg[SPtr].string.len = MAX_STRING_LENGTH;
SSeg[SPtr].string.sig = SIGNATURE;
}
else
runtime_error(M_OUT, M_OF, M_MEMORY, M_0);
}
void delete_string()
{
// allocated?
assert(SSeg[SPtr].string.sig == SIGNATURE);
delete SSeg[SPtr].string.ptr;
SSeg[SPtr].string.ptr = NULL;
SSeg[SPtr].string.len = 0;
SSeg[SPtr].string.sig = 0;
}
void ipow()
{
real_to_int();
long integer = SSeg[SPtr].integer;
decr_sptr();
real_to_int();
if (SSeg[SPtr].integer <= 0.0)
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
else
{
long base = 1;
for (long i = integer; i > 0; i--)
base = base*SSeg[SPtr].integer;
SSeg[SPtr].integer = base;
int_to_real();
}
}
void str_cat()
{
int length = strlen(SSeg[SPtr].string.ptr);
strcpy(String, SSeg[SPtr].string.ptr);
delete_string();
decr_sptr();
length += strlen(SSeg[SPtr].string.ptr);
if (length <= MAX_STRING_LENGTH)
strcat(SSeg[SPtr].string.ptr, String);
else
runtime_error(M_VALUE, M_OUT, M_OF, M_RANGE, M_0);
}
void logic()
{
int index = SSeg[SPtr].index;
decr_sptr();
switch (Operator)
{
case LOGIC_NOT:
incr_sptr();
if (index)
SSeg[SPtr].index = 0;
else
SSeg[SPtr].index = 1;
break;
case LOGIC_OR:
if (SSeg[SPtr].index || index)
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = 0;
break;
case LOGIC_NOR:
if (!(SSeg[SPtr].index || index))
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = 0;
break;
case LOGIC_AND:
if (SSeg[SPtr].index && index)
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = 0;
break;
case LOGIC_NAND:
if (!(SSeg[SPtr].index && index))
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = 0;
break;
case LOGIC_XOR:
if ((!SSeg[SPtr].index && index) || ( SSeg[SPtr].index && !index))
SSeg[SPtr].index = 1;
else
SSeg[SPtr].index = 0;
break;
}
}
/*
* "debug_to_user_screen" replaces the debug screen with the
* user screen
*
* returns: nothing
*/
void debug_to_user_screen()
{
gettext(1, 1, 80, 25, Debug_screen); // save debug screen
puttext(1, 1, 80, 25, User_screen); // restore user screen
gotoxy(User_col + 1, User_lin + 1); // restore cursor
_setcursortype(_NORMALCURSOR);
}
/*
* "user_to_debug_screen" replaces the user screen with the
* debug screen
*
* returns: nothing
*/
void user_to_debug_screen()
{
User_col = wherex() - 1; // save cursor location
User_lin = wherey() - 1;
gettext(1, 1, 80, 25, User_screen); // save user screen
puttext(1, 1, 80, 25, Debug_screen); // restore debug screen
_setcursortype(_NOCURSOR);
}
/*
* "write_to_user_screen" writes a string to the user screen buffer
* and updates values representing the cursor as if it were on
* the screen
*
* returns: nothing
*/
void write_to_user_screen(char *string) // item to write
{
int i = 0;
while (string[i] != NULL)
{
int j = 2*(80*User_lin + User_col);
if (string[i] == '\n')
{
i++;
User_col = 0;
User_lin++;
}
else if (string[i] == '\t')
{
i++;
User_col += 8;
}
else
{
User_screen[j] = string[i];
i++;
User_col++;
}
if (User_col > 79)
{
User_col = 0;
User_lin++;
}
if (User_lin > 24)
{
User_lin = 24;
move_up_user_screen();
}
}
}
/*
* "move_up_user_screen" shifts all characters in the user screen
* up by one line and clears the bottom line
*
* returns: nothing
*/
void move_up_user_screen()
{
int i;
for (i = 160; i < 4000; i++) // shift screen up
User_screen[i - 160] = User_screen[i];
for (i = 3840; i < 4000; i += 2) // clear bottom line
User_screen[i] = ' ';
}
| home
| contents
| previous
| next page
| send comment
| send link
| add bookmark |
Copyright © 2004, Stephen R. Schmitt