mirror of
https://github.com/dschmenk/VM02.git
synced 2024-10-05 20:56:46 +00:00
183 lines
4.3 KiB
C
Executable File
183 lines
4.3 KiB
C
Executable File
/*
|
|
* Symbol table and fixup information.
|
|
*/
|
|
static int consts = 0;
|
|
static char idconst_name[1024][17];
|
|
static int idconst_value[1024];
|
|
static int globals = 0;
|
|
static int globalsize = 0;
|
|
static char idglobal_name[1024][17];
|
|
static int idglobal_type[1024];
|
|
static int idglobal_tag[1024];
|
|
static int locals = 0;
|
|
static int localsize = 0;
|
|
static char idlocal_name[128][17];
|
|
static int idlocal_type[128];
|
|
static int idlocal_offset[128];
|
|
static int codetag = 0;
|
|
static int fixup = 0;
|
|
int id_match(char *name, int len, char *id)
|
|
{
|
|
if (len == id[0])
|
|
{
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
{
|
|
if (name[len] != id[1 + len])
|
|
return (0);
|
|
}
|
|
return (1);
|
|
}
|
|
return (0);
|
|
}
|
|
int idlocal_lookup(char *name, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < locals; i++)
|
|
if (id_match(name, len, &(idlocal_name[i][0])))
|
|
return (i);
|
|
return (-1);
|
|
}
|
|
int idglobal_lookup(char *name, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < globals; i++)
|
|
if (id_match(name, len, &(idglobal_name[i][0])))
|
|
return (i);
|
|
return (-1);
|
|
}
|
|
int idconst_lookup(char *name, int len)
|
|
{
|
|
int i;
|
|
for (i = 0; i < consts; i++)
|
|
if (id_match(name, len, &(idconst_name[i][0])))
|
|
return (i);
|
|
return (-1);
|
|
}
|
|
int idlocal_add(char *name, int len, int type, int size)
|
|
{
|
|
if (localsize > 255)
|
|
{
|
|
printf("Local variable size overflow\n");
|
|
return (0);
|
|
}
|
|
char c = name[len];
|
|
name[len] = '\0';
|
|
emit_idlocal(name, localsize);
|
|
name[len] = c;
|
|
idlocal_name[locals][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idlocal_name[locals][1 + len] = name[len];
|
|
idlocal_type[locals] = type;
|
|
idlocal_offset[locals] = localsize;
|
|
localsize += size;
|
|
locals++;
|
|
return (1);
|
|
}
|
|
int idglobal_add(char *name, int len, int type, int size)
|
|
{
|
|
if (globals > 1024)
|
|
{
|
|
printf("Global variable count overflow\n");
|
|
return (0);
|
|
}
|
|
char c = name[len];
|
|
name[len] = '\0';
|
|
emit_idglobal(globalsize, size, name);
|
|
name[len] = c;
|
|
idglobal_name[globals][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idglobal_name[globals][1 + len] = name[len];
|
|
idglobal_type[globals] = type;
|
|
idglobal_tag[globals] = globalsize;
|
|
globalsize += size;
|
|
globals++;
|
|
return (1);
|
|
}
|
|
void idglobal_size(int type, int size, int constsize)
|
|
{
|
|
if (size > constsize)
|
|
globalsize += emit_data(0, 0, 0, size - constsize);
|
|
else
|
|
globalsize += constsize;
|
|
}
|
|
int idfunc_add(char *name, int len, int tag)
|
|
{
|
|
if (globals > 1024)
|
|
{
|
|
printf("Global variable count overflow\n");
|
|
return (0);
|
|
}
|
|
idglobal_name[globals][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idglobal_name[globals][1 + len] = name[len];
|
|
idglobal_type[globals] = FUNC_TYPE;
|
|
idglobal_tag[globals] = tag;
|
|
globals++;
|
|
return (1);
|
|
}
|
|
int idconst_add(char *name, int len, int value)
|
|
{
|
|
if (consts > 1024)
|
|
{
|
|
printf("Constant count overflow\n");
|
|
return (0);
|
|
}
|
|
char c = name[len];
|
|
name[len] = '\0';
|
|
emit_idconst(name, value);
|
|
name[len] = c;
|
|
idconst_name[consts][0] = len;
|
|
if (len > 16) len = 16;
|
|
while (len--)
|
|
idconst_name[consts][1 + len] = name[len];
|
|
idconst_value[consts] = value;
|
|
consts++;
|
|
return (1);
|
|
}
|
|
int id_addr(char *name, int len)
|
|
{
|
|
int i;
|
|
if ((i = idlocal_lookup(name, len)) >= 0)
|
|
return (idlocal_offset[i]);
|
|
if ((i = idglobal_lookup(name, len)) >= 0)
|
|
return (idglobal_tag[i]);
|
|
parse_error("Undeclared identifier");
|
|
return (-1);
|
|
}
|
|
int id_const(char *name, int len)
|
|
{
|
|
int i;
|
|
if ((i = idconst_lookup(name, len)) >= 0)
|
|
return (idconst_value[i]);
|
|
parse_error("Undeclared constant");
|
|
return (0);
|
|
}
|
|
int id_type(char *name, int len)
|
|
{
|
|
int i;
|
|
if ((i = idconst_lookup(name, len)) >= 0)
|
|
return (CONST_TYPE);
|
|
if ((i = idlocal_lookup(name, len)) >= 0)
|
|
return (idlocal_type[i] | LOCAL_TYPE);
|
|
if ((i = idglobal_lookup(name, len)) >= 0)
|
|
return (idglobal_type[i]);
|
|
parse_error("Undeclared identifier");
|
|
return (0);
|
|
}
|
|
void idlocal_reset(void)
|
|
{
|
|
locals = localsize = 0;
|
|
}
|
|
int tag_new(void)
|
|
{
|
|
return (codetag++);
|
|
}
|
|
int add_fixup(tag)
|
|
{
|
|
return (fixup++);
|
|
}
|