/* compile.c */
/* This file contains the functions to compile CI-C into an easily
interpreted form */
#include "config.h"
#include "object.h"
#include "instr.h"
#include "construct.h"
#include "file.h"
#include "token.h"
#include "globals.h"
/* The precedence array - keeps track of operator precedences */
struct
{
int comp_prec; /* precedence used in comparison */
int res_prec; /* result precedence passed on */
} prec_array[NUM_OPERS]={ 1,1,
3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,3,2,
5,4,
6,6,
7,7,
8,8,
9,9,
10,10,
11,11,11,11,
12,12,12,12,12,12,12,12,
13,13,13,13,
14,14,14,14,
15,15,15,15,15,15,
17,16,17,16,17,16,17,16,17,16,17,16,17,16 };
/* scall_array contains the names of system calls */
char *scall_array[NUM_SCALLS]={ "add_verb","add_xverb","call_other",
"alarm","remove_alarm","caller_object","clone_object","destruct",
"contents","next_object","location","next_child","parent","next_proto",
"move_object","this_object","this_player","set_interactive","interactive",
"set_priv","priv","in_editor","connected","get_devconn","send_device",
"reconnect_device","disconnect_device","random","time","mktime",
"typeof","command","compile_object","edit","cat","ls","rm","cp","mv",
"mkdir","rmdir","hide","unhide","chown","syslog","sscanf","sprintf",
"midstr","strlen","leftstr","rightstr","subst","instr","otoa","itoa",
"atoi","atoo","upcase","downcase","is_legal","otoi","itoo","chmod",
"fread","fwrite","remove_verb","ferase","chr","asc","sysctl","prototype",
"iterate","next_who"
};
/* The functions themselves */
void set_c_err_msg(char *msg) {
if (!c_err_msg)
c_err_msg=msg;
}
void resize(fn_t *fn, unsigned long newsize)
{
struct var *tmp;
unsigned long x,size;
if (newsize) {
tmp=(struct var *) MALLOC(newsize*sizeof(struct var));
for (x=0;x<(fn->num_code);x++)
tmp[x]=fn->code[x];
FREE(fn->code);
fn->code=tmp;
}
}
#define make_new(fn) \
if ((fn->num_code)++) { \
if ((fn->num_code)>(fn->num_alloc)) \
resize(fn,(fn->num_alloc)+=FN_BLK); \
} else { \
fn->code=(struct var *) MALLOC(FN_BLK*sizeof(struct var)); \
fn->num_alloc=FN_BLK; \
}
#define DO_FUNC1(A,B,C,D) \
void A(fn_t *curr_fn, B val) \
{ \
unsigned long x; \
\
x=curr_fn->num_code; \
make_new(curr_fn) \
curr_fn->code[x].type=C; \
curr_fn->code[x].value.D=val; \
}
#define DO_FUNC2(A,B) \
void A(fn_t *curr_fn) \
{ \
make_new(curr_fn) \
curr_fn->code[curr_fn->num_code-1].type=B; \
}
#define DO_FUNC3(A,B) \
void A(fn_t *curr_fn, unsigned int ref, unsigned int size) \
{ \
unsigned long x; \
\
x=curr_fn->num_code; \
make_new(curr_fn) \
curr_fn->code[x].type=B; \
curr_fn->code[x].value.l_value.ref=ref; \
curr_fn->code[x].value.l_value.size=size; \
}
DO_FUNC1(add_code_branch, unsigned long, BRANCH, num)
DO_FUNC1(add_code_new_line, unsigned int, NEW_LINE, num)
DO_FUNC1(add_code_instr, unsigned char, ASM_INSTR, instruction)
DO_FUNC1(add_code_jump, unsigned long, JUMP, num)
DO_FUNC1(add_code_integer, signed long, INTEGER, integer)
DO_FUNC1(add_code_func_call, struct fns *, FUNC_CALL, func_call)
DO_FUNC1(add_code_func_name, char *, FUNC_NAME, string)
DO_FUNC1(add_code_num_args, unsigned int, NUM_ARGS, num)
DO_FUNC2(add_code_return, RETURN)
DO_FUNC2(add_code_gr, GLOBAL_REF)
DO_FUNC2(add_code_lr, LOCAL_REF)
DO_FUNC3(add_code_glv, GLOBAL_L_VALUE)
DO_FUNC3(add_code_llv, LOCAL_L_VALUE)
void add_code_string(fn_t *curr_fn, char *val)
{
unsigned long x;
x=curr_fn->num_code;
make_new(curr_fn);
if (*val) {
curr_fn->code[x].type=STRING;
curr_fn->code[x].value.string=copy_string(val);
} else {
curr_fn->code[x].type=INTEGER;
curr_fn->code[x].value.integer=0;
}
}
void free_sym_t(sym_tab_t *sym)
{
struct var_tab *curr_var, *next_var;
struct array_size *curr_array, *next_array;
curr_var=sym->varlist;
while (curr_var) {
next_var=curr_var->next;
curr_array=curr_var->array;
while (curr_array) {
next_array=curr_array->next;
FREE(curr_array);
curr_array=next_array;
}
FREE(curr_var->name);
FREE(curr_var);
curr_var=next_var;
}
}
void free_file_stack(filptr *file_info)
{
struct file_stack *curr, *next;
curr=file_info->previous;
while (curr) {
close_file(curr->file_ptr);
next=curr->previous;
FREE(curr);
curr=next;
}
}
void free_define(filptr *file_info)
{
struct define *curr, *next;
struct parm *currparm, *nextparm;
curr=file_info->defs;
while (curr) {
next=curr->next;
currparm=curr->params;
while (currparm) {
nextparm=currparm->next;
FREE(currparm->name);
if (currparm->exp)
FREE(currparm->exp);
FREE(currparm);
currparm=nextparm;
}
FREE(curr->name);
FREE(curr->definition);
FREE(curr);
curr=next;
}
}
unsigned int calc_size(struct array_size *array)
{
if (array==NULL)
return 1;
else
return (array->size)*calc_size(array->next);
}
unsigned char find_syscall(char *name)
{
int x;
for (x=0;x<NUM_SCALLS;x++)
if (!strcmp(name,scall_array[x]))
return x+NUM_OPERS;
return 0;
}
struct fns *find_func(struct fns *position, char *name)
{
while (position) {
if (!strcmp(position->funcname,name))
return position;
position=position->next;
}
return NULL;
}
struct var_tab *find_var(char *name, sym_tab_t *sym)
{
struct var_tab *curr;
curr=sym->varlist;
while (curr) {
if (!strcmp(curr->name,name))
return curr;
curr=curr->next;
}
return NULL;
}
unsigned int add_var(filptr *file_info, sym_tab_t *sym)
{
token_t token;
struct var_tab *curr_var;
int done;
struct array_size **rest;
get_token(file_info,&token);
if (token.type!=NAME_TOK) {
set_c_err_msg("expected variable name declaration");
return file_info->phys_line;
}
curr_var=(struct var_tab *) MALLOC(sizeof(struct var_tab));
curr_var->name=copy_string(token.token_data.name);
curr_var->base=sym->num;
curr_var->array=NULL;
curr_var->next=sym->varlist;
sym->varlist=curr_var;
rest=&(curr_var->array);
done=0;
while (!done) {
get_token(file_info,&token);
if (token.type!=LARRAY_TOK)
done=1;
else {
get_token(file_info,&token);
if (token.type!=INTEGER_TOK) {
set_c_err_msg("array size must be integer constant");
return file_info->phys_line;
}
*rest=(struct array_size *) MALLOC(sizeof(struct array_size));
(*rest)->size=token.token_data.integer;
(*rest)->next=NULL;
rest=&((*rest)->next);
get_token(file_info,&token);
if (token.type!=RARRAY_TOK) {
set_c_err_msg("expected ]");
return file_info->phys_line;
}
}
}
unget_token(file_info,&token);
sym->num+=calc_size(curr_var->array);
return 0;
}
unsigned int parse_base(filptr *file_info,fn_t *curr_fn, sym_tab_t
*loc_sym, struct array_size **rest)
{
token_t token;
if (*rest==NULL) {
set_c_err_msg("array reference on non-array type");
return file_info->phys_line;
}
(*rest)=(*rest)->next;
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
add_code_integer(curr_fn,calc_size(*rest));
add_code_instr(curr_fn,MUL_OPER);
add_code_instr(curr_fn,ADD_OPER);
get_token(file_info,&token);
if (token.type!=RARRAY_TOK) {
set_c_err_msg("expected ]");
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type==LARRAY_TOK)
return parse_base(file_info,curr_fn,loc_sym,rest);
unget_token(file_info,&token);
return 0;
}
unsigned int parse_var(char *name,filptr *file_info,fn_t *curr_fn,sym_tab_t
*loc_sym)
{
token_t token;
int global;
struct var_tab *the_var;
struct array_size *rest;
if (the_var=find_var(name,loc_sym))
global=0;
else
if (the_var=find_var(name,file_info->glob_sym))
global=1;
else {
set_c_err_msg("variable undefined");
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type!=LARRAY_TOK) {
unget_token(file_info,&token);
if (global)
add_code_glv(curr_fn,the_var->base,calc_size(the_var->array));
else
add_code_llv(curr_fn,the_var->base,calc_size(the_var->array));
} else {
rest=the_var->array;
add_code_integer(curr_fn,the_var->base);
if (parse_base(file_info,curr_fn,loc_sym,&rest))
return file_info->phys_line;
add_code_integer(curr_fn,calc_size(rest));
if (global)
add_code_gr(curr_fn);
else
add_code_lr(curr_fn);
}
return 0;
}
unsigned int parse_arglist(filptr *file_info, fn_t *curr_fn, sym_tab_t
*loc_sym)
{
token_t token;
int done,argcount;
done=0;
get_token(file_info,&token);
if (token.type==RPAR_TOK)
argcount=0;
else
argcount=1;
unget_token(file_info,&token);
while (!done) {
if (parse_exp(file_info,curr_fn,loc_sym,1,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type==RPAR_TOK)
done=1;
else
if (token.type!=COMMA_TOK) {
set_c_err_msg("expected )");
return file_info->phys_line;
} else
argcount++;
}
add_code_num_args(curr_fn,argcount);
return 0;
}
unsigned int parse_exp(filptr *file_info, fn_t *curr_fn, sym_tab_t *loc_sym,
int prec, int last_was_arg)
{
token_t token;
char name[MAX_TOK_LEN+1];
unsigned char instr;
struct fns *func,*sec_func;
unsigned long marker1,marker2;
get_token(file_info,&token);
if (token.type==LPAR_TOK) {
if (last_was_arg) {
set_c_err_msg("expected arithmetic operation");
return file_info->phys_line;
}
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=RPAR_TOK) {
set_c_err_msg("expected )");
return file_info->phys_line;
}
last_was_arg=1;
get_token(file_info,&token);
}
if (token.type==INTEGER_TOK) {
if (last_was_arg) {
set_c_err_msg("expected arithmetic operation");
return file_info->phys_line;
}
add_code_integer(curr_fn,token.token_data.integer);
last_was_arg=1;
get_token(file_info,&token);
}
if (token.type==STRING_TOK) {
if (last_was_arg) {
set_c_err_msg("expected arithmetic operation");
return file_info->phys_line;
}
add_code_string(curr_fn,token.token_data.name);
last_was_arg=1;
get_token(file_info,&token);
}
if (token.type==NAME_TOK) {
strcpy(name,token.token_data.name);
if (last_was_arg) {
set_c_err_msg("expected arithmetic operation");
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type==LPAR_TOK) {
if (parse_arglist(file_info,curr_fn,loc_sym))
return file_info->phys_line;
if (func=find_func(file_info->curr_code->func_list,name))
add_code_func_call(curr_fn,func);
else
if (instr=find_syscall(name))
add_code_instr(curr_fn,instr);
else
add_code_func_name(curr_fn,copy_string(name));
} else {
unget_token(file_info,&token);
if (parse_var(name,file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
last_was_arg=1;
get_token(file_info,&token);
}
if (token.type==SECOND_TOK) {
set_c_err_msg("operation \'::\' unsupported");
return file_info->phys_line;
}
if (token.type<NUM_OPERS) {
if ((token.type==MIN_OPER) && (!last_was_arg))
token.type=UMIN_OPER;
if ((token.type==POSTADD_OPER) && (!last_was_arg))
token.type=PREADD_OPER;
if ((token.type==POSTMIN_OPER) && (!last_was_arg))
token.type=PREMIN_OPER;
instr=token.type;
if (prec_array[instr].comp_prec<=prec) {
unget_token(file_info,&token);
return 0;
}
if ((instr!=PREADD_OPER) && (instr!=PREMIN_OPER) && (instr!=UMIN_OPER)
&& (instr!=BITNOT_OPER) && (instr!=NOT_OPER) && (!last_was_arg)) {
set_c_err_msg("malformed expression");
return file_info->phys_line;
}
if (instr==COND_OPER) {
add_code_branch(curr_fn,0);
marker1=curr_fn->num_code-1;
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
add_code_jump(curr_fn,0);
marker2=curr_fn->num_code-1;
add_code_instr(curr_fn,instr);
curr_fn->code[marker1].value.num=curr_fn->num_code-1;
get_token(file_info,&token);
if (token.type!=COLON_TOK) {
set_c_err_msg("expected :");
return file_info->phys_line;
}
if (parse_exp(file_info,curr_fn,loc_sym,prec_array[instr].res_prec,0))
return file_info->phys_line;
add_code_instr(curr_fn,instr);
curr_fn->code[marker2].value.num=curr_fn->num_code-1;
} else {
if ((instr!=POSTADD_OPER) && (instr!=POSTMIN_OPER))
if (parse_exp(file_info,curr_fn,loc_sym,prec_array[instr].res_prec,
0))
return file_info->phys_line;
add_code_instr(curr_fn,instr);
}
return parse_exp(file_info,curr_fn,loc_sym,prec,1);
}
unget_token(file_info,&token);
return 0;
}
unsigned int parse_block(filptr *file_info, fn_t *curr_fn, sym_tab_t *loc_sym)
{
int done;
token_t token;
done=0;
while (!done) {
get_token(file_info,&token);
if (token.type==RBRACK_TOK)
done=1;
else {
unget_token(file_info,&token);
if (parse_line(file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
}
return 0;
}
unsigned int parse_line(filptr *file_info, fn_t *curr_fn, sym_tab_t *loc_sym)
{
token_t token;
unsigned long marker1,marker2;
int done;
get_token(file_info,&token);
switch (token.type) {
case VAR_DCL_TOK:
done=0;
while (!done) {
if (add_var(file_info,loc_sym))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type==SEMI_TOK)
done=1;
else
if (token.type!=COMMA_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
}
break;
case IF_TOK:
get_token(file_info,&token);
if (token.type!=LPAR_TOK) {
set_c_err_msg("expected (");
return file_info->phys_line;
}
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=RPAR_TOK) {
set_c_err_msg("expected )");
return file_info->phys_line;
}
add_code_branch(curr_fn,0);
marker1=curr_fn->num_code-1;
get_token(file_info,&token);
if (token.type==LBRACK_TOK) {
if (parse_block(file_info,curr_fn,loc_sym))
return file_info->phys_line;
} else {
unget_token(file_info,&token);
if (parse_line(file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type==ELSE_TOK) {
add_code_jump(curr_fn,0);
marker2=curr_fn->num_code-1;
get_token(file_info,&token);
add_code_new_line(curr_fn,file_info->phys_line);
curr_fn->code[marker1].value.num=curr_fn->num_code-1;
if (token.type==LBRACK_TOK) {
if (parse_block(file_info,curr_fn,loc_sym))
return file_info->phys_line;
} else {
unget_token(file_info,&token);
if (parse_line(file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
marker1=marker2;
} else
unget_token(file_info,&token);
get_token(file_info,&token);
unget_token(file_info,&token);
add_code_new_line(curr_fn,file_info->phys_line);
curr_fn->code[marker1].value.num=curr_fn->num_code-1;
break;
case WHILE_TOK:
get_token(file_info,&token);
if (token.type!=LPAR_TOK) {
set_c_err_msg("exepcted (");
return file_info->phys_line;
}
add_code_new_line(curr_fn,file_info->phys_line);
marker1=curr_fn->num_code-1;
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=RPAR_TOK) {
set_c_err_msg("expected )");
return file_info->phys_line;
}
add_code_branch(curr_fn,0);
marker2=curr_fn->num_code-1;
get_token(file_info,&token);
if (token.type==LBRACK_TOK) {
if (parse_block(file_info,curr_fn,loc_sym))
return file_info->phys_line;
} else {
unget_token(file_info,&token);
if (parse_line(file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
add_code_jump(curr_fn,marker1);
get_token(file_info,&token);
unget_token(file_info,&token);
add_code_new_line(curr_fn,file_info->phys_line);
curr_fn->code[marker2].value.num=curr_fn->num_code-1;
break;
case FOR_TOK:
get_token(file_info,&token);
if (token.type!=LPAR_TOK) {
set_c_err_msg("expected (");
return file_info->phys_line;
}
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=SEMI_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
add_code_new_line(curr_fn,file_info->phys_line);
marker1=curr_fn->num_code-1;
add_code_integer(curr_fn,1);
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=SEMI_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
add_code_branch(curr_fn,0);
marker2=curr_fn->num_code-1;
add_code_jump(curr_fn,0);
add_code_new_line(curr_fn,file_info->phys_line);
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=RPAR_TOK) {
set_c_err_msg("expected (");
return file_info->phys_line;
}
add_code_jump(curr_fn,marker1);
add_code_new_line(curr_fn,file_info->phys_line);
curr_fn->code[marker2+1].value.num=curr_fn->num_code-1;
get_token(file_info,&token);
if (token.type==LBRACK_TOK) {
if (parse_block(file_info,curr_fn,loc_sym))
return file_info->phys_line;
} else {
unget_token(file_info,&token);
if (parse_line(file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
add_code_jump(curr_fn,marker2+2);
add_code_new_line(curr_fn,file_info->phys_line);
curr_fn->code[marker2].value.num=curr_fn->num_code-1;
break;
case DO_TOK:
add_code_new_line(curr_fn,file_info->phys_line);
marker1=curr_fn->num_code-1;
get_token(file_info,&token);
if (token.type==LBRACK_TOK) {
if (parse_block(file_info,curr_fn,loc_sym))
return file_info->phys_line;
} else {
unget_token(file_info,&token);
if (parse_line(file_info,curr_fn,loc_sym))
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type!=WHILE_TOK) {
set_c_err_msg("expected \'while\'");
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type!=LPAR_TOK) {
set_c_err_msg("expected (");
return file_info->phys_line;
}
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=RPAR_TOK) {
set_c_err_msg("expected )");
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type!=SEMI_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
add_code_branch(curr_fn,0);
marker2=curr_fn->num_code-1;
add_code_jump(curr_fn,marker1);
add_code_new_line(curr_fn,file_info->phys_line);
curr_fn->code[marker2].value.num=curr_fn->num_code-1;
break;
case RETURN_TOK:
get_token(file_info,&token);
if (token.type==SEMI_TOK)
add_code_integer(curr_fn,0);
else {
unget_token(file_info,&token);
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=SEMI_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
}
add_code_return(curr_fn);
break;
default:
add_code_new_line(curr_fn,file_info->phys_line);
unget_token(file_info,&token);
if (parse_exp(file_info,curr_fn,loc_sym,0,0))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type!=SEMI_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
}
return 0;
}
unsigned int top_level_parse(filptr *file_info)
{
token_t token;
sym_tab_t loc_sym;
int done, is_static;
fn_t curr_func;
struct fns *tmp_fns;
while (1) {
is_static=0;
done=0;
get_token(file_info,&token);
if (token.type==STATIC_TOK) {
is_static=1;
get_token(file_info,&token);
}
switch (token.type) {
case EOF_TOK:
return 0;
break;
case VAR_DCL_TOK:
while (!done) {
if (add_var(file_info,file_info->glob_sym))
return file_info->phys_line;
get_token(file_info,&token);
if (token.type==SEMI_TOK)
done=1;
else
if (token.type!=COMMA_TOK) {
set_c_err_msg("expected ;");
return file_info->phys_line;
}
}
break;
case NAME_TOK:
curr_func.code=NULL;
curr_func.num_code=0;
curr_func.num_alloc=0;
loc_sym.num=0;
loc_sym.varlist=NULL;
tmp_fns=(struct fns *) MALLOC(sizeof(struct fns));
tmp_fns->is_static=is_static;
tmp_fns->num_args=0;
tmp_fns->num_instr=0;
tmp_fns->num_locals=0;
tmp_fns->code=NULL;
tmp_fns->funcname=copy_string(token.token_data.name);
tmp_fns->next=file_info->curr_code->func_list;
file_info->curr_code->func_list=tmp_fns;
get_token(file_info,&token);
if (token.type!=LPAR_TOK) {
set_c_err_msg("expected (");
return file_info->phys_line;
}
while (!done) {
get_token(file_info,&token);
if (token.type==RPAR_TOK)
done=1;
else {
if (token.type!=VAR_DCL_TOK)
unget_token(file_info,&token);
if (add_var(file_info,&loc_sym)) {
free_sym_t(&loc_sym);
return file_info->phys_line;
}
get_token(file_info,&token);
if (token.type==RPAR_TOK)
unget_token(file_info,&token);
else
if (token.type!=COMMA_TOK) {
set_c_err_msg("expected )");
free_sym_t(&loc_sym);
return file_info->phys_line;
}
}
}
tmp_fns->num_args=loc_sym.num;
get_token(file_info,&token);
if (token.type!=LBRACK_TOK) {
set_c_err_msg("expected {");
free_sym_t(&loc_sym);
return file_info->phys_line;
}
add_code_new_line(&curr_func,file_info->phys_line);
if (parse_block(file_info,&curr_func,&loc_sym)) {
tmp_fns->code=curr_func.code;
tmp_fns->num_instr=curr_func.num_code;
free_sym_t(&loc_sym);
return file_info->phys_line;
}
add_code_integer(&curr_func,0);
add_code_return(&curr_func);
resize(&curr_func,curr_func.num_code);
tmp_fns->code=curr_func.code;
tmp_fns->num_locals=loc_sym.num;
tmp_fns->num_instr=curr_func.num_code;
free_sym_t(&loc_sym);
break;
default:
return file_info->phys_line;
break;
}
}
}