<commit_before>/**

	File:			NBinaryOperator.cpp

	Project:		DCPU-16 Tools
	Component:		Compiler

	Authors:		<NAME>
					<NAME>

	Description:	Defines the NBinaryOperator AST class.

**/

// Prevents importing all of the class dependencies in
// the parser header so that we only get the token values.
#define YYSTYPE int

#include "NInteger.h"
#include <AsmGenerator.h>
#include <CompilerException.h>
#include "../parser.hpp"
#include "NBinaryOperator.h"

AsmBlock* NBinaryOperator::compile(AsmGenerator& context)
{
	AsmBlock* block = new AsmBlock();

	// When an expression is evaluated, the result goes into the A register.
	AsmBlock* lhs = this->lhs.compile(context);

	// Move the value onto the stack.
	*block <<   *lhs;
	*block <<	"	SET PUSH, A" << std::endl;
	delete lhs;

	// When an expression is evaluated, the result goes into the A register.
	AsmBlock* rhs = this->rhs.compile(context);

	// Move the value onto the stack.
	*block <<   *rhs;
	*block <<	"	SET PUSH, A" << std::endl;
	delete rhs;

	// If debugging, clear the values as we POP them.
	if (context.isAssemblerDebug())
	{
		// Put the values into A and B and clear the
		// stack positions as we do so.
		*block <<	"	SET B, PEEK" << std::endl;
		*block <<	"	SET POP, 0" << std::endl;
		*block <<	"	SET A, PEEK" << std::endl;
		*block <<	"	SET POP, 0" << std::endl;
	}
	else
	{
		// Not debugging, put the values into A and B.
		*block <<	"	SET B, POP" << std::endl;
		*block <<	"	SET A, POP" << std::endl;
	}

	// Now do the appropriate operation.
	switch (this->op)
	{
	case ADD:
		*block <<	"	ADD A, B" << std::endl;
		break;
	case SUBTRACT:
		*block <<	"	SUB A, B" << std::endl;
		break;
	case STAR:
		*block <<	"	MUL A, B" << std::endl;
		break;
	case SLASH:
		*block <<	"	DIV A, B" << std::endl;
		break;
	case PERCENT:
		*block <<	"	MOD A, B" << std::endl;
		break;
	case BOOLEAN_AND:
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN B, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		*block <<	"	XOR A, B" << std::endl;
		*block <<	"	XOR A, 0x1" << std::endl;
		break;
	case BOOLEAN_OR:
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN B, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		*block <<	"	BOR A, B" << std::endl;
		*block <<	"	XOR A, 0x1" << std::endl;
		break;
	case BINARY_AND:
		*block <<	"	AND A, B" << std::endl;
		break;
	case BINARY_OR:
		*block <<	"	BOR A, B" << std::endl;
		break;
	case BINARY_XOR:
		*block <<	"	XOR A, B" << std::endl;
		break;
	case BINARY_LEFT_SHIFT:
		*block <<	"	SHL A, B" << std::endl;
		break;
	case BINARY_RIGHT_SHIFT:
		*block <<	"	SHR A, B" << std::endl;
		break;
	case COMPARE_EQUAL:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFN O, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	XOR A, 0x1" << std::endl;
		break;
	case COMPARE_NOT_EQUAL:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFN O, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		break;
	case COMPARE_LESS_THAN:
		*block <<	"	SUB B, A" << std::endl;
		*block <<	"	IFE O, 0x1" << std::endl;
		*block <<	"		SET B, 0x0" << std::endl;
		*block <<	"	IFN B, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		*block <<	"	SET A, B" << std::endl;
		break;
	case COMPARE_LESS_THAN_EQUAL:
		*block <<	"	SUB B, A" << std::endl;
		*block <<	"	IFE O, 0x1" << std::endl;
		*block <<	"		SET B, 0x0" << std::endl;
		*block <<	"	IFE O, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		break;
		*block <<	"	SET A, B" << std::endl;
	case COMPARE_GREATER_THAN:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFE O, 0x1" << std::endl;
		*block <<	"		SET A, 0x0" << std::endl;
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		break;
	case COMPARE_GREATER_THAN_EQUAL:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFE O, 0x1" << std::endl;
		*block <<	"		SET A, 0x0" << std::endl;
		*block <<	"	IFE O, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		break;
	default:
		throw new CompilerException("Unknown binary operations requested.");
	}

	return block;
}

AsmBlock* NBinaryOperator::reference(AsmGenerator& context)
{
	throw new CompilerException("Unable to get reference to the result of an binary operator.");
}
<commit_msg>replacing O with EX for new specs<commit_after>/**

	File:			NBinaryOperator.cpp

	Project:		DCPU-16 Tools
	Component:		Compiler

	Authors:		<NAME>
					<NAME>

	Description:	Defines the NBinaryOperator AST class.

**/

// Prevents importing all of the class dependencies in
// the parser header so that we only get the token values.
#define YYSTYPE int

#include "NInteger.h"
#include <AsmGenerator.h>
#include <CompilerException.h>
#include "../parser.hpp"
#include "NBinaryOperator.h"

AsmBlock* NBinaryOperator::compile(AsmGenerator& context)
{
	AsmBlock* block = new AsmBlock();

	// When an expression is evaluated, the result goes into the A register.
	AsmBlock* lhs = this->lhs.compile(context);

	// Move the value onto the stack.
	*block <<   *lhs;
	*block <<	"	SET PUSH, A" << std::endl;
	delete lhs;

	// When an expression is evaluated, the result goes into the A register.
	AsmBlock* rhs = this->rhs.compile(context);

	// Move the value onto the stack.
	*block <<   *rhs;
	*block <<	"	SET PUSH, A" << std::endl;
	delete rhs;

	// If debugging, clear the values as we POP them.
	if (context.isAssemblerDebug())
	{
		// Put the values into A and B and clear the
		// stack positions as we do so.
		*block <<	"	SET B, PEEK" << std::endl;
		*block <<	"	SET POP, 0" << std::endl;
		*block <<	"	SET A, PEEK" << std::endl;
		*block <<	"	SET POP, 0" << std::endl;
	}
	else
	{
		// Not debugging, put the values into A and B.
		*block <<	"	SET B, POP" << std::endl;
		*block <<	"	SET A, POP" << std::endl;
	}

	// Now do the appropriate operation.
	switch (this->op)
	{
	case ADD:
		*block <<	"	ADD A, B" << std::endl;
		break;
	case SUBTRACT:
		*block <<	"	SUB A, B" << std::endl;
		break;
	case STAR:
		*block <<	"	MUL A, B" << std::endl;
		break;
	case SLASH:
		*block <<	"	DIV A, B" << std::endl;
		break;
	case PERCENT:
		*block <<	"	MOD A, B" << std::endl;
		break;
	case BOOLEAN_AND:
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN B, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		*block <<	"	XOR A, B" << std::endl;
		*block <<	"	XOR A, 0x1" << std::endl;
		break;
	case BOOLEAN_OR:
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN B, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		*block <<	"	BOR A, B" << std::endl;
		*block <<	"	XOR A, 0x1" << std::endl;
		break;
	case BINARY_AND:
		*block <<	"	AND A, B" << std::endl;
		break;
	case BINARY_OR:
		*block <<	"	BOR A, B" << std::endl;
		break;
	case BINARY_XOR:
		*block <<	"	XOR A, B" << std::endl;
		break;
	case BINARY_LEFT_SHIFT:
		*block <<	"	SHL A, B" << std::endl;
		break;
	case BINARY_RIGHT_SHIFT:
		*block <<	"	SHR A, B" << std::endl;
		break;
	case COMPARE_EQUAL:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFN O, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	XOR A, 0x1" << std::endl;
		break;
	case COMPARE_NOT_EQUAL:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFN EX, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		break;
	case COMPARE_LESS_THAN:
		*block <<	"	SUB B, A" << std::endl;
		*block <<	"	IFE EX, 0x1" << std::endl;
		*block <<	"		SET B, 0x0" << std::endl;
		*block <<	"	IFN B, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		*block <<	"	SET A, B" << std::endl;
		break;
	case COMPARE_LESS_THAN_EQUAL:
		*block <<	"	SUB B, A" << std::endl;
		*block <<	"	IFE EX, 0x1" << std::endl;
		*block <<	"		SET B, 0x0" << std::endl;
		*block <<	"	IFE EX, 0x0" << std::endl;
		*block <<	"		SET B, 0x1" << std::endl;
		break;
		*block <<	"	SET A, B" << std::endl;
	case COMPARE_GREATER_THAN:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFE EX, 0x1" << std::endl;
		*block <<	"		SET A, 0x0" << std::endl;
		*block <<	"	IFN A, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		break;
	case COMPARE_GREATER_THAN_EQUAL:
		*block <<	"	SUB A, B" << std::endl;
		*block <<	"	IFE EX, 0x1" << std::endl;
		*block <<	"		SET A, 0x0" << std::endl;
		*block <<	"	IFE EX, 0x0" << std::endl;
		*block <<	"		SET A, 0x1" << std::endl;
		break;
	default:
		throw new CompilerException("Unknown binary operations requested.");
	}

	return block;
}

AsmBlock* NBinaryOperator::reference(AsmGenerator& context)
{
	throw new CompilerException("Unable to get reference to the result of an binary operator.");
}

{'fraction_non_alphanumeric': 0.19535293469882173, 'fraction_numerical': 0.01629776456337408, 'mean_word_length': 3.214385150812065, 'pattern_counts': {'":': 0, '<': 523, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1778220', 'n_tokens_mistral': 4238, 'n_tokens_neox': 3905, 'n_words': 1094}