Exemplo n.º 1
0
void Assembler::extractMacroDefinitions(){
	for(int lineNum=0; lineNum<program.size(); lineNum++){
		vector<ProgramLine> macroLines;
		ProgramLine programLine = program[lineNum];
		string token = parser.extractFirstToken(programLine.text);
		if(token == ".macro"){
			macroLines.push_back(programLine);
			program.erase(program.begin() + lineNum);
			while(lineNum < program.size()){
                if(parser.extractFirstToken(program[lineNum].text) == ".end_macro"){
					break;
				}
				macroLines.push_back(program[lineNum]);
				program.erase(program.begin() + lineNum);
			}
            if(program.size() == 0){
                //EXCEPTION
				string error = "Macro not matched with .end_macro directive before EOF";
				string offendingToken = programLine.text;
				addException(AssemblerException(programLine, error, offendingToken));
                return;
            }
			macroLines.push_back(program[lineNum]);
			program.erase(program.begin() + lineNum);
			MacroAtom atom = MacroAtom(macroLines);
			macroDB.push_back(atom);
			lineNum--;
		}else{

		}
	}
}
Exemplo n.º 2
0
void Assembler::replaceLabels(){
	for(int i=0; i<alignedProgram.size(); i++){
		ProgramAtom atom = alignedProgram[i];
		if(atom.type == DIRECTIVE_INSTRUCTION){
		//Modified replacement
			string mnemonic = parser.extractFirstToken(atom.token);
			mnemonic = parser.toLower(mnemonic);
			bool isBranch = parser.tokenIsBranchInstructionName(mnemonic);
			bool isJump = parser.tokenIsJumpInstructionName(mnemonic);
			vector<string> instructionTokens = parser.tokenizeInstruction(atom.token);
			if(isBranch || isJump){
				string lastToken = instructionTokens[instructionTokens.size() - 1];
				if(!tokenIsInLabelDB(lastToken)){
					//EXCEPTION
					string error = ERROR_UNRECOGNIZED_LABEL;
					string offendingToken = lastToken;
					addException(AssemblerException(*atom.programLine, error, offendingToken));
					continue;
				}
				virtualAddr labelAddr = getLabelAddress(lastToken);
				virtualAddr instructionAddr = atom.addr;
				virtualAddr immediateVal = 0;
				if(isBranch){
					int32_t offset = labelAddr - instructionAddr - 4;	//pc still increments by 4 on branches
					offset >>= 2;
					immediateVal = (virtualAddr)offset;
				}else if(isJump){
					immediateVal = (labelAddr & 0x0FFFFFFF) >> 2;
				}
				string immediateString = parser.literals.getHexLiteralString(immediateVal);
				instructionTokens[instructionTokens.size() - 1] = immediateString;
				string newInstructionString = parser.combineInstructionTokens(instructionTokens);
				alignedProgram[i].token = newInstructionString;
			}else{
Exemplo n.º 3
0
void Assembler::flushLabelBuffer(){
	for(int i=0; i<labelsToAssign.size(); i++){
		virtualAddr addr = memorySegmentTopArray[currentMemorySegment];
		try{
			addLabelAddress(parser.getLabelName(labelsToAssign[i]->text), addr);
		}catch(InvalidTokenException &e){
			//EXCEPTION
			string error = ERROR_INVALID_LABEL;
			string offendingToken = labelsToAssign[i]->text;
			addException(AssemblerException(*labelsToAssign[i], error, offendingToken));
			continue;
		}

		ProgramAtom atom;
		atom.addr = addr;
		atom.token = parser.getLabelName(labelsToAssign[i]->text);
		atom.type = DIRECTIVE_LABEL;
		atom.programLine = labelsToAssign[i];
		alignedProgram.push_back(atom);
	}
	labelsToAssign.clear();
}
Exemplo n.º 4
0
void Assembler::loadProgramFromFile(string fileName, ProgramLine* programLine){
	string programFileDir = rootDirectory + fileName;
	fstream file = fstream(programFileDir);
	if(!file.is_open()){
		//EXCEPTION
		string error = "I'm sorry Dave, I'm afraid I can't open that file";
		string offendingToken = rootDirectory + fileName;
		throw AssemblerException(*programLine, error, offendingToken);
		return;
	}
	string tmpProgramLine;
	uint32_t lineNumber = 0;
	while(getline(file, tmpProgramLine)){
		tmpProgramLine = parser.sanitizeProgramLine(tmpProgramLine);
		
		string token = parser.toLower(parser.extractFirstToken(tmpProgramLine));
		if(token == ".include"){
			parser.extractAndRemoveFirstToken(tmpProgramLine, token);
			string nestedFileName = parser.trim(tmpProgramLine);
			nestedFileName = parser.removeNestedQuotes(nestedFileName);
			nestedFileName = parser.trim(nestedFileName);
			ProgramLine* programLinePtr = (program.size() == 0)? NULL : &program[program.size() - 1];
			loadProgramFromFile(nestedFileName, programLinePtr);
			continue;
		}

		if(tmpProgramLine != ""){
			ProgramLine programLine;
			programLine.fileName = rootDirectory + fileName;
			programLine.lineNumber = lineNumber;
			programLine.text = tmpProgramLine;
			program.push_back(programLine);
		}
		
		lineNumber++;
	}
}
Exemplo n.º 5
0
unsigned short Assembler::start()
{
    unsigned short start = 0;
    Parser::LinePtr curLine;
    std::map<std::string, unsigned short> labelAddr;
    std::deque<Parser::LinePtr> lines;
    unsigned short curAddr(0);
#ifdef DEBUG
    std::cout << "Analyzing code..." << std::endl;
#endif
    while (curLine = m_parser.getNextLine()) {
        std::string lbl(curLine->label);
        if (!curLine->label.empty()) {
            if (labelAddr.find(curLine->label) != labelAddr.end()) {
                std::string msg("Duplicate label: ");
                msg += curLine->label;
                msg += " on line ";
                msg += (int)m_parser.getLineNumber();
                throw AssemblerException(msg);
            }
            labelAddr[curLine->label] = curAddr;
            this->labelReverse[curAddr] = curLine->label;
        }
        lines.push_back(curLine);
        byteToLineMap[curAddr] = (int)m_parser.getLineNumber();
        if (boost::dynamic_pointer_cast<Parser::Byte>(curLine)) {
            curAddr++;
        } else {
            curAddr+=4;
        }
    }
#ifdef DEBUG
    std::cout << "Processed: " << m_parser.getLineNumber() << " lines. " << labelAddr.size() << " labels, "
        << lines.size() * 4 << " bytes used." << std::endl;
    std::cout << "Building binary block..." << std::endl;
#endif

    curAddr = 0;
    while (lines.size()) {
        Parser::LinePtr line(lines.front());
        lines.pop_front();
        Parser::IntPtr intData(boost::dynamic_pointer_cast<Parser::Int>(line));
        Parser::BytePtr byteData(boost::dynamic_pointer_cast<Parser::Byte>(line));
        Parser::InstructionPtr instruction(boost::dynamic_pointer_cast<Parser::Instruction>(line));

        if (byteData) {
            // This is byte data
            m_block[curAddr] = byteData->value;
            curAddr++;
        } else if (intData) {
            *((int*)&m_block[curAddr]) = intData->value;
            curAddr += sizeof(intData->value);
        } else if (instruction) {
            // This is an actual "machine" instruction
            // First, let's record the address of the first instruction (relative to the "machine")
            if (!start)
                start = curAddr;
            ParamType type = PT_DEFAULT;
            instructionBlock block;
            block.value = 0;
            if (instruction->args.size() >= 1) {
                char reg(getRegister(instruction->args[0]));
                if (reg >= 0) {
                    block.uint8_param = (unsigned char)reg;
                    type = PT_REG;
                } else if (labelAddr.find(instruction->args[0]) != labelAddr.end()) {
                    block.uint16_param2 = labelAddr[instruction->args[0]];
                    type = PT_ADDR;
                } else {
                    try {
                        block.uint16_param2 = boost::lexical_cast<unsigned short>(instruction->args[0]);
                        type = PT_IMMEDIATE;
                    } catch (...) { // boost::bad_lexical_cast
                        std::string msg = "Invalid command; unrecognized argument 1 on command " + instruction->name;
                        msg += " on line " + boost::lexical_cast<std::string>(byteToLineMap[curAddr]);
                        throw AssemblerException(msg);
                    }
                }
            }
            if (instruction->args.size() >= 2 && !block.uint16_param2) {
                char reg(getRegister(instruction->args[1]));
                if (reg >= 0) {
                    block.uint8_param2 = (unsigned char)reg;
                    type = PT_REGREG;
                } else if (labelAddr.find(instruction->args[1]) != labelAddr.end()) {
                    block.uint16_param2 = labelAddr[instruction->args[1]];
                    type = PT_REGADDR;
                } else {
                    try {
                        block.uint16_param2 = boost::lexical_cast<unsigned short>(instruction->args[1]);
                        type = PT_REGIMMEDIATE;
                    } catch (...) { // boost::bad_lexical_cast
                        std::string msg = "Invalid command; unrecognized argument 2 on command " + instruction->name;
                        msg += " on line " + boost::lexical_cast<std::string>(byteToLineMap[curAddr]);
                        throw AssemblerException(msg);
                    }
                }
            }
            if (instruction->args.size() > 2) {
                throw AssemblerException("Too many arguments on command " + instruction->name + " on line " + boost::lexical_cast<std::string>(byteToLineMap[curAddr]));
            }
            block.instruction = m_config->strToBinary(instruction->name, type);
            *((int*)&m_block[curAddr]) = block.value;
            curAddr += sizeof(block.value);
        } else {
            throw AssemblerException("Invalid LinePtr found at " + curAddr);
        }
    }

    return start;
}
Exemplo n.º 6
0
//Post-processing
void Assembler::pseudoInstructionReplace(){
	for(int i=0; i<alignedProgram.size(); i++){
		ProgramAtom atom = alignedProgram[i];
		string line = atom.token;
		if(atom.type == DIRECTIVE_INSTRUCTION){
			string mnemonic = parser.extractFirstToken(atom.token);
			mnemonic = parser.toLower(mnemonic);
			if(parser.tokenIsPseudoInstructionName(mnemonic)){
				int pseudoInstructionNumber = parser.getPseudoInstructionNameNumber(mnemonic);
				int numInsertedLines = parser.getPseudoInstructionNumberOfLinesToInsert(mnemonic);
				vector<string> tokenizedInstruction = parser.tokenizeInstruction(line);
				switch(pseudoInstructionNumber){
					//TODO: add exceptions for incorrect number of instruction arguments
					case 0:
						{
							//bge	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName1 + ", " + registerName2;
							string line2 = "beq\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 1:
						{
							//bgt	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName2 + ", " + registerName1;
							string line2 = "bne\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 2:
						{
							//ble	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName2 + ", " + registerName1;
							string line2 = "beq\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;

						}
						break;
					case 3:
						{
							//blt	$reg1, $reg2, label
							if(tokenizedInstruction.size() != 4){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string labelName = tokenizedInstruction[3];
							string line1 = "slt\t$at, " + registerName1 + ", " + registerName2;
							string line2 = "bne\t$at, $zero, " + labelName;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 4:
						{
							//clear	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string line1 = "add\t" + registerName1 + ", $zero, $zero";
							alignedProgram[i].token = line1;
						}
						break;
					case 5:
						{
							//la	$reg, label
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string labelName = tokenizedInstruction[2];
							if(!tokenIsInLabelDB(labelName)){
								//EXCEPTION
								string error = ERROR_UNRECOGNIZED_LABEL;
								string offendingToken = labelName;
								addException(AssemblerException(*atom.programLine, error, offendingToken));
								continue;
							}
							virtualAddr labelAddr = getLabelAddress(labelName);
							virtualAddr msb = labelAddr >> (SIZE_BITS_VIRTUAL_ADDR / 2);
							virtualAddr lsb = labelAddr & 0x0000FFFF;
							string msbHex = parser.literals.getHexLiteralString(msb);
							string lsbHex = parser.literals.getHexLiteralString(lsb);
							string registerName = tokenizedInstruction[1];
							string line1 = "lui\t" + registerName + ", " + msbHex;
							string line2 = "ori\t" + registerName + ", " + registerName + ", " + lsbHex;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 6:
						{
							//li	$reg, imm
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string immediateString = tokenizedInstruction[2];

							//EXCEPTION
							//TODO
							uint32_t immediateVal;
							try{
								immediateVal = parser.literals.getLiteralValue(immediateString);
							}catch(InvalidTokenException &e){
								string error = ERROR_INVALID_IMMEDIATE_LI;
								string offendingToken = immediateString;
								addException(AssemblerException(*atom.programLine, error, offendingToken));
								continue;
							}
							virtualAddr msb = immediateVal >> (SIZE_BITS_WORD / 2);
							virtualAddr lsb = immediateVal & 0x0000FFFF;
							string msbHex = parser.literals.getHexLiteralString(msb);
							string lsbHex = parser.literals.getHexLiteralString(lsb);
							string registerName = tokenizedInstruction[1];
							string line1 = "lui\t" + registerName + ", " + msbHex;
							string line2 = "ori\t" + registerName + ", " + registerName + ", " + lsbHex;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;

						}
						break;
					case 7:
						{
							//move	$reg1, $reg2
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string line1 = "add\t" + registerName1 + ", " + registerName2 + ", $zero";
							alignedProgram[i].token = line1;
						}
						break;
					case 8:
						{
							//neg	$reg1, $reg2
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string line1 = "sub\t" + registerName1 + ", $zero, " + registerName2;
							alignedProgram[i].token = line1;
						}
						break;
					case 9:
						{
							//not	$reg1, $reg2
							if(tokenizedInstruction.size() != 3){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string registerName2 = tokenizedInstruction[2];
							string line1 = "addi\t" + registerName1 + ", $zero, -1";
							string line2 = "xor\t" + registerName1 + ", " + registerName1 + "," + registerName2;
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
						/*
						PUSH:
						sub $sp,$sp,4
						sw $t2,($sp)

						POP:
						lw $t2,($sp)
						addiu $sp,$sp,4
						*/
					case 10:
						{
							//push	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string line1 = "sub\t$sp, $sp, 4";
							string line2 = "sw\t" + registerName1 + ", 0($sp)";
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 11:
						{
							//pop	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName1 = tokenizedInstruction[1];
							string line1 = "lw\t" + registerName1 + ", 0($sp)";
							string line2 = "addi\t$sp, $sp, 4";
							alignedProgram[i].token = line1;
							alignedProgram[i+1].token = line2;
						}
						break;
					case 12:
						{
							//peak	$reg
							if(tokenizedInstruction.size() != 2){addException(AssemblerException(*atom.programLine, ERROR_INVALID_PSEUDOINSTRUCTION, atom.programLine->text));continue;}
							string registerName = tokenizedInstruction[1];
							string line = "lw\t" + registerName + ", 0($sp)";
							alignedProgram[i].token = line;
						}
						break;
					case 13:
						{
							//rem

						}
						break;
					case 14:
						{
							//sge

						}
						break;
					case 15:
						{
							//sgt

						}
						break;
					default:

						break;
				}
				i += numInsertedLines;
			}else{

			}
		}else{

		}
	}
}
Exemplo n.º 7
0
void Assembler::alignRawProgram(){
	for(int lineNum=0; lineNum<program.size(); lineNum++){
		ProgramLine programLine = program[lineNum];

		string token = parser.extractFirstToken(programLine.text);
		if(parser.tokenIsLabel(token)){
			string labelName = parser.getLabelName(token);
			programLine.text = labelName;
			labelsToAssign.push_back(&program[lineNum]);
			continue;
		}else if(parser.tokenIsDirective(token)){
			parser.extractAndRemoveFirstToken(programLine.text, token);
			applyDirective(token, &programLine);
			token = parser.extractFirstToken(programLine.text);
		}
		
		if(programLine.text == "" && currentAction != ACTION_DECLARE_SEGMENT && currentAction != ACTION_MEMWRITE_INTEGRAL){
			continue; //if programLine is all consumed, skip to next line unless you need to declare segment in following actions
		}
		//consume literal token
		ProgramAtom atom;
		string mappedProgramString;
		switch(currentAction){
			case ACTION_INIT:
				{
					string error = ERROR_UNRECOGNIZED_TOKEN;
					string offendingToken = programLine.text;
					addException(AssemblerException(program[lineNum], error, offendingToken));
					continue;
				}
				break;
			case ACTION_DECLARE_SEGMENT:
				{
					virtualAddr addr = getCurrentMemoryLocation();
					mappedProgramString = parser.getDirectiveName(currentMemorySegment);
					atom.addr = addr;
					atom.token = mappedProgramString;
					atom.type = currentMemorySegment;
					atom.programLine = &program[lineNum];
					alignedProgram.push_back(atom);
					switch(currentMemorySegment){
						case DIRECTIVE_DATA:
							currentAction = ACTION_INIT;
							break;
						case DIRECTIVE_TEXT:
							currentAction = ACTION_INSTRUCTION_ENCODE;
							break;
						case DIRECTIVE_KDATA:
							currentAction = ACTION_INIT;
							break;
						case DIRECTIVE_KTEXT:
							currentAction = ACTION_INSTRUCTION_ENCODE;
							break;
					}
				}
				break;
			case ACTION_MEMWRITE_INTEGRAL:
				{
					alignSegmentTop();
					flushLabelBuffer();

					vector<string> literalTokens = parser.commaSeparatedLiteralListExplode(programLine.text);
					alignLiteralTokenList(literalTokens, programLine.text, &program[lineNum]);
					currentAction = ACTION_INIT;
				}
				break;
			case ACTION_MEMWRITE_STRING:
				{
					flushLabelBuffer();
					int i=0;
					while(programLine.text[i] != '"'){i++;}

					string stringLiteral = programLine.text.substr(i);
					string rawString;
					try{
						rawString = parser.literals.getStringLiteralValue(stringLiteral);
					}catch(InvalidTokenException &e){
						//EXCEPTION
						string error = ERROR_INVALID_STRING_LITERAL;
						string offendingToken = programLine.text;
						addException(AssemblerException(program[lineNum], error, offendingToken));
						continue;
					}

					mappedProgramString = parser.literals.getRawStringLiteralValue(rawString);
					atom.addr = getCurrentMemoryLocation();
					atom.token = mappedProgramString;
					atom.type = currentValueTypeSpecifier;
					atom.programLine = &program[lineNum];
					alignedProgram.push_back(atom);
					
					virtualAddr segmentIncrementSize = rawString.length() * SIZE_BYTES_BYTE;
					if(currentValueTypeSpecifier == DIRECTIVE_ASCIIZ){
						segmentIncrementSize+=2;
					}

					incrementSegmentTop(segmentIncrementSize);
					currentAction = ACTION_INIT;
				}
				break;
			case ACTION_ALIGN:
				{
					try{
						currentByteAlignment = parser.literals.getFixedPointLiteralValue(token);
					}catch(InvalidTokenException &e){
						string error = ERROR_INVALID_ALIGNMENT_VALUE;
						string offendingToken = token;
						addException(AssemblerException(program[lineNum], error, token));
						continue;
					}
					alignSegmentTop();
					currentAction = ACTION_INIT;
				}
				break;
			case ACTION_SPACE:
				{
					currentByteAlignment = SIZE_BYTES_BYTE;
					alignSegmentTop();
					flushLabelBuffer();

					parser.extractAndRemoveFirstToken(programLine.text, token);
					uint32_t spaceSize = 0;
					try{
						spaceSize = parser.literals.getFixedPointLiteralValue(token);
					}catch(InvalidTokenException &e){
						//EXCEPTION
						string error = ERROR_INVALID_SPACE_VALUE;
						string offendingToken = token;
						addException(AssemblerException(program[lineNum], error, offendingToken));
						continue;
					}

					atom.token = parser.literals.getDecimalLiteralString(spaceSize);
					atom.addr = getCurrentMemoryLocation();
					atom.type = DIRECTIVE_SPACE;
					atom.programLine = &program[lineNum];
					alignedProgram.push_back(atom);

					incrementSegmentTop(spaceSize);
					currentAction = ACTION_INIT;
				}
				break;
			case ACTION_INSTRUCTION_ENCODE:
				{
					currentByteAlignment = SIZE_BYTES_WORD;
					alignSegmentTop();
					flushLabelBuffer();

					atom.addr = getCurrentMemoryLocation();
					atom.token = programLine.text;	//instruction full line
					atom.type = DIRECTIVE_INSTRUCTION;
					atom.programLine = &program[lineNum];
					alignedProgram.push_back(atom);

					incrementSegmentTop(SIZE_BYTES_WORD);
				}
				break;
			default:
				
				break;
		}
	}
}
Exemplo n.º 8
0
void Assembler::applyDirective(string directive, ProgramLine* programLine){
	uint32_t directiveNumber = parser.getDirectiveNumber(directive);
	switch(directiveNumber){
		//Primary memory segments
		case DIRECTIVE_DATA:
			currentMemorySegment = DIRECTIVE_DATA;
			currentAction = ACTION_DECLARE_SEGMENT;
			break;
		case DIRECTIVE_TEXT:
			currentMemorySegment = DIRECTIVE_TEXT;
			currentAction = ACTION_DECLARE_SEGMENT;
			break;
		case DIRECTIVE_KDATA:
			currentMemorySegment = DIRECTIVE_KDATA;
			currentAction = ACTION_DECLARE_SEGMENT;
			break;
		case DIRECTIVE_KTEXT:
			currentMemorySegment = DIRECTIVE_KTEXT;
			currentAction = ACTION_DECLARE_SEGMENT;
			break;

		//Memory value type specifiers (integral)
		case DIRECTIVE_BYTE:
			currentValueTypeSpecifier = DIRECTIVE_BYTE;
			currentByteAlignment = SIZE_BYTES_BYTE;
			currentAction = ACTION_MEMWRITE_INTEGRAL;
			break;
		case DIRECTIVE_HALF:
			currentValueTypeSpecifier = DIRECTIVE_HALF;
			currentByteAlignment = SIZE_BYTES_HWORD;
			currentAction = ACTION_MEMWRITE_INTEGRAL;
			break;
		case DIRECTIVE_WORD:
			currentValueTypeSpecifier = DIRECTIVE_WORD;
			currentByteAlignment = SIZE_BYTES_WORD;
			currentAction = ACTION_MEMWRITE_INTEGRAL;
			break;
		case DIRECTIVE_FLOAT:
			currentValueTypeSpecifier = DIRECTIVE_FLOAT;
			currentByteAlignment = SIZE_BYTES_FLOAT;
			currentAction = ACTION_MEMWRITE_INTEGRAL;
			break;
		case DIRECTIVE_DOUBLE:
			currentValueTypeSpecifier = DIRECTIVE_DOUBLE;
			currentByteAlignment = SIZE_BYTES_DOUBLE;
			currentAction = ACTION_MEMWRITE_INTEGRAL;
			break;

		//Memory value type specifiers (string)
		case DIRECTIVE_ASCII:
			currentValueTypeSpecifier = DIRECTIVE_ASCII;
			currentByteAlignment = SIZE_BYTES_BYTE;
			currentAction = ACTION_MEMWRITE_STRING;
			break;
		case DIRECTIVE_ASCIIZ:
			currentValueTypeSpecifier = DIRECTIVE_ASCIIZ;
			currentByteAlignment = SIZE_BYTES_BYTE;
			currentAction = ACTION_MEMWRITE_STRING;
			break;

		//Memory alignment specifiers
		case DIRECTIVE_ALIGN:
			currentAction = ACTION_ALIGN;
			break;
		case DIRECTIVE_SPACE:
			currentByteAlignment = SIZE_BYTES_BYTE;
			currentAction = ACTION_SPACE;
			break;
		case DIRECTIVE_INCLUDE:

			break;
		case DIRECTIVE_EXTERN:

			break;
		case DIRECTIVE_GLOBL:

			break;
		case DIRECTIVE_SET:

			break;
		case DIRECTIVE_MACRO:
            currentAction = ACTION_INSTRUCTION_ENCODE;
			break;
		case DIRECTIVE_END_MACRO:
            currentAction = ACTION_INIT;
			break;
		case DIRECTIVE_EQV:

			break;
		default:
			//EXCEPTION
			string error = ERROR_UNRECOGNIZED_DIRECTIVE;
			string offendingToken = directive;
			addException(AssemblerException(*programLine, error, offendingToken));
			break;
	}
}