/*
This file is part of the FElt finite element analysis package.
Copyright (C) 1993-2000 Jason I. Gobat and Darren C. Atkinson
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/************************************************************************
* File: execute.c *
* *
* Description: This file contains the public and private function and *
* variable definitions for execution of the virtual *
* machine code. *
************************************************************************/
# include <string.h>
# include "debug.h"
# include "error.h"
# include "status.h"
# include "execute.h"
# include "exectab.h"
# include VAR_ARGS_INCLUDE
# ifndef StackSize
# define StackSize 4096
# endif
static descriptor the_stack [StackSize];
Address pc;
descriptor *varp;
descriptor *argp = the_stack;
descriptor *sp = the_stack;
descriptor *stack = the_stack;
/************************************************************************
* Function: SaveState *
* *
* Description: Saves the current state of the virtual machine. *
************************************************************************/
void SaveState (state)
ExecState *state;
{
state -> pc = pc;
state -> cs = cs;
state -> sp = sp;
state -> argp = argp;
state -> varp = varp;
state -> line = curr_line_num;
state -> file = curr_file_num;
}
/************************************************************************
* Function: RestoreState *
* *
* Description: Restores previously saved state information. *
************************************************************************/
void RestoreState (state)
ExecState *state;
{
pc = state -> pc;
cs = state -> cs;
sp = state -> sp;
argp = state -> argp;
varp = state -> varp;
curr_line_num = state -> line;
curr_file_num = state -> file;
curr_file_name = *strlit (curr_file_num);
}
/************************************************************************
* Function: execute *
* *
* Description: Executes a code segment of the virtual machine. *
************************************************************************/
int execute (code, vars, args)
Code code;
descriptor *vars;
descriptor *args;
{
ExecState state;
int status;
SaveState (&state);
pc = 0;
cs = code;
varp = vars;
argp = args;
while ((status = exectab [fetch (pc ++).op] ( )) == 0);
RestoreState (&state);
d_printf ("clearing stack\n");
while (sp != state.sp)
RecycleData (pop ( ));
return status;
}
/************************************************************************
* Function: TypeError *
* *
* Description: Reports a type error for an operator or function. *
************************************************************************/
void TypeError (op, a, b, c, is_func)
char *op;
descriptor *a;
descriptor *b;
descriptor *c;
int is_func;
{
char *a_type;
char *b_type;
char *c_type;
char *msg = "type error in expression";
a_type = a ? D_TypeName (a) : "";
b_type = b ? D_TypeName (b) : "";
c_type = c ? D_TypeName (c) : "";
if (is_func == F_False) {
if (a && b && c)
rterror ("%s: %s %s %s %s %s", msg, a_type, op, b_type, op, c_type);
else if (a && c)
rterror ("%s: %s %s %s", msg, a_type, op, c_type);
else if (a && b)
rterror ("%s: %s %s %s", msg, a_type, op, b_type);
else if (a)
rterror ("%s: %s %s", msg, a_type, op);
else if (b)
rterror ("%s: %s %s", msg, op, b_type);
else
rterror ("%s: %s", msg, op);
} else {
if (a && b && c)
rterror ("%s: %s (%s, %s, %s)", msg, op, a_type, b_type, c_type);
else if (a && b)
rterror ("%s: %s (%s, %s)", msg, op, a_type, b_type);
else if (a)
rterror ("%s: %s (%s)", msg, op, a_type);
else
rterror ("%s: %s ()", msg, op);
}
}
/************************************************************************
* Function: MatrixError *
* *
* Description: Reports a matrix error. *
************************************************************************/
void MatrixError (op, a, b, s, is_func)
char *op;
Matrix a;
Matrix b;
int s;
int is_func;
{
char *msg;
char a_size [32];
char b_size [32];
if (a)
sprintf (a_size, "(%u x %u)", Mrows (a), Mcols (a));
else
sprintf (a_size, "(1 x 1)");
if (b)
sprintf (b_size, "(%u x %u)", Mrows (b), Mcols (b));
else
sprintf (b_size, "(1 x 1)");
msg = is_func == F_True ? "() function" : " expression";
switch (s) {
case M_RDONLY:
rterror ("read only matrix in expression (op = %s)", op);
break;
case M_COMPACT:
rterror ("compact matrix unexpected in %s%s", op, msg);
break;
case M_FULL:
rterror ("full matrix unexpected in %s%s", op, msg);
break;
case M_NOTSYMMETRIC:
rterror ("symmetric matrix required in %s%s", op, msg);
break;
case M_SIZEMISMATCH:
if (is_func == F_True)
rterror ("argument size mismatch in %s() function: %s", op, a_size);
else
rterror ("size mismatch in expression: %s %s %s", a_size,op,b_size);
break;
case M_NOTCOLUMN:
rterror ("column vector required in %s%s", op, msg);
break;
case M_NOTROW:
rterror ("row vector required in %s%s", op, msg);
break;
case M_NOTSQUARE:
rterror ("square matrix required in %s%s", op, msg);
break;
case M_NOOVERWRITE:
rterror ("cannot overwrite matrix (op = %s)", op);
break;
case M_NOTEXIST:
rterror ("matrix does not exist (op = %s)", op);
break;
case M_NOTFULL:
rterror ("full matrix required in %s%s", op, msg);
break;
case M_NOTCOMPACT:
rterror ("compact matrix required in %s%s", op, msg);
break;
case M_BADSUBSECTION:
rterror ("illegal subsection (op = %s)", op);
break;
case M_NOTPOSITIVEDEFINITE:
rterror ("positive definite matrix required in %s%s", op, msg);
break;
default:
rterror ("unknown matrix error (op=%s)", op);
break;
}
}
/************************************************************************
* Function: MathException *
* *
* Description: Reports a mathematic exception. *
************************************************************************/
void MathException (s)
char *s;
{
rterror ("exception in expression: %s", s);
}
syntax highlighted by Code2HTML, v. 0.9.1