/*
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: globals.c *
* *
* Description: This file contains the function and variable *
* definitions for the global symbols. *
************************************************************************/
# include <string.h>
# include "trap.h"
# include "execute.h"
# include "functab.h"
# include "globals.h"
# include "allocate.h"
# include "consttab.h"
# include "our-stdlib.h"
/* Symbol tables for global symbols. */
st var_st;
st str_st;
st dbl_st;
st field_st;
st import_st;
/* Current sizes of global symbol arrays. */
unsigned var_array_size;
unsigned str_array_size;
unsigned dbl_array_size;
/* Global symbol arrays. */
descriptor *var_array;
char **str_array;
double *dbl_array;
static int constant_handler PROTO ((descriptor *, descriptor **));
/************************************************************************
* Function: constant_handler *
* *
* Description: Trapped variable handler for enumeration constants. *
************************************************************************/
static int constant_handler (dest, src)
descriptor *dest;
descriptor **src;
{
/* This data is never recycled. */
if (!src)
return 0;
/* This data is read-only. */
TypeError ("cannot assign to constant", NULL, NULL, NULL, F_False);
return 1;
}
/************************************************************************
* Function: add_literal *
* *
* Description: Adds a literal to the given symbol table and stores the *
* value in the global symbol arrays. The arrays are *
* reallocated if necessary (this is ok because the *
* instructions contain an index into these arrays, not an *
* address). *
************************************************************************/
ste *add_literal (table, name, op)
st *table;
char *name;
Opcode op;
{
ste *s;
if (!(s = st_lookup (table, name)))
if (table != &str_st && table != &dbl_st)
s = st_lookup (&import_st, name);
if (!s) {
s = st_insert (table, name, op);
if (table == &var_st) {
if (s -> idx >= var_array_size) {
var_array_size = var_array_size ? var_array_size << 1 : 16;
Reallocate (var_array, descriptor, var_array_size);
}
CreateData (&var_array [s -> idx], NULL, NULL, T_Null);
s -> op = GlblOp;
} else if (table == &str_st) {
if (s -> idx >= str_array_size) {
str_array_size = str_array_size ? str_array_size << 1 : 16;
Reallocate (str_array, char *, str_array_size);
}
str_array [s -> idx] = Strdup (name);
} else if (table == &dbl_st) {
if (s -> idx >= dbl_array_size) {
dbl_array_size = dbl_array_size ? dbl_array_size << 1 : 16;
Reallocate (dbl_array, double, dbl_array_size);
}
dbl_array [s -> idx] = strtod (name, NULL);
}
}
return s;
}
/************************************************************************
* Function: global_init *
* *
* Description: Initializes the global symbol tables. *
************************************************************************/
void global_init ( )
{
int i;
char buffer [32];
ste *s;
descriptor *d;
st_init (&var_st);
st_init (&str_st);
st_init (&dbl_st);
st_init (&field_st);
st_init (&import_st);
add_literal (&dbl_st, "0", DblOp);
add_literal (&dbl_st, "1", DblOp);
add_literal (&field_st, "", FieldOp);
for (i = 0; i < NumIntrinsics; i ++) {
d = &var_array [add_literal (&var_st, functab [i].name, GlblOp) -> idx];
D_Type (d) = T_Intrinsic;
D_Temp (d) = F_False;
D_Trapped (d) = F_False;
D_Intrinsic (d) = i;
}
for (i = 0; i < NumConstants; i ++) {
d = &var_array [add_literal (&var_st, consttab [i].name, GlblOp) -> idx];
sprintf (buffer, "%g", consttab [i].value),
s = add_literal (&dbl_st, buffer, DblOp);
D_Type (d) = T_Double;
D_Temp (d) = F_False;
D_Trapped (d) = AddTrap (constant_handler);
D_Double (d) = &dbl_array [s -> idx];
}
d = &var_array [add_literal (&var_st, "&null", GlblOp) -> idx];
D_Type (d) = T_Null;
D_Temp (d) = F_False;
D_Trapped (d) = AddTrap (constant_handler);
D_Pointer (d) = NULL;
}
/************************************************************************
* Function: is_global *
* *
* Description: Returns whether the specified variable is a global *
* variable. *
************************************************************************/
int is_global (var)
descriptor *var;
{
return var_array <= var && var < var_array + var_st.num_syms;
}
syntax highlighted by Code2HTML, v. 0.9.1