Пример #1
0
JAM_RETURN_TYPE jam_init_stack(void)

/*																			*/
/*	Description:	Initialize the stack.  The stack is located after the	*/
/*					symbol table in the workspace buffer.					*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, else appropriate error code	*/
/*																			*/
/****************************************************************************/
{
	int index = 0;
	int size = 0;
	JAM_RETURN_TYPE return_code = JAMC_SUCCESS;
	void **symbol_table = NULL;

	if (jam_workspace != NULL)
	{
		symbol_table = (void **) jam_workspace;
		jam_stack = (JAMS_STACK_RECORD *) &symbol_table[JAMC_MAX_SYMBOL_COUNT];

		size = (JAMC_MAX_SYMBOL_COUNT * sizeof(void *)) +
			(JAMC_MAX_NESTING_DEPTH * sizeof(JAMS_STACK_RECORD));

		if (jam_workspace_size < size)
		{
			return_code = JAMC_OUT_OF_MEMORY;
		}
	}
	else
	{
		jam_stack = jam_malloc(
			JAMC_MAX_NESTING_DEPTH * sizeof(JAMS_STACK_RECORD));

		if (jam_stack == NULL)
		{
			return_code = JAMC_OUT_OF_MEMORY;
		}
	}

	if (return_code == JAMC_SUCCESS)
	{
		for (index = 0; index < JAMC_MAX_NESTING_DEPTH; ++index)
		{
			jam_stack[index].type = JAM_ILLEGAL_STACK_TYPE;
			jam_stack[index].iterator = (JAMS_SYMBOL_RECORD *) 0;
			jam_stack[index].for_position = 0L;
			jam_stack[index].stop_value = 0L;
			jam_stack[index].step_value = 0L;
			jam_stack[index].push_value = 0L;
			jam_stack[index].return_position = 0L;
		}
	}

	return (return_code);
}
Пример #2
0
JAM_RETURN_TYPE jam_init_symbol_table()

/*																			*/
/*	Description:	Initializes the symbol table.  The symbol table is		*/
/*					located at the beginning of the workspace buffer.		*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if the	*/
/*					size of the workspace buffer is too small to hold the	*/
/*					desired number of symbol records.						*/
/*																			*/
/****************************************************************************/
{
	int index = 0;
	JAM_RETURN_TYPE status = JAMC_SUCCESS;

	if (jam_workspace != NULL)
	{
		jam_symbol_table = (JAMS_SYMBOL_RECORD **) jam_workspace;

		jam_symbol_bottom = (void *) (((long)jam_workspace) +
			((long)jam_workspace_size));

		if (jam_workspace_size <
			(JAMC_MAX_SYMBOL_COUNT * sizeof(void *)))
		{
			status = JAMC_OUT_OF_MEMORY;
		}
	}
	else
	{
		jam_symbol_table = (JAMS_SYMBOL_RECORD **) jam_malloc(
			(JAMC_MAX_SYMBOL_COUNT * sizeof(void *)));

		if (jam_symbol_table == NULL)
		{
			status = JAMC_OUT_OF_MEMORY;
		}
	}

	if (status == JAMC_SUCCESS)
	{
		for (index = 0; index < JAMC_MAX_SYMBOL_COUNT; ++index)
		{
			jam_symbol_table[index] = NULL;
		}
	}

	return (status);
}
Пример #3
0
JAM_RETURN_TYPE jam_add_symbol
(
	JAME_SYMBOL_TYPE type,
	char *name,
	long value,
	long position
)

/*																			*/
/*	Description:	Adds a new symbol to the symbol table.  If the symbol	*/
/*					name already exists in the symbol table, it is an error	*/
/*					unless the symbol type and the position in the file		*/
/*					where the symbol was declared are identical.  This is	*/
/*					necessary to allow labels and variable declarations		*/
/*					inside loops and subroutines where they may be			*/
/*					encountered multiple times.								*/
/*																			*/
/*	Returns:		JAMC_SUCCESS for success, or JAMC_REDEFINED_SYMBOL		*/
/*					if symbol was already declared elsewhere, or			*/
/*					JAMC_OUT_OF_MEMORY if symbol table is full.				*/
/*																			*/
/****************************************************************************/
{
	char r, l;
	int ch_index = 0;
	int hash = 0;
	long init_list_value = 0L;
	BOOL match = FALSE;
	BOOL identical_redeclaration = FALSE;
	JAM_RETURN_TYPE status = JAMC_SUCCESS;
	JAMS_SYMBOL_RECORD *symbol_record = NULL;
	JAMS_SYMBOL_RECORD *prev_symbol_record = NULL;

	/*
	*	Check for legal characters in name, and legal name length
	*/
	while (name[ch_index] != JAMC_NULL_CHAR)
	{
		if (!jam_is_name_char(name[ch_index++])) status = JAMC_ILLEGAL_SYMBOL;
	}

	if ((ch_index == 0) || (ch_index > JAMC_MAX_NAME_LENGTH))
	{
		status = JAMC_ILLEGAL_SYMBOL;
	}

	/*
	*	Get hash key for this name
	*/
	hash = jam_hash(name);

	/*
	*	Get pointer to first symbol record corresponding to this hash key
	*/
	symbol_record = jam_symbol_table[hash];

	/*
	*	Then check for duplicate entry in symbol table
	*/
	while ((status == JAMC_SUCCESS) && (symbol_record != NULL) &&
		(!identical_redeclaration))
	{
		match = TRUE;
		ch_index = 0;
		do
		{
			r = symbol_record->name[ch_index];
			l = name[ch_index];
			match = (r == l);
			++ch_index;
		}
		while (match && (r != '\0') && (l != '\0'));

		if (match)
		{
			/*
			*	Check if symbol was already declared identically
			*	(same name, type, and source position)
			*/
			if ((symbol_record->position == position) &&
				(jam_phase == JAM_DATA_PHASE))
			{
				if ((type == JAM_INTEGER_ARRAY_WRITABLE) &&
					(symbol_record->type == JAM_INTEGER_ARRAY_INITIALIZED))
				{
					type = JAM_INTEGER_ARRAY_INITIALIZED;
				}

				if ((type == JAM_BOOLEAN_ARRAY_WRITABLE) &&
					(symbol_record->type == JAM_BOOLEAN_ARRAY_INITIALIZED))
				{
					type = JAM_BOOLEAN_ARRAY_INITIALIZED;
				}
			}

			if ((symbol_record->type == type) &&
				(symbol_record->position == position))
			{
				/*
				*	For identical redeclaration, simply assign the value
				*/
				identical_redeclaration = TRUE;

				if (jam_version != 2)
				{
					symbol_record->value = value;
				}
				else
				{
					if ((type != JAM_PROCEDURE_BLOCK) &&
						(type != JAM_DATA_BLOCK) &&
						(jam_current_block != NULL) &&
						(jam_current_block->type == JAM_PROCEDURE_BLOCK))
					{
						symbol_record->value = value;
					}
				}
			}
			else
			{
				status = JAMC_REDEFINED_SYMBOL;
			}
		}

		prev_symbol_record = symbol_record;
		symbol_record = symbol_record->next;
	}

	/*
	*	If no duplicate entry found, add the symbol
	*/
	if ((status == JAMC_SUCCESS) && (symbol_record == NULL) &&
		(!identical_redeclaration))
	{
		/*
		*	Check initialization list -- if matching name is found,
		*	override the initialization value with the new value
		*/
		if (((type == JAM_INTEGER_SYMBOL) || (type == JAM_BOOLEAN_SYMBOL)) &&
			(jam_init_list != NULL))
		{
			if ((jam_version != 2) &&
				jam_check_init_list(name, &init_list_value))
			{
				/* value was found -- override old value */
				value = init_list_value;
			}
		}

		/*
		*	Add the symbol
		*/
		if (jam_workspace != NULL)
		{
			jam_symbol_bottom = (void *)
				(((long)jam_symbol_bottom) - sizeof(JAMS_SYMBOL_RECORD));

			symbol_record = (JAMS_SYMBOL_RECORD *) jam_symbol_bottom;

			if ((long)jam_heap_top > (long)jam_symbol_bottom)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
		}
		else
		{
			symbol_record = (JAMS_SYMBOL_RECORD *)
				jam_malloc(sizeof(JAMS_SYMBOL_RECORD));

			if (symbol_record == NULL)
			{
				status = JAMC_OUT_OF_MEMORY;
			}
		}

		if (status == JAMC_SUCCESS)
		{
			symbol_record->type = type;
			symbol_record->value = value;
			symbol_record->position = position;
			symbol_record->parent = jam_current_block;
			symbol_record->next = NULL;

			if (prev_symbol_record == NULL)
			{
				jam_symbol_table[hash] = symbol_record;
			}
			else
			{
				prev_symbol_record->next = symbol_record;
			}

			ch_index = 0;
			while ((ch_index < JAMC_MAX_NAME_LENGTH) &&
				(name[ch_index] != '\0'))
			{
				symbol_record->name[ch_index] = name[ch_index];
				++ch_index;
			}
			symbol_record->name[ch_index] = '\0';
		}
	}

	return (status);
}