shithub: lpa

ref: ad872eeb19b4fcc41a5d34750ca6cdcf88a39795
dir: /symtab.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>

#include "dat.h"
#include "fns.h"

struct {
	char *name;
	void *(*init)(void);
} defaultsyms[] = {
	{ "⎕IO", init_quadio },
};

Symtab *
allocsymtab(int defaults)
{
	Symtab *s = alloc(DataSymtab);
	if(defaults){
		for(uvlong i = 0; i < nelem(defaultsyms); i++){
			uvlong symb = sym(s, defaultsyms[i].name);
			symset(s, symb, defaultsyms[i].init());
		}
	}

	return s;
}

uvlong
sym(Symtab *s, char *name)
{
	uvlong id;
	int new = 1;
	rlock(&s->lock);
	for(id = 0; id < s->count; id++){
		if(strcmp(name, s->symbols[id]->name) == 0){
			new = 0;
			break;
		}
	}
	runlock(&s->lock);
	if(new){
		/* check if the name is valid, or return -1 */
		Symbol *newsym = alloc(DataSymbol);
		newsym->name = strdup(name);
		newsym->value = nil;
		newsym->qsymbol = freshobjqid();
		newsym->table = s;
		newsym->id = id;

		wlock(&s->lock);
		s->count++;
		s->symbols = allocextra(s, sizeof(Symbol *) * s->count);
		s->symbols[id] = newsym;
		wunlock(&s->lock);
	}
	return id;
}

char *
symname(Symtab *s, uvlong id)
{
	char *name;
	rlock(&s->lock);
	name = s->symbols[id]->name;
	runlock(&s->lock);
	return name;
}

void *
symval(Symtab *s, uvlong id)
{
	void *value;
	rlock(&s->lock);
	value = s->symbols[id]->value;
	runlock(&s->lock);
	return value;
}

Qid
symqid(Symtab *s, uvlong id)
{
	Qid qid;
	rlock(&s->lock);
	qid = s->symbols[id]->qsymbol;
	runlock(&s->lock);
	return qid;
}

void
symset(Symtab *s, uvlong id, void *newval)
{
	wlock(&s->lock);
	s->symbols[id]->value = newval;
	wunlock(&s->lock);
}

Enumeration *
enumsymbols(Symtab *symtab)
{
	rlock(&symtab->lock);
	Enumeration *e = allocenum(symtab->count);
	for(uvlong i = 0; i < symtab->count; i++)
		e->items[i] = symtab->symbols[i];
	runlock(&symtab->lock);
	return e;
}