/* Copyright (c) 1993 Stephen F. White */
#include <stdio.h>
#ifdef SYSV
#include <string.h>
#else
#include <strings.h>
#endif
#include "config.h"
#include "cool.h"
#include "proto.h"
#include "sys_proto.h"
List *empty_list, *zero, *one;
static struct st {
Sys_sym sym;
const char *name;
} system_table_names[] = {
{ BLANK, "" },
{ INIT, "init" },
{ PARSE, "parse" },
{ BOOT_SERVER, "boot_server" },
{ CONNECT_SERVER, "connect_server" },
{ DISCONNECT_SERVER, "disconnect_server" },
{ CONNECT_PLAYER, "connect_player" },
{ CREATE_PLAYER, "create_player" },
{ DISCONNECT_PLAYER, "disconnect_player" },
{ NAME, "name" },
{ PASSWORD, "password" },
{ RAISE, "raise" },
{ RETURN, "return" },
};
#define SYS_SIZE Arraysize(system_table_names)
String *system_table[SYS_SIZE];
int
sym_add(Object *o, String *name)
{
int i;
Symbol *new_symbols;
for (i = 0; i < o->nsymb; i++) {
if (o->symbols[i].ref && !strcmp(o->symbols[i].s->str, name->str)) {
o->symbols[i].ref++;
string_free(name);
return i;
}
}
for (i = 0; i < SYS_SIZE; i++) {
if (!strcmp(system_table[i]->str, name->str)) {
string_free(name);
return -i - 1;
}
}
for (i = 0; i < o->nsymb; i++) {
if (!o->symbols[i].ref) { /* no refs to symbol; blank entry */
o->symbols[i].s = name; /* fill it in */
o->symbols[i].ref = 1;
return i;
}
}
if (o->nsymb >= o->st_size) { /* symbol table full, double it */
new_symbols = MALLOC(Symbol, o->st_size * 2);
for (i = 0; i < o->nsymb; i++) {
new_symbols[i] = o->symbols[i];
}
o->st_size *= 2;
FREE(o->symbols);
o->symbols = new_symbols;
}
o->symbols[o->nsymb].s = name;
o->symbols[o->nsymb++].ref = 1;
return o->nsymb - 1;
}
void
sym_init_sys(void)
{
int i;
struct st j;
for (i = 0; i < Arraysize(system_table_names); i++) {
j = system_table_names[i];
system_table[j.sym] = string_cpy(j.name);
}
empty_list = list_new(0);
zero = list_new(1);
zero->el[0].type = NUM;
zero->el[0].v.num = 0;
one = list_new(1);
one->el[0].type = NUM;
one->el[0].v.num = 1;
}
void
sym_free(Object *o, int symno)
{
if (symno < 0) { /* it's a system symbol */
return; /* abort */
}
if (!--o->symbols[symno].ref) {
string_free(o->symbols[symno].s);
o->symbols[symno].s = 0;
}
}
void
sym_init(Object *o)
{
o->st_size = SYM_INIT_SIZE;
o->symbols = MALLOC(Symbol, o->st_size);
o->nsymb = 0;
}