#include "bcdefs.h"
#include "global.h"
#include "proto.h"
program_counter load_adr;
char load_str;
char load_const;
void
init_load ()
{
clear_func(0);
load_adr.pc_func = 0;
load_adr.pc_addr = 0;
load_str = FALSE;
load_const = FALSE;
}
void
addbyte (byte)
char byte;
{
int pc;
bc_function *f;
char *new_body;
if (had_error) return;
pc = load_adr.pc_addr++;
f = &functions[load_adr.pc_func];
if (pc >= f->f_body_size)
{
f->f_body_size *= 2;
new_body = (char *) bc_malloc (f->f_body_size);
memcpy(new_body, f->f_body, f->f_body_size/2);
free (f->f_body);
f->f_body = new_body;
}
f->f_body[pc] = byte;
f->f_code_size++;
}
void
def_label (lab)
long lab;
{
bc_label_group *temp;
int group, offset, func;
group = lab >> BC_LABEL_LOG;
offset = lab % BC_LABEL_GROUP;
func = load_adr.pc_func;
if (functions[func].f_label == NULL)
{
functions[func].f_label =
(bc_label_group *) bc_malloc (sizeof(bc_label_group));
functions[func].f_label->l_next = NULL;
}
temp = functions[func].f_label;
while (group > 0)
{
if (temp->l_next == NULL)
{
temp->l_next = (bc_label_group *) bc_malloc (sizeof(bc_label_group));
temp->l_next->l_next = NULL;
}
temp = temp->l_next;
group --;
}
temp->l_adrs [offset] = load_adr.pc_addr;
}
long
long_val (str)
char **str;
{ int val = 0;
char neg = FALSE;
if (**str == '-')
{
neg = TRUE;
(*str)++;
}
while (isdigit((int)(**str)))
val = val*10 + *(*str)++ - '0';
if (neg)
return -val;
else
return val;
}
void
load_code (code)
char *code;
{
char *str;
long ap_name;
long label_no;
long vaf_name;
long func;
static program_counter save_adr;
str = code;
while (*str != 0)
{
if (had_error) return;
if (load_str)
{
if (*str == '"') load_str = FALSE;
addbyte (*str++);
}
else
if (load_const)
{
if (*str == '\n')
str++;
else
{
if (*str == ':')
{
load_const = FALSE;
addbyte (*str++);
}
else
if (*str == '.')
addbyte (*str++);
else
if (*str >= 'A')
addbyte (*str++ + 10 - 'A');
else
addbyte (*str++ - '0');
}
}
else
{
switch (*str)
{
case '"':
load_str = TRUE;
break;
case 'N':
str++;
label_no = long_val (&str);
def_label (label_no);
break;
case 'B':
case 'J':
case 'Z':
addbyte(*str++);
label_no = long_val (&str);
if (label_no > 65535L)
{
fprintf (stderr,"Program too big.\n");
exit(1);
}
addbyte ( (char) (label_no & 0xFF));
addbyte ( (char) (label_no >> 8));
break;
case 'F':
str++;
func = long_val (&str);
clear_func (func);
#if DEBUG > 2
printf ("Loading function number %d\n", func);
#endif
while (*str++ != '.')
{
if (*str == '.')
{
str++;
break;
}
if (*str == '*')
{
str++;
ap_name = long_val (&str);
#if DEBUG > 2
printf ("var parameter number %d\n", ap_name);
#endif
functions[(int)func].f_params =
nextarg (functions[(int)func].f_params, ap_name,
TRUE);
}
else
{
ap_name = long_val (&str);
#if DEBUG > 2
printf ("parameter number %d\n", ap_name);
#endif
functions[(int)func].f_params =
nextarg (functions[(int)func].f_params, ap_name,
FALSE);
}
}
while (*str != '[')
{
if (*str == ',') str++;
ap_name = long_val (&str);
#if DEBUG > 2
printf ("auto number %d\n", ap_name);
#endif
functions[(int)func].f_autos =
nextarg (functions[(int)func].f_autos, ap_name, FALSE);
}
save_adr = load_adr;
load_adr.pc_func = func;
load_adr.pc_addr = 0;
break;
case ']':
functions[load_adr.pc_func].f_defined = TRUE;
load_adr = save_adr;
break;
case 'C':
addbyte (*str++);
func = long_val (&str);
if (func < 128)
addbyte ( (char) func);
else
{
addbyte (((func >> 8) & 0xff) | 0x80);
addbyte (func & 0xff);
}
if (*str == ',') str++;
while (*str != ':')
addbyte (*str++);
addbyte (':');
break;
case 'c':
addbyte (*str++);
addbyte (*str);
break;
case 'K':
addbyte (*str);
load_const = TRUE;
break;
case 'd':
case 'i':
case 'l':
case 's':
case 'A':
case 'M':
case 'L':
case 'S':
addbyte (*str++);
vaf_name = long_val (&str);
if (vaf_name < 128)
addbyte (vaf_name);
else
{
addbyte (((vaf_name >> 8) & 0xff) | 0x80);
addbyte (vaf_name & 0xff);
}
break;
case '@':
switch (*(++str))
{
case 'i':
init_load ();
break;
case 'r':
execute ();
break;
}
break;
case '\n':
break;
default:
addbyte (*str);
}
str++;
}
}
}