WORD AssemblyParser::ParseRegValue(const std::string& token) { //TODO: UH OH, HOW TO DIFFERENTIATE BETWEEN ACCUMULATOR AND NUMERICAL?????? WORD reg_index = ParseRegister(token); if (reg_index == BAD_REGISTER_INDEX) { reg_index = stoi(token); } // TODO: support bin/hex/ASCII formats (0xAA, b1010101010101010 return reg_index; }
/* Translate the code of the current part, * assuming that part addresses the first character in an operand. */ bool TranslateOperand(bool sourceOperand) { if (ParseImmediateAddressing(sourceOperand, true, true, true)) /* immediate operand */ return true; if (localSyntaxError) return false; if (ParseRegister(sourceOperand, true)) /* register operand */ return true; if (ParseIndexAddressing(sourceOperand)) /* varied index operand */ return true; if (ParseDirectAddressing(sourceOperand)) /* direct addressing with label */ return true; return false; /* syntax error */ }
/** ** ParseBuffer: Handler client/server interaction. ** ** @param session Current session. */ static void ParseBuffer(Session *session) { char *buf; if (!session || session->Buffer[0] == '\0') { return; } buf = session->Buffer; if (!session->UserData.LoggedIn) { if (!strncmp(buf, "USER ", 5)) { ParseUser(session, buf + 5); } else if (!strncmp(buf, "REGISTER ", 9)) { ParseRegister(session, buf + 9); } else { fprintf(stderr, "Unknown command: %s\n", session->Buffer); Send(session, "ERR_BADCOMMAND\n"); } } else { if (!strncmp(buf, "USER ", 5) || !strncmp(buf, "REGISTER ", 9)) { Send(session, "ERR_ALREADYLOGGEDIN\n"); } else if (!strncmp(buf, "CREATEGAME ", 11)) { ParseCreateGame(session, buf + 11); } else if (!strcmp(buf, "CANCELGAME") || !strncmp(buf, "CANCELGAME ", 11)) { ParseCancelGame(session, buf + 10); } else if (!strcmp(buf, "STARTGAME") || !strncmp(buf, "STARTGAME ", 10)) { ParseStartGame(session, buf + 9); } else if (!strcmp(buf, "LISTGAMES") || !strncmp(buf, "LISTGAMES ", 10)) { ParseListGames(session, buf + 9); } else if (!strncmp(buf, "JOINGAME ", 9)) { ParseJoinGame(session, buf + 9); } else if (!strcmp(buf, "PARTGAME") || !strncmp(buf, "PARTGAME ", 9)) { ParsePartGame(session, buf + 8); } else if (!strncmp(buf, "ENDGAME ", 8)) { ParseEndGame(session, buf + 8); } else if (!strncmp(buf, "MSG ", 4)) { ParseMsg(session, buf + 4); } else { fprintf(stderr, "Unknown command: %s\n", session->Buffer); Send(session, "ERR_BADCOMMAND\n"); } } }
//TODO: need to rework //Parse whole line first //Get number of arguments //Get base op code //Get first argument register offset if exists //Get second argument register offset if exists //Calculate op_code //Get first value argument if exists (i.e. RAM address) //Get second value argument if exists (i.e. register or value) void AssemblyParser::Parse(const ASSEMBLY &assembly, Model::Memory &memory, PROGRAM_ASSEMBLY_MAP &program_map) { ADDRESS byte_address = memory.GetTopAddress(); std::map<std::string, ADDRESS> tag_map; unsigned int line_number = 0; bool found_begin = false; bool found_end = false; for (auto line : assembly) { line_number++; if (line == PROGRAM_BEGIN && !found_begin) { found_begin = true; memory.SetValue(byte_address++, Model::OpCode::GetOpCode(OP_BEGIN, 0)); } else if (line == PROGRAM_END && !found_end) { found_end = true; memory.SetValue(byte_address++, Model::OpCode::GetOpCode(OP_END, 0)); } else if (found_begin && !line.empty()) { std::istringstream strstream(line); std::string token; std::getline(strstream, token, ' '); //TODO: tags are any strings (a-z, A-Z, ending with :) //Tags must be defined before use //TODO: subroutines are blocks beginning with a tag and ending with ROUTINE_RET if (token.substr(0,1) == COMMENT_BEGIN) { continue; } else if (token.back() == TAG_END) { tag_map[token.substr(0,token.length() - 1)] = byte_address; memory.SetValue(byte_address++, OP_NOP); } else { program_map[line_number] = byte_address; auto base_op_code = ParseInstruction(token); auto num_arguments = Model::OpCode::GetNumArguments(base_op_code); if (num_arguments >= 1) { std::getline(strstream, token, ' '); int register_index = 0; auto op_code = Model::OpCode::GetOpCode(base_op_code, register_index); //TODO: get rid of comma if (base_op_code == OP_JMP) { if (tag_map.find(token) != tag_map.end()) { memory.SetValue(byte_address++, op_code); memory.SetValue(byte_address++, tag_map[token]); } } else { register_index = ParseRegister(token); op_code = Model::OpCode::GetOpCode(base_op_code, register_index); memory.SetValue(byte_address++, op_code); } if (num_arguments >= 2) { std::getline(strstream, token, ' '); auto value = ParseRegValue(token); memory.SetValue(byte_address++, value); } //TODO: what if more arguments? i.e. what about inline comments } else { memory.SetValue(byte_address++, base_op_code); } } } } }