view src/symtab.c @ 0:57495da01900

Initial checking of LWASM
author lost
date Fri, 03 Oct 2008 02:44:20 +0000
parents
children 34568fab6058
line wrap: on
line source

/*
 * symtab.c
 *
 * main code for lwasm
 */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define __symtab_c_seen__
#include "lwasm.h"

void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags)
{
	symtab_t *st;
	symtab_t *prev;
	int cv = -2;
	
	for (prev = NULL, st = as -> symbol_table; st; st = st -> next)
	{
		cv = strcasecmp(st -> symbol, symstr);
		if (cv == 0)
		{
			cv = strcmp(st -> symbol, symstr);
		}
		if (cv >= 0)
			break;
		prev = st;
	}
	// cv is 0 if we found the symbol, > 0 if we didn't and found one
	// later in order, or -2 if we never did a comparison
	// if st is NULL, the value of cv is irrelevant as it means
	// we fell off the end of the list
	// if st is NULL and prev is not, then prev is the tail of the list
	// if both are NULL, the list is empty
	
	// handle adding the symbol if needed
	if (!st || cv != 0)
	{
		symtab_t *st2;
		// register the symbol
		st2 = malloc(sizeof(symtab_t));
		st2 -> symbol = strdup(symstr);
		st2 -> addr = val;
		st2 -> flags = 0;
		if (flags & SYMFLAG_SET)
			st2 -> flags |= SYMFLAG_SET;

		if (prev)
			prev -> next = st2;
		else
			as -> symbol_table = st2;
		
		st2 -> next = st;
		return;
	}
	
	// st is NOT NULL here and cv IS 0
	if ((flags & SYMFLAG_SET) && ((st -> flags) & SYMFLAG_SET))
	{
		// symbol already exists but it is a "SET" symbol so reset the value
		st -> addr = val;
		return;
	}
	if (st && as -> passnum == 1)
	{
		// duplicate symbol, flag error
		errorp1(ERR_DUPSYM);
	}
	if (st -> addr != val)
		errorp2(ERR_PHASE);
}

int lookup_symbol(asmstate_t *as, char *symstr)
{
	symtab_t *st;

	for (st = as -> symbol_table; st; st = st -> next)
	{
		if (!strcmp(symstr, st -> symbol))
			break;
	}
	if (st)
		return st -> addr;
	return -1;
}

void list_symbols(asmstate_t *as, FILE *f)
{
	symtab_t *st;
	for (st = as -> symbol_table; st; st = st -> next)
	{
		fprintf(f, "%04X %s%s\n", st -> addr, st -> symbol, (st -> flags & SYMFLAG_SET) ? "(S)" : "");
	}
}