<commit_before>/*	____________________________________________________________________________

	    Semantics and Coding Component Implementation for the Micro Compiler

	                               mcode.cpp

	                              Version 2007

	                           <NAME>
	                     Last Update: August 28, 2007
	                     Update by <NAME>: January 21,2016

	The routines in this unit are based on those provided in the book
	"Crafting A Compiler" by <NAME> and <NAME>, Jr.,
	Benjamin Cummings Publishing Co. (1991).

	See Section 2.3-2.4, pp. 31-40.
	____________________________________________________________________________
*/

#include <iostream>
#include <fstream>
using namespace std;

extern ifstream sourceFile;
extern ofstream outFile, listFile;

#include "mscan.h"   // Scanner class definition
#include "mcode.h"   // CodeGen class definition

extern Scanner scan; // global Scanner object declared in micro.cpp

// *******************
// **  Constructor  **
// *******************

CodeGen::CodeGen() {
	maxTemp = 0;
}

// *******************************
// ** Private Member Functions  **
// *******************************

void CodeGen::Enter(ExprRec& var) {
	/* Create the key and fill it */
	SymbolEntry variable;
	variable.name = var.name;
	variable.type = var.var_type;
	/* Check variable size */
	switch (var.var_type) {
	case BOOL:
		variable.size = 2 * var.hiphip_size; /* 16 bits per BOOL */
		variable.ival = 0; /* init with boolean "False" value */
		break;
	case INT:
		variable.size = 2 * var.hiphip_size; /* 16 bits per INT */
		variable.ival = 0; /* init with integer 0 value */
		break;
	case FLOAT:
		variable.size = 4 * var.hiphip_size; /* 32 bits per FLOAT */
		if (var.s_fval.size() > 0) {
			variable.s_fval = var.s_fval; /* use assigned value */
		} else {
			variable.s_fval = "0.0"; /* init with 0.0 */
		}
		break;

	case CHEESE:
		variable.label = NewStringLabel();
		if (var.kind == ID_EXPR) {
			/* TODO: allow other sizes and check if it is even */
			/* Default size per CHEESE*/
			if(var.stringLength != 1024 && var.stringLength!=0){
				variable.size = var.stringLength;
			} else {
				variable.size = 1024;
			}
		} else {
			int var_size = scan.cheese_size;
			/* Only even number of bytes are allowed */
			if (var_size % 2) {
				var_size++;
			}
			/* var_size per CHEESE */
			variable.size = var_size * var.hiphip_size;
			/* Set the initial value of the string */
			variable.sval = var.sval;
		}
		break;
	default:
		/* Compiler internal error */
		CompilerError("fatal error in function Enter.");
		break;
	}
	/* Update hiphip data */
	variable.arrayLength = var.hiphip_size;
	variable.isArray = (var.hiphip_size > 1);
	/* Add the record to the symbol table */
	symbolTable.push_back(variable);
}

void CodeGen::ExtractExpr(const ExprRec& e, string& s, \
		const ExprRec& index, int offset) {
	string t;
	int k, n;

	/* FIXME FIX THIS FUNCTION. IT IS WORKING FOR THE WRONG REASON */
	if (index.var_type != INT) {
		/* FIXME: throw an error instead and find a way to check 
		 * if the ExprRec index was initialized by mparser. In other
		 * words, if an index was assigned in mnc.
		 */
		ExtractExpr(e, s, offset);
	} else {
		/* Only variables are allowed to have hiphip_size > 1 */
		s = e.name;
		k = n = 0;
		while (symbolTable[n].name != s) {
			k += symbolTable[n].size;
			n++;
		}
		/* TODO add a fatal error here if n is out of bounds */
		IntToAlpha(k, t);
		s = "#" + t;
		/* Load variable base address on R11 */
		Generate("LD        ", "R11", "R15");
		Generate("IA        ", "R11", s);
		/* Load index on R10 */
		ExtractExpr(index, s, 0);
		Generate("LD        ", "R10", s);
		/* Call subroutine to calculate address */
		switch (e.var_type) {
		case BOOL:
		case INT:
		case CHEESE:
			/* Call the IDXINT subroutine */
			Generate("JSR       ", "R7", "IDXINT");
			break;
		case FLOAT:
			/* Call the IDXREAL subroutine */
			Generate("JSR       ", "R7", "IDXREAL");
			break;
		default:
			/* Compiler internal error */
			CompilerError("fatal error in function "
					"ExtractExpr(hiphip).");
			break;
		}
		/* Return R10 as the address */
		s = "+0(R10)";
	}
}

void CodeGen::ExtractExpr(const ExprRec & e, string& s, int offset) {
	string t;
	int k, n;

	switch (e.kind) {
	case ID_EXPR:
	case TEMP_EXPR:  /* operand form: +k(R15) */
		s = e.name;
		k = n = 0;
		while (symbolTable[n].name != s) {
			k += symbolTable[n].size;
			n++;
		}
		/* TODO add a fatal error here if n is out of bounds */
		k = k + offset; /* add offset bytes to k */
		IntToAlpha(k, t);
		s = "+" + t + "(R15)";
		break;
	case LITERAL_EXPR:
		switch (e.var_type) {
		case BOOL:
			IntToAlpha(e.ival, t);
			s = "#" + t;
			break;
		case INT:<commit_msg>Fix the FLOAT hiphips addressing.<commit_after>/*	____________________________________________________________________________

	    Semantics and Coding Component Implementation for the Micro Compiler

	                               mcode.cpp

	                              Version 2007

	                           <NAME>
	                     Last Update: August 28, 2007
	                     Update by <NAME>: January 21,2016

	The routines in this unit are based on those provided in the book
	"Crafting A Compiler" by <NAME> and <NAME>, Jr.,
	<NAME> Publishing Co. (1991).

	See Section 2.3-2.4, pp. 31-40.
	____________________________________________________________________________
*/

#include <iostream>
#include <fstream>
using namespace std;

extern ifstream sourceFile;
extern ofstream outFile, listFile;

#include "mscan.h"   // Scanner class definition
#include "mcode.h"   // CodeGen class definition

extern Scanner scan; // global Scanner object declared in micro.cpp

// *******************
// **  Constructor  **
// *******************

CodeGen::CodeGen() {
	maxTemp = 0;
}

// *******************************
// ** Private Member Functions  **
// *******************************

void CodeGen::Enter(ExprRec& var) {
	/* Create the key and fill it */
	SymbolEntry variable;
	variable.name = var.name;
	variable.type = var.var_type;
	/* Check variable size */
	switch (var.var_type) {
	case BOOL:
		variable.size = 2 * var.hiphip_size; /* 16 bits per BOOL */
		variable.ival = 0; /* init with boolean "False" value */
		break;
	case INT:
		variable.size = 2 * var.hiphip_size; /* 16 bits per INT */
		variable.ival = 0; /* init with integer 0 value */
		break;
	case FLOAT:
		variable.size = 4 * var.hiphip_size; /* 32 bits per FLOAT */
		if (var.s_fval.size() > 0) {
			variable.s_fval = var.s_fval; /* use assigned value */
		} else {
			variable.s_fval = "0.0"; /* init with 0.0 */
		}
		break;

	case CHEESE:
		variable.label = NewStringLabel();
		if (var.kind == ID_EXPR) {
			/* TODO: allow other sizes and check if it is even */
			/* Default size per CHEESE*/
			if(var.stringLength != 1024 && var.stringLength!=0){
				variable.size = var.stringLength;
			} else {
				variable.size = 1024;
			}
		} else {
			int var_size = scan.cheese_size;
			/* Only even number of bytes are allowed */
			if (var_size % 2) {
				var_size++;
			}
			/* var_size per CHEESE */
			variable.size = var_size * var.hiphip_size;
			/* Set the initial value of the string */
			variable.sval = var.sval;
		}
		break;
	default:
		/* Compiler internal error */
		CompilerError("fatal error in function Enter.");
		break;
	}
	/* Update hiphip data */
	variable.arrayLength = var.hiphip_size;
	variable.isArray = (var.hiphip_size > 1);
	/* Add the record to the symbol table */
	symbolTable.push_back(variable);
}

void CodeGen::ExtractExpr(const ExprRec& e, string& s, \
		const ExprRec& index, int offset) {
	string t;
	int k, n;

	/* FIXME FIX THIS FUNCTION. IT IS WORKING FOR THE WRONG REASON */
	if (index.var_type != INT) {
		/* FIXME: throw an error instead and find a way to check 
		 * if the ExprRec index was initialized by mparser. In other
		 * words, if an index was assigned in mnc.
		 */
		ExtractExpr(e, s, offset);
	} else {
		/* Only variables are allowed to have hiphip_size > 1 */
		s = e.name;
		k = n = 0;
		while (symbolTable[n].name != s) {
			k += symbolTable[n].size;
			n++;
		}
		/* TODO add a fatal error here if n is out of bounds */
		IntToAlpha(k, t);
		s = "#" + t;
		/* Load variable base address on R11 */
		Generate("LD        ", "R11", "R15");
		Generate("IA        ", "R11", s);
		/* Load index on R10 */
		ExtractExpr(index, s, 0);
		Generate("LD        ", "R10", s);
		/* Call subroutine to calculate address */
		switch (e.var_type) {
		case BOOL:
		case INT:
		case CHEESE:
			/* Call the IDXINT subroutine */
			Generate("JSR       ", "R7", "IDXINT");
			break;
		case FLOAT:
			/* Call the IDXREAL subroutine */
			Generate("JSR       ", "R7", "IDXREAL");
			break;
		default:
			/* Compiler internal error */
			CompilerError("fatal error in function "
					"ExtractExpr(hiphip).");
			break;
		}
		/* Add the offset and return the address +offset(R10) */
		IntToAlpha(offset, t);
		s = "+" + t + "(R10)";
	}
}

void CodeGen::ExtractExpr(const ExprRec & e, string& s, int offset) {
	string t;
	int k, n;

	switch (e.kind) {
	case ID_EXPR:
	case TEMP_EXPR:  /* operand form: +k(R15) */
		s = e.name;
		k = n = 0;
		while (symbolTable[n].name != s) {
			k += symbolTable[n].size;
			n++;
		}
		/* TODO add a fatal error here if n is out of bounds */
		k = k + offset; /* add offset bytes to k */
		IntToAlpha(k, t);
		s = "+" + t + "(R15)";
		break;
	case LITERAL_EXPR:
		switch (e.var_type) {
		case BOOL:
			IntToAlpha(e.ival, t);
			s = "#" + t;
			break;
		case INT:
{'fraction_non_alphanumeric': 0.1495249034144304, 'fraction_numerical': 0.017437610942883992, 'mean_word_length': 2.6725460122699385, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 22, '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': '1133800', 'n_tokens_mistral': 3643, 'n_tokens_neox': 3176, 'n_words': 1006}