#include "sem.hpp"



//-------------------- SEMANTIC ANALYZER Module -----------------//
//						  v 15 . 04 .  2007						 //
//																 //
//								MT								 //
//---------------------------------------------------------------//



//------------------------------ HELPER ------------------------------+

//============================== HELPER ==============================-


//---------------------------------- RUN ------------------------------

//--- Add Item
void CRun :: AddElem(PolizElem *elem)
{
	if (exe->begin == NULL) 
	{
		exe->cur = new PolizItem(elem);
		exe->begin = exe->cur;
		exe->cur_num++;
		return;
	}
	exe->cur->next = new PolizItem(elem);
	exe->cur = exe->cur->next;
};


//--- Label Collect
void CRun :: LabelCollect()
{
	exe->Debug("\nLabel Collect ::\n");
	exe->cur_num = 1;
	exe->cur = exe->begin;
	//PolizItem *prev = NULL;

	while (exe->cur!=NULL)
	{
		PolizFuncLabelRead *p = 
			dynamic_cast<PolizFuncLabelRead*>(exe->cur->p);

		if (p) {
			exe->cur->p->Evaluate_main(exe);
			//PolizItem *todel = exe->cur;

/*			if (prev) prev->next = exe->cur->next;
			else exe->begin=exe->begin->next;
*/
			if (exe->Debug("Label Addr: ")) 
				printf("%d", exe->cur_num);
			exe->cur_num++;

			exe->cur = exe->cur->next;
//			delete todel;
		} else {
//			prev = exe->cur;
			exe->cur = exe->cur->next;
			exe->cur_num++;
		};
	}
	exe->Debug("\n :: Label Collect\n");
}

//--- Execute
void CRun :: Execute () 
{
	Debug("\n\n\n	--- DEBUG MODE ---\n");

	if (!collected) LabelCollect();

	exe->cur_num = 1;
	exe->cur = exe->begin;
	
	while (exe->cur!=NULL)
	{
		if (exe->Debug("\n ElemAddr: ")) {
			printf("%d =", exe->GetCurNum());
			if (exe->cur->next==NULL) printf("\n next==NULL");
		};
		
		try {
			PolizItem *tmp = exe->cur;
			//--- Evaluate
			exe->cur->p->Evaluate_main(exe);
			//=== Evaluate
			if (tmp==exe->cur) exe->SetCur(0,true);
		}

		catch (PolizExNotInt) 
			{ exe->ShowError ("Const int waiting on stack."); return; }
		catch (PolizExNotStr) 
			{ exe->ShowError ("Const str waiting on stack."); return; }
		catch (PolizExWrongAddr) 
			{ exe->ShowError ("Wrong operation address."); return; }
		catch (PolizExWrongMacros) 
			{ exe->ShowError ("Wrong macros parameter."); return; }
		catch (PolizEx) 
			{ exe->ShowError ("PolizEx throw."); return; }
		catch (...) 
			{ exe->ShowError ("Undefined error."); return; };
	};
	
	exe->Debug("\n Execution end.");
	if (exe->Debug("\n\n :: Var Table :: ")) 
		exe->VarTable.Print();
	Debug("\n\n	=== DEBUG MODE ===\n");
};


//--- Debug
void CRun :: Debug(char *s1, char *s2)
{
	exe->Debug(s1, s2);
};

