/**
 * Function representing the <st_factor_ident> prods
 */
void RecursiveDescentParser::st_factor_ident(TableEntry* te) {
	if(errorCondition) return;
	if(token == TK_LEFT_PARENTHESES) 
	{
#if DEBUG_PARSER
		std::cout << "<st_factor_ident> --> (<o_list>);\n";
#endif
		Token leftParen = token;
		token = scanner->getToken();
		ParamList* pList = o_list();
		
		if(te) {
			if(te->getEntryType()!=TableEntry::FUNCTION) {
				std::stringstream errorMsg;
				errorMsg << "'" << te->getName() << "' is not a function";
				errorHandler(errorMsg.str(), leftParen);
			} else {
				// now makes sure the lists match
				FunctionEntry* fe = (FunctionEntry*)te;
				if(pList) matchParameters(fe, pList, leftParen);
				
				iCode.threeAddressCode(TAC_PARAM, pList);
				iCode.threeAddressCode( 
						symTab.getNextAddress(), // throw away temporary
						TAC_CALL, 
						fe->getLabel(), 
						fe->getParamCount()
					);
			}
		} else {
			std::stringstream errorMsg;
			errorMsg << "Undeclared function";
			errorHandler(errorMsg.str(), leftParen);
		}
		
		match(TK_RIGHT_PARENTHESES);
		match(TK_SEMICOLON);
	} 
	else if(token == TK_LEFT_BRACKET || 
			token == TK_ASSIGNMENT) 
	{
#if DEBUG_PARSER		
		std::cout << "<st_factor_ident> --> <var_prime>=<exp>;\n";
#endif
		VariableEntry* vEntry = (VariableEntry*)te;
		Token startToken = token;
		
		attr varAttr  = var_prime(vEntry);
		match(TK_ASSIGNMENT);
		attr expAttr = exp();
		
		if(expAttr.type != varAttr.type) {
			std::stringstream errorMsg;
			errorMsg << "Type mismatch variable '" << vEntry->getName() << "'";
			errorHandler(errorMsg.str(), startToken);
		}
		
		if(varAttr.attrib == VA_ARRAY) {
			std::stringstream errorMsg;
			errorMsg << "Assignment error, array '" << vEntry->getName() << "' must be indexed.";
			errorHandler( errorMsg.str(), startToken );
		}
		
		if(vEntry->getAttribute() == VA_ARRAY) {
			//                       array addr                           value to assign   index
			iCode.threeAddressCode(vEntry->getAttr(), TAC_ASSIGN_TO_ADDRESS_AT, expAttr, varAttr);
		} else {
			iCode.threeAddressCode(vEntry->getAttr(), TAC_ASSIGN, expAttr);
		}
		
		match(TK_SEMICOLON);
	} 
	else 
	{
		errorHandler();
	}
}