/*9:*/
#line 260 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

/*22:*/
#line 462 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

#include "yacco2_stbl.h"

/*:22*/
#line 261 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
using namespace NS_yacco2_err_symbols;
using namespace NS_yacco2_terminals;
using namespace yacco2;
/*20:*/
#line 454 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

table_entry yacco2_stbl::stbl[hash_table_size]= {table_entry()};
char yacco2_stbl::char_pool_[char_pool_size]= {};
int yacco2_stbl::char_pool_idx_(0);

/*:20*//*24:*/
#line 504 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

void yacco2_stbl::hash_fnct(T_sym_tbl_report_card&Report,const char&Key)
{
Report.pos_= -1;
Report.key_len_= strlen(&Key);
if(Report.key_len_==0){
Report.status_= T_sym_tbl_report_card::failure;
Report.err_entry_= new Err_zero_len_sym;
return;
}
Report.key_len_+= 1;
const char*k= &Key;
Report.pos_= *k++;
for(;*k!=0;++k){
Report.pos_= ((Report.pos_*257)+*k)%hash_table_size;
}
Report.status_= T_sym_tbl_report_card::okay;
}

/*:24*//*25:*/
#line 548 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

void yacco2_stbl::add_sym_to_stbl
(T_sym_tbl_report_card&Report
,const char&Name
,yacco2::CAbs_lr1_sym&Sym
,table_entry::defined_or_used_typ Why
,table_entry::entry_typ What)
{
static int guest_cnt(0);
hash:/*21:*/
#line 459 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

yacco2_stbl::hash_fnct(Report,Name);
/*:21*/
#line 557 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*26:*/
#line 566 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

if(Report.status_==T_sym_tbl_report_card::failure)return;
if(Report.status_==T_sym_tbl_report_card::fatal)return;


/*:26*/
#line 558 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
compare:/*27:*/
#line 572 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

table_entry*te= &yacco2_stbl::stbl[Report.pos_];
int r(0);
if(te->vacant_==true)goto insert;

r= strcmp(te->key_,&Name);
if(r==0){
Report.status_= T_sym_tbl_report_card::failure;
Report.err_entry_= new Err_dup_entry_in_sym_table;
Report.tbl_entry_= te;
Report.key_len_= 0;
return;
}

/*:27*/
#line 559 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
advance:/*28:*/
#line 587 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

--Report.pos_;
if(Report.pos_<0)Report.pos_+= hash_table_size;
goto compare;

/*:28*/
#line 560 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
insert:/*29:*/
#line 593 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

if(guest_cnt==hash_table_full){
Report.status_= T_sym_tbl_report_card::failure;
Report.err_entry_= new Err_sym_tbl_full;
return;
}
if(char_pool_idx_+Report.key_len_> char_pool_size){
Report.status_= T_sym_tbl_report_card::failure;
Report.err_entry_= new Err_sym_tbl_char_pool_full;
return;
}
++guest_cnt;
te->pos_= Report.pos_;
te->vacant_= false;
char*key_name= &char_pool_[char_pool_idx_];
strncpy(key_name,&Name,Report.key_len_);
te->key_= key_name;
te->key_len_= Report.key_len_;
char_pool_idx_+= Report.key_len_;
te->symbol_= &Sym;
te->type_= What;
if(Why==table_entry::used)
te->used_= true;
else
te->defined_= true;
Report.status_= T_sym_tbl_report_card::okay;
Report.action_= T_sym_tbl_report_card::inserted;
Report.tbl_entry_= te;



/*:29*/
#line 561 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
}


/*:25*//*30:*/
#line 644 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

void yacco2_stbl::find_sym_in_stbl(T_sym_tbl_report_card&Report,const char&Name)
{
hash:/*21:*/
#line 459 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

yacco2_stbl::hash_fnct(Report,Name);
/*:21*/
#line 647 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*26:*/
#line 566 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

if(Report.status_==T_sym_tbl_report_card::failure)return;
if(Report.status_==T_sym_tbl_report_card::fatal)return;


/*:26*/
#line 648 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
compare:/*31:*/
#line 654 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

Report.tbl_entry_= &yacco2_stbl::stbl[Report.pos_];
table_entry*te= Report.tbl_entry_;
if(te->vacant_==true){
Report.status_= T_sym_tbl_report_card::okay;
Report.action_= T_sym_tbl_report_card::not_fnd;
return;
}
int r= strcmp(te->key_,&Name);
if(r==0){
Report.status_= T_sym_tbl_report_card::okay;
Report.action_= T_sym_tbl_report_card::fnd;
return;
}

/*:31*/
#line 649 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
advance:/*32:*/
#line 670 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

--Report.pos_;
if(Report.pos_<0)Report.pos_+= hash_table_size;
goto compare;

/*:32*/
#line 650 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
}

/*:30*//*33:*/
#line 684 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

void yacco2_stbl::get_sym_entry_by_sub(T_sym_tbl_report_card&Report,int Sub)
{
Report.pos_= Sub;
if((Sub<0)||(Sub> hash_table_full)){
Report.status_= T_sym_tbl_report_card::failure;
Report.err_entry_= new Err_subscript_out_of_range;
return;
}
Report.tbl_entry_= &yacco2_stbl::stbl[Sub];
Report.status_= T_sym_tbl_report_card::okay;
if(Report.tbl_entry_->vacant_==false)
Report.action_= T_sym_tbl_report_card::fnd;
else
Report.action_= T_sym_tbl_report_card::not_fnd;
}


/*:33*//*34:*/
#line 710 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

void yacco2_stbl::test_program()
{
/*8:*/
#line 256 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

using namespace yacco2_stbl;

/*:8*/
#line 713 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*35:*/
#line 724 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

const char*zero_len_name= "";
T_eol*a_good_sym= new T_eol;
int cnt(0);
T_sym_tbl_report_card report_card;
std::cout<<"Prime number used: "<<hash_table_size<<std::endl;
std::cout<<"Test zero len key"<<std::endl;
add_sym_to_stbl(report_card,*zero_len_name,*a_good_sym,table_entry::used,table_entry::terminal);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error zero_len_name: "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
std::cout<<"Should have been a zero_len_name error "<<std::endl;
}

/*:35*/
#line 714 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*36:*/
#line 740 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

char buf[256];
std::string*sbuf[hash_table_size];
sbuf[1]= new string("1");
const char*f1st_dup= "1";
std::cout<<"1st entry test"<<std::endl;
add_sym_to_stbl(report_card,*sbuf[1]->c_str(),*a_good_sym,table_entry::defed,table_entry::rule);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error first entry failed: "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}

std::cout<<"duplicate entry test"<<std::endl;
add_sym_to_stbl(report_card,*f1st_dup,*a_good_sym,table_entry::defed,table_entry::rule);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error duplicate entry: "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
std::cout<<"Should have been a duplicate entry error "<<std::endl;
}

cout<<"Same key address test "<<endl;
add_sym_to_stbl(report_card,*sbuf[1]->c_str(),*a_good_sym,table_entry::defed,table_entry::rule);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error same key address: "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
std::cout<<"Should have been a same key address error "<<std::endl;
}

/*:36*/
#line 715 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*37:*/
#line 771 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

const char*numeric_key= "%i";
std::cout<<"Fill up balance of table"<<std::endl;
for(cnt= 2;cnt<=hash_table_full;++cnt){
sprintf(buf,numeric_key,cnt);
sbuf[cnt]= new string(buf);
add_sym_to_stbl(report_card,*sbuf[cnt]->c_str()
,*a_good_sym,table_entry::defed,table_entry::rule);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error entry failed: "<<cnt<<" "
<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}
}

/*:37*/
#line 716 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*38:*/
#line 787 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

const char*overflow_key= "overflow";
std::cout<<"Overflow test"<<std::endl;
add_sym_to_stbl(report_card,*overflow_key,*a_good_sym,table_entry::defed,table_entry::rule);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error overflow: "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
std::cout<<"Should be overflow error"<<std::endl;
}

/*:38*/
#line 717 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*39:*/
#line 801 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

std::cout<<"Find symbol test"<<std::endl;
for(cnt= 1;cnt<=hash_table_full;++cnt){
find_sym_in_stbl(report_card,*sbuf[cnt]->c_str());
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error Should have been found: "<<cnt
<<" "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
if(report_card.action_==T_sym_tbl_report_card::not_fnd){
std::cout<<"Error Action should have been found: "<<cnt<<std::endl;
}
}
}
std::cout<<"Not found test"<<std::endl;
find_sym_in_stbl(report_card,*overflow_key);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Should not be an error: "<<cnt
<<" "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
if(report_card.action_==T_sym_tbl_report_card::fnd){
std::cout<<"Error should be not found: "<<std::endl;
}
}

/*:39*/
#line 718 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*40:*/
#line 832 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

std::cout<<"get symbol by subscript test"<<std::endl;
for(cnt= -1;cnt<=hash_table_size;++cnt){
get_sym_entry_by_sub(report_card,cnt);
if(report_card.status_==T_sym_tbl_report_card::failure){
std::cout<<"Error subscript out of range: "
<<cnt<<" "<<report_card.err_entry_->id__<<std::endl;
delete report_card.err_entry_;
}else{
if(report_card.action_==T_sym_tbl_report_card::not_fnd){
std::cout<<"Error not found if this message appears more than once: "
<<cnt<<std::endl;
std::cout<<"Remember 1 spot is left vacant in the algorithm!"<<std::endl;
}
}
}

/*:40*/
#line 719 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
/*41:*/
#line 850 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"

std::cout<<"Clean up"<<std::endl;
delete a_good_sym;
for(cnt= 1;cnt<=hash_table_full;++cnt){
delete sbuf[cnt];
}

/*:41*/
#line 720 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;
}

/*:34*/
#line 265 "/usr/local/yacco2/compiler/stbl/yacco2_stbl.w"
;




/*:9*/
