ASTNode* TestASTMatcher::buildSubTree()
{
	ASTNode* plusNode = new ASTNode("", PLUS, 0);
	ASTNode* minusNode = new ASTNode("", MINUS, 0);
	ASTNode* varNodeB = new ASTNode("b", VARIABLE, 0);
	ASTNode* varNodeC = new ASTNode("c", VARIABLE, 0);
	ASTNode* constantNode = new ASTNode("1", CONSTANT, 0);

	minusNode->joinChild(plusNode);
	plusNode->joinChild(varNodeB);
	varNodeB->joinNext(varNodeC);
	plusNode->joinNext(constantNode);

	return minusNode;
}
ASTNode* TestASTMatcher::buildSubTreeWithDiffValue()
{
	ASTNode* timesNode = new ASTNode("", TIMES, 0);
	ASTNode* divideNode = new ASTNode("", DIVIDE, 0);
	ASTNode* varNodeB = new ASTNode("b", VARIABLE, 0);
	ASTNode* varNodeC = new ASTNode("c", VARIABLE, 0);
	ASTNode* constantNode = new ASTNode("1", CONSTANT, 0);

	divideNode->joinChild(timesNode);
	timesNode->joinChild(varNodeB);
	varNodeB->joinNext(varNodeC);
	timesNode->joinNext(constantNode);

	return timesNode;
}
ASTNode* Parser::ifStmt()
{
	matchKeyword("if");
	ASTNode* ifNode = new ASTNode("", IF, _stmtNum);

	_varTable->addVariable(_token);
	ASTNode* varNode = new ASTNode(_token, VARIABLE, 0);
	matchName();

	matchKeyword("then");
	matchKeyword("{");

	ASTNode* ifStmtListNode = statementList();

	matchKeyword("}");
	matchKeyword("else");
	matchKeyword("{");
	
	ASTNode* elseStmtListNode = statementList();

	matchKeyword("}");

	ifNode->joinChild(varNode);
	varNode->joinNext(ifStmtListNode);
	ifStmtListNode->joinNext(elseStmtListNode);

	return ifNode;
}
ASTNode* Parser::procedure()
{
	matchKeyword("procedure");

	if (_procTable->getIndex(_token) > -1) {
		throw ParseException(_stmtNum, _token, "Duplicate procedure names");
	}

	std::string procedure = _token;

	ASTNode* procNode = new ASTNode(procedure, PROCEDURE, 0);
	matchName();

	matchKeyword("{");
	int fromStmtNum = _stmtNum + 1;

	ASTNode* stmtListNode = statementList();
	
	matchKeyword("}");
	int toStmtNum = _stmtNum;

	_procTable->addProcedure(procedure, fromStmtNum, toStmtNum);

	procNode->joinChild(stmtListNode);

	return procNode;
}
ASTNode* TestASTMatcher::buildTree()
{
	ASTNode* assignNode = new ASTNode("", ASSIGN, 1);
	ASTNode* plusNode = new ASTNode("", PLUS, 0);
	ASTNode* minusNode = new ASTNode("", MINUS, 0);
	ASTNode* varNodeA = new ASTNode("a", VARIABLE, 0);
	ASTNode* varNodeB = new ASTNode("b", VARIABLE, 0);
	ASTNode* varNodeC = new ASTNode("c", VARIABLE, 0);
	ASTNode* constantNode = new ASTNode("1", CONSTANT, 0);

	assignNode->joinChild(varNodeA);
	varNodeA->joinNext(minusNode);
	minusNode->joinChild(plusNode);
	plusNode->joinChild(varNodeB);
	varNodeB->joinNext(varNodeC);
	plusNode->joinNext(constantNode);

	return assignNode;
}
ASTNode* Parser::assignStmt()
{
	_varTable->addVariable(_token);
	ASTNode* varNode = new ASTNode(_token, VARIABLE, 0);
	matchName();

	matchKeyword("=");
	ASTNode* assignNode = new ASTNode("", ASSIGN, _stmtNum);

	ASTNode* expNode = expression();

	matchKeyword(";");

	assignNode->joinChild(varNode);
	varNode->joinNext(expNode);

	return assignNode;
}
ASTNode* Parser::program()
{
	ASTNode* progNode = new ASTNode("Simple", PROGRAM, 0);

	ASTNode* procNode = procedure();

	progNode->joinChild(procNode);

	ASTNode* prevProcNode;

	while (isKeyword("procedure")) {
		prevProcNode = procNode;
		procNode = procedure();

		prevProcNode->joinNext(procNode);
	}

	return progNode;
}
ASTNode* Parser::statementList()
{
	ASTNode* stmtListNode = new ASTNode("", STATEMENT_LIST, 0);

	ASTNode* stmtNode = statement();

	stmtListNode->joinChild(stmtNode);

	ASTNode* prevStmtNode;

	while (!isKeyword("}")) {
		prevStmtNode = stmtNode;
		stmtNode = statement();

		prevStmtNode->joinNext(stmtNode);
	}

	return stmtListNode;
}
ASTNode* Parser::whileStmt()
{
	matchKeyword("while");
	ASTNode* whileNode = new ASTNode("", WHILE, _stmtNum);

	_varTable->addVariable(_token);
	ASTNode* varNode = new ASTNode(_token, VARIABLE, 0);
	matchName();

	matchKeyword("{");

	ASTNode* stmtListNode = statementList();
	
	matchKeyword("}");

	whileNode->joinChild(varNode);
	varNode->joinNext(stmtListNode);

	return whileNode;
}
void ASTExpressionBuilder::buildOperators()
{
	ASTNode* operatorNode;
	ASTNode* leftNode;
	ASTNode* rightNode;

	ASTType type;

	if (_operators.back() == "+") {
		type = PLUS;
	} else if (_operators.back() == "-") {
		type = MINUS;
	} else if (_operators.back() == "*") {
		type = TIMES;
	}else if (_operators.back() == "/") {
		type = DIVIDE;
	}

	operatorNode = new ASTNode("", type, 0);

	if (!_results.empty()) {
		rightNode = _results.back();
		_results.pop_back();
	} else {
		throw ParseException(_token, "Unable to parse expression");
	}

	if (!_results.empty()) {
		leftNode = _results.back();
		_results.pop_back();
	} else {
		throw ParseException(_token, "Unable to parse expression");
	}

	operatorNode->joinChild(leftNode);
	leftNode->joinNext(rightNode);

	_results.push_back(operatorNode);

	_operators.pop_back();
}