Добавлен: 16.03.2024
Просмотров: 47
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
SimpleAssembler
main.cpp
const short int MEM_SIZE = 100 ;
unsigned short int memory[MEM_SIZE] {0};
#include
#include
#include
#include
#include "commands.hpp"
int readFile(FILE * fb) ;
int commandEncode(unsigned short int command, unsigned short int operand, unsigned short int * value) ;
bool checkCorrectInputHEX(const char *buffer) ;
int main(int argc, char const *argv[])
{
if (argc != 3) {
printf("\033[38;5;196mThe number of arguments does not match the condition!\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n") ;
return -1 ;
}
if (strcmp(strrchr(argv[1], '.'), ".sa") != 0) {
printf("\033[38;5;196mThe extension of the first argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n", argv[1]) ;
return -1 ;
}
if (strcmp(strrchr(argv[2], '.'), ".o") != 0) {
printf("\033[38;5;196mThe extension of the second argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n", argv[2]) ;
return -1 ;
}
FILE * fb ;
if (!(fb = fopen(argv[1], "r"))){
printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck whether the file is in the directory, as well as access rights.\n", argv[1]) ;
return -1 ;
}
if (readFile(fb))
return -1 ;
fclose(fb) ;
if (!(fb = fopen(argv[2], "wb"))){
printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck your access rights.\n", argv[2]) ;
return -1 ;
}
fwrite(memory, sizeof(memory), 1, fb) ;
fclose(fb) ;
return 0 ;
}
int readFile(FILE * fb){
char buffer[256] ;
short int prevCell = -1, currCell ;
unsigned short int currLine = 1, comm = 0, op = 0, res;
char *part, *strCell;
while (fgets(buffer, 256, fb)) {
/* Часть с адресом ячейки */
part = strtok (buffer, " ") ;
if (strlen(part) != 2){
printf("\033[38;5;196mError | line %d\033[0m \nThe cell address number must be 2 characters long.\n", currLine) ;
return -1 ;
}
for (int i = 0 ; i < 2 ; ++i)
{
if (part[i] < '0' || part[i] > '9'){
printf("\033[38;5;196mError | line %d\033[0m \nThe cell number cannot consist of letters. The cell number must be entered in the 10 number system.\n", currLine) ;
return -1 ;
}
}
currCell = atoi(part);
if (currCell <= prevCell){
printf("\033[38;5;196mError | line %d\033[0m \nThe number of the memory address must be increasing and must not be repeated.\n", currLine) ;
return -1 ;
}
else
prevCell = currCell ;
/* Часть с командой */
part = strtok (NULL, " ");
if (strcmp(part, "READ") == 0)
comm = READ;
else if (strcmp(part, "WRITE") == 0)
comm = WRITE;
else if (strcmp(part, "LOAD") == 0)
comm = LOAD;
else if (strcmp(part, "STORE") == 0)
comm = STORE;
else if (strcmp(part, "ADD") == 0)
comm = ADD;
else if (strcmp(part, "SUB") == 0)
comm = SUB;
else if (strcmp(part, "DIVIDE") == 0)
comm = DIVIDE;
else if (strcmp(part, "MUL") == 0)
comm = MUL;
else if (strcmp(part, "JUMP") == 0)
comm = JUMP;
else if (strcmp(part, "JNEG") == 0)
comm = JNEG;
else if (strcmp(part, "JZ") == 0)
comm = JZ;
else if (strcmp(part, "HALT") == 0)
comm = HALT;
else if (strcmp(part, "RCR") == 0)
comm = RCR;
else if (strcmp(part, "=") == 0)
comm = 0 ;
else{
printf("\033[38;5;196mError | line %d\033[0m \nUnknown command\n", currLine) ;
return -1 ;
}
/* Часть с операндом */
part = strtok (NULL, " ");
if (part[strlen(part) - 1] == '\n')
part[strlen(part) - 1] = '\0' ;
if (comm != 0){ // Если не присваивание
for (int i = 0 ; i < strlen(part) ; ++i)
if (part[i] < '0' || part[i] > '9'){
printf("\033[38;5;196mError | line %d\033[0m \nThe operand cannot contain letters. The operand must be set in the 10 number system.\n", currLine) ;
return -1 ;
}
op = atoi(part) ;
if (commandEncode((unsigned short int)((comm & 0xFF)), (unsigned short int)(op & 0xFF), &res)){
printf("\033[38;5;196mError | line %d\033[0m \nInvalid command, the command cannot exceed 3FFF.\n", currLine) ;
return -1 ;
}
}
else{
res = 0 ;
int i = 0;
if (part[0] == '+')
i = 1 ;
else{
res |= (1 << 14) ;
if (part[0] == '-') {
i = 1 ;
res |= (1 << 13) ;
}
else
i = 0 ;
}
if (!checkCorrectInputHEX(&part[i])){
printf("\033[38;5;196mError | line %d\033[0m \nIncorrect assignment.\n", currLine) ;
return -1 ;
}
long int number ;
char * tmp ;
number = strtol(&part[i], &tmp, 16) ;
if (part[0] == '+') { // Если команда
if ((number >> 8) > 0x7F){
printf("\033[38;5;196mError | line %d\033[0m \nThe command cannot be more than 7 bits (0x7F).\n", currLine) ;
return -1 ;
}
if ((number & 0xFF) > 0x7F){
printf("\033[38;5;196mError | line %d\033[0m \nThe operand cannot be more than 7 bits (0x7F).\n", currLine) ;
return -1 ;
}
unsigned short int value = 0;
commandEncode((unsigned short int)((number >> 8)), (unsigned short int)(number & 0xFF), &value) ;
res |= value ;
}
else { // Если число
if(number > 0x2000 or (number > 0x1FFF and part[0] != '-') ){
printf("\033[38;5;196mError | line %d\033[0m \nThe valid range for the value of the number from -0x2000 to 0x1FFF inclusive.\n", currLine) ;
return -1 ;
}
if (part[0] == '-') {
number =
number + 1 ;
if (!((number >> 13) & 1))
res &=
(1 << 13) ;
SimpleAssembler
main.cpp
const short int MEM_SIZE = 100 ;
unsigned short int memory[MEM_SIZE] {0};
#include
#include
#include
#include
#include "commands.hpp"
int readFile(FILE * fb) ;
int commandEncode(unsigned short int command, unsigned short int operand, unsigned short int * value) ;
bool checkCorrectInputHEX(const char *buffer) ;
int main(int argc, char const *argv[])
{
if (argc != 3) {
printf("\033[38;5;196mThe number of arguments does not match the condition!\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n") ;
return -1 ;
}
if (strcmp(strrchr(argv[1], '.'), ".sa") != 0) {
printf("\033[38;5;196mThe extension of the first argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n", argv[1]) ;
return -1 ;
}
if (strcmp(strrchr(argv[2], '.'), ".o") != 0) {
printf("\033[38;5;196mThe extension of the second argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleAssembler file.sa file.o, where file.sa – name of the file that contains the program in Simple Assembler, file. o-translation result\n", argv[2]) ;
return -1 ;
}
FILE * fb ;
if (!(fb = fopen(argv[1], "r"))){
printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck whether the file is in the directory, as well as access rights.\n", argv[1]) ;
return -1 ;
}
if (readFile(fb))
return -1 ;
fclose(fb) ;
if (!(fb = fopen(argv[2], "wb"))){
printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck your access rights.\n", argv[2]) ;
return -1 ;
}
fwrite(memory, sizeof(memory), 1, fb) ;
fclose(fb) ;
return 0 ;
}
int readFile(FILE * fb){
char buffer[256] ;
short int prevCell = -1, currCell ;
unsigned short int currLine = 1, comm = 0, op = 0, res;
char *part, *strCell;
while (fgets(buffer, 256, fb)) {
/* Часть с адресом ячейки */
part = strtok (buffer, " ") ;
if (strlen(part) != 2){
printf("\033[38;5;196mError | line %d\033[0m \nThe cell address number must be 2 characters long.\n", currLine) ;
return -1 ;
}
for (int i = 0 ; i < 2 ; ++i)
{
if (part[i] < '0' || part[i] > '9'){
printf("\033[38;5;196mError | line %d\033[0m \nThe cell number cannot consist of letters. The cell number must be entered in the 10 number system.\n", currLine) ;
return -1 ;
}
}
currCell = atoi(part);
if (currCell <= prevCell){
printf("\033[38;5;196mError | line %d\033[0m \nThe number of the memory address must be increasing and must not be repeated.\n", currLine) ;
return -1 ;
}
else
prevCell = currCell ;
/* Часть с командой */
part = strtok (NULL, " ");
if (strcmp(part, "READ") == 0)
comm = READ;
else if (strcmp(part, "WRITE") == 0)
comm = WRITE;
else if (strcmp(part, "LOAD") == 0)
comm = LOAD;
else if (strcmp(part, "STORE") == 0)
comm = STORE;
else if (strcmp(part, "ADD") == 0)
comm = ADD;
else if (strcmp(part, "SUB") == 0)
comm = SUB;
else if (strcmp(part, "DIVIDE") == 0)
comm = DIVIDE;
else if (strcmp(part, "MUL") == 0)
comm = MUL;
else if (strcmp(part, "JUMP") == 0)
comm = JUMP;
else if (strcmp(part, "JNEG") == 0)
comm = JNEG;
else if (strcmp(part, "JZ") == 0)
comm = JZ;
else if (strcmp(part, "HALT") == 0)
comm = HALT;
else if (strcmp(part, "RCR") == 0)
comm = RCR;
else if (strcmp(part, "=") == 0)
comm = 0 ;
else{
printf("\033[38;5;196mError | line %d\033[0m \nUnknown command\n", currLine) ;
return -1 ;
}
/* Часть с операндом */
part = strtok (NULL, " ");
if (part[strlen(part) - 1] == '\n')
part[strlen(part) - 1] = '\0' ;
if (comm != 0){ // Если не присваивание
for (int i = 0 ; i < strlen(part) ; ++i)
if (part[i] < '0' || part[i] > '9'){
printf("\033[38;5;196mError | line %d\033[0m \nThe operand cannot contain letters. The operand must be set in the 10 number system.\n", currLine) ;
return -1 ;
}
op = atoi(part) ;
if (commandEncode((unsigned short int)((comm & 0xFF)), (unsigned short int)(op & 0xFF), &res)){
printf("\033[38;5;196mError | line %d\033[0m \nInvalid command, the command cannot exceed 3FFF.\n", currLine) ;
return -1 ;
}
}
else{
res = 0 ;
int i = 0;
if (part[0] == '+')
i = 1 ;
else{
res |= (1 << 14) ;
if (part[0] == '-') {
i = 1 ;
res |= (1 << 13) ;
}
else
i = 0 ;
}
if (!checkCorrectInputHEX(&part[i])){
printf("\033[38;5;196mError | line %d\033[0m \nIncorrect assignment.\n", currLine) ;
return -1 ;
}
long int number ;
char * tmp ;
number = strtol(&part[i], &tmp, 16) ;
if (part[0] == '+') { // Если команда
if ((number >> 8) > 0x7F){
printf("\033[38;5;196mError | line %d\033[0m \nThe command cannot be more than 7 bits (0x7F).\n", currLine) ;
return -1 ;
}
if ((number & 0xFF) > 0x7F){
printf("\033[38;5;196mError | line %d\033[0m \nThe operand cannot be more than 7 bits (0x7F).\n", currLine) ;
return -1 ;
}
unsigned short int value = 0;
commandEncode((unsigned short int)((number >> 8)), (unsigned short int)(number & 0xFF), &value) ;
res |= value ;
}
else { // Если число
if(number > 0x2000 or (number > 0x1FFF and part[0] != '-') ){
printf("\033[38;5;196mError | line %d\033[0m \nThe valid range for the value of the number from -0x2000 to 0x1FFF inclusive.\n", currLine) ;
return -1 ;
}
if (part[0] == '-') {
number =
}
number &= 0x1FFF ;
res |= number ;
}
}
/* Часть с комментарием */
part = strtok (NULL, " ");
if (part != NULL and part[0] != ';' and part[0] != '\n'){
printf("\033[38;5;196mError | line %d\033[0m \nThe wrong line! Invalid number of arguments or comment doesn't start with ';'\n", currLine) ;
return -1 ;
}
memory[currCell] = res;
++currLine ;
}
return 0 ;
}
int commandEncode(unsigned short int command, unsigned short int operand, unsigned short int * value){
if (command > 0x7F)
return -1 ;
if (operand > 0x7F)
return -1 ;
* value = 0 ;
/* Операнд */
for (int i = 0 ; i < 7 ; i++) {
int8_t bit = (operand >> i) & 1 ;
*value |= (bit << i) ;
}
/* Команда */
for (int i = 0 ; i < 7 ; i++) {
int8_t bit = (command >> i) & 1 ;
*value |= (bit << (i + 7)) ;
}
return 0 ;
}
bool checkCorrectInputHEX(const char *buffer){
if (strlen(buffer) == 0 or strlen(buffer) > 4)
return false ;
for (int i = 0 ; i < strlen(buffer) ; ++i)
if (!(isxdigit(buffer[i])))
return false ;
return true ;
}
commands.hpp
#ifndef COMMANDS_HPP
#define COMMANDS_HPP
#define READ 0x10
#define WRITE 0x11
#define LOAD 0x20
#define STORE 0x21
#define ADD 0x30
#define SUB 0x31
#define DIVIDE 0x32
#define MUL 0x33
#define JUMP 0x40
#define JNEG 0x41
#define JZ 0x42
#define HALT 0x43
#define RCR 0x63
#endif //COMMANDS_HPP
SimpleBasic
main.cpp
#include
#include
#include
#include
short currCellVar = 99 ;
short currCellComm = 0 ;
struct variable{
variable(std::string title, short address){
this->address = address ;
this->title = title ;
}
std::string title ;
short address ;
};
struct commandSA{
commandSA(short cell, const std::string &command, short operand) {
this->cell = cell ;
this->command = command ;
this->operand = operand ;
}
short cell ;
std::string command ;
short operand ;
};
std::map<:string short> startCommands ; // Начало команд (всё ради goto :3) | Строка в SB, адрес ячейки в SA
std::vector
std::vector
std::vector
const std::regex basicCheckLine(R"((\d+)\s+(REM|INPUT|PRINT|LET|GOTO|IF|END)\s*(.*))") ;
const std::regex varCheck(R"(([A-Z])\s*)") ;
const std::regex numCheck(R"((\-?\d+)\s*)") ;
const std::regex numLineCheck(R"((\d+)\s*)") ;
short checkPresenceVar(const std::string& str) ;
int commInput(const std::string& operand, const std::string& line) ;
int commPrint(const std::string& operand, const std::string& line) ;
int commGoTo(const std::string& operand, const std::string& line) ;
int commLet(const std::string& operand, const std::string& line) ;
int commEnd(const std::string& operand, const std::string& line) ;
int commIf(const std::string& operand, const std::string& line) ;
int main(int argc, char* argv[]) {
/* Проверки корректности аргументов */
if (argc != 3)
{
printf("\033[38;5;196mThe number of arguments does not match the condition!\033[0m \nThe translator launch command must look like: simpleBasic file.sb file.sa, where file.sb – name of the file that contains the program in Simple Basic, file.sa - translation result\n") ;
return -1 ;
}
if(!regex_match(argv[1], std::regex(R"(\w+\.sb)"))){
printf("\033[38;5;196mThe extension of the first argument, \"%s\", does not match the conditions\033[0m \nTThe translator launch command must look like: simpleBasic file.sb file.sa, where file.sb – name of the file that contains the program in Simple Basic, file.sa - translation result\n", argv[1]) ;
return -1 ;
}
if(!regex_match(argv[2], std::regex(R"(\w+\.sa)"))){
printf("\033[38;5;196mThe extension of the second argument, \"%s\", does not match the conditions\033[0m \nThe translator launch command must look like: simpleBasic file.sb file.sa, where file.sb – name of the file that contains the program in Simple Basic, file.sa - translation result\n", argv[1]) ;
return -1 ;
}
/* Открытие входного файла */
std::ifstream inFile(argv[1]) ;
if(!inFile.is_open()){
printf("\033[38;5;196mUnable to open the \"%s\" file. \033[0m \nCheck whether the file is in the directory, as well as access rights.\n", argv[1]) ;
return -1 ;
}
std::string line ;
short int prevLine = -1 ;
bool checkMainEnd = false ;
std::cmatch parsedLine ;
/* Построчное считывание */
while (getline(inFile, line)){
if (regex_match(line, std::regex(R"(\s*)")))
continue ;
if (!regex_match(line.c_str(), parsedLine, basicCheckLine)) {
printf("\033[38;5;196mInvalid line\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
short tmp = stoi(parsedLine[1]);
if (prevLine <= tmp){
printf("\033[38;5;196mInvalid line | The line number must increase and must not be repeated.\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
prevLine = tmp ;
std::string command = parsedLine[2] ;
if (command == "REM"){
continue ;
}
else if(command == "INPUT"){
std::string operand = parsedLine[3] ;
startCommands[parsedLine[1]] = currCellComm ;
if (commInput(operand, line))
return -1 ;
}
else if(command == "PRINT"){
std::string operand = parsedLine[3] ;
startCommands[parsedLine[1]] = currCellComm ;
if (commPrint(operand, line))
return -1 ;
}
else if(command == "GOTO"){
std::string operand = parsedLine[3] ;
startCommands[parsedLine[1]] = currCellComm ;
if (commGoTo(operand, line))
return -1 ;
}
else if(command == "LET"){
std::string operand = parsedLine[3] ;
startCommands[parsedLine[1]] = currCellComm ;
if (commLet(operand, line))
return -1 ;
}
else if(command == "END"){
std::string operand = parsedLine[3] ;
startCommands[parsedLine[1]] = currCellComm ;
if (commEnd(operand, line))
return -1 ;
checkMainEnd = true ;
break;
}
else if(command == "IF"){
std::string operand = parsedLine[3] ;
startCommands[parsedLine[1]] = currCellComm ;
if (commIf(operand, line))
return -1 ;
}
if (currCellComm > currCellVar){
printf("\033[38;5;196mError ! The program didn't have enough memory!\033[0m\n") ;
return -1 ;
}
}
inFile.close();
if (!checkMainEnd){
printf("\033[38;5;196mError! The main end is not found!\033[0m\n") ;
return -1 ;
}
/* Вторичный проход по goto */
for (auto &i : queueGoTo){
if(startCommands.find(std::to_string(commands[i].operand)) == startCommands.end()){
printf("\033[38;5;196mInvalid operand for \"goto\". | GoTo refers to a nonexistent string\033[0m\n") ;
return -1 ;
}
else{
short addressOperand = startCommands.find(std::to_string(commands[i].operand))->second ;
commands[i].operand = addressOperand ;
}
}
/* Запись в файл */
std::ofstream outFile(argv[2]) ;
if(!outFile.is_open()){
printf("\033[38;5;196mUnable to open the \"%s\" file.\033[0m\n\tCheck your access rights.\n", argv[2]) ;
return -1 ;
}
// Запись команд
for (auto &i: commands)
outFile << std::setfill('0') << std::setw(2) << i.cell << " " << i.command << " " << std::setfill('0') << std::setw(2) << i.operand << std::endl ;
// Запись переменных
for (int i = variables.size() - 1 ; i >=0 ; i--)
if (regex_match(variables[i].title, varCheck))
outFile << std::setfill('0') << std::setw(2) << variables[i].address << " " << "=" << " " << "0" << std::endl ;
else{
outFile << std::setfill('0') << std::setw(2) << variables[i].address << " = " ;
outFile << std::hex << std::uppercase << stoi(variables[i].title) << std::dec << std::endl ;
}
outFile.close() ;
return 0 ;
}
short checkPresenceVar(const std::string& str){
for (short i = 0 ; i < variables.size() ; i++){
if (variables[i].title == str)
return i ;
}
variables.emplace_back(str, currCellVar--) ;
return variables.size() - 1 ;
}
int commInput(const std::string& operand, const std::string& line){
std::cmatch oper ;
if (!regex_match(operand.c_str(), oper, varCheck)){
printf("\033[38;5;196mInvalid line | Invalid variable for \"input\"\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
short addressOperand = checkPresenceVar(oper[1]) ;
commands.emplace_back(commandSA(currCellComm++, "READ ", variables[addressOperand].address)) ;
return 0 ;
}
int commPrint(const std::string& operand, const std::string& line){
std::cmatch oper ;
if (!regex_match(operand.c_str(), oper, varCheck) && !regex_match(operand.c_str(), oper, numCheck)){
printf("\033[38;5;196mInvalid line | Invalid operand for \"print\"\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
if(regex_match(operand, numCheck)){
short temp = stoi(operand) ;
if (temp < -0x2000 || temp >0x1FFF){
printf("\033[38;5;196mInvalid line | The valid range for the value of the number from -0x2000 to 0x1FFF inclusive\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
}
short addressOperand = checkPresenceVar(oper[1]) ;
commands.emplace_back(commandSA(currCellComm++, "WRITE ", variables[addressOperand].address)) ;
return 0 ;
}
int commGoTo(const std::string& operand, const std::string& line){
if (!regex_match(operand, numLineCheck)){
printf("\033[38;5;196mInvalid line | Invalid operand for \"goto\"\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
if(startCommands.find(operand) == startCommands.end()){
commands.emplace_back(commandSA(currCellComm++, "JUMP ", stoi(operand))) ;
queueGoTo.emplace_back(commands.size() - 1) ;
}
else{
short addressOperand = startCommands.find(operand)->second ;
commands.emplace_back(commandSA(currCellComm++, "JUMP ", addressOperand)) ;
}
return 0 ;
}
int commLet(const std::string& operand, const std::string& line){
const std::regex letOneParamCheck(R"(([A-Z])\s*=\s*([A-Z]|-?\d+)\s*)") ;
const std::regex letTwoParamCheck(R"(([A-Z])\s*=\s*([A-Z]|-?\d+)\s*([\+\-\*\/])\s*([A-Z]|-?\d+)\s*)") ;
std::cmatch letLine ;
if (!regex_match(operand.c_str(), letLine, letOneParamCheck) && !regex_match(operand.c_str(), letLine, letTwoParamCheck)){
printf("\033[38;5;196mInvalid line | Invalid operand for \"let\"\033[0m \n\"%s\"\n", line.c_str()) ;
return -1 ;
}
if(regex_match(operand, letOneParamCheck)){
std::string var = letLine[1] ;
std::string value = letLine[2] ;
if(regex_match(value, numCheck)){
short temp = stoi(value) ;
if (temp < -0x2000 || temp >0x1FFF){
printf("\033[38;5;196mInvalid line | The valid range for the value of the number from -0x2000 to 0x1FFF inclusive\033[0m \n\"%s\"\n", line.c_str()) ;
return -1 ;
}
}
short valueAddress = checkPresenceVar(value) ;
commands.emplace_back(commandSA(currCellComm++, "LOAD ", variables[valueAddress].address)) ;
short varAddress = checkPresenceVar(var) ;
commands.emplace_back(commandSA(currCellComm++, "STORE ", variables[varAddress].address)) ;
}
else{
std::string var = letLine[1] ;
std::string value1 = letLine[2] ;
std::string sign = letLine[3] ;
std::string value2 = letLine[4] ;
/////////////////////////////////////// value1
if(regex_match(value1, numCheck)){
short temp = stoi(value1) ;
if (temp < -0x2000 || temp >0x1FFF){
printf("\033[38;5;196mInvalid line | The valid range for the value of the number from -0x2000 to 0x1FFF inclusive\033[0m \n\"%s\"\n", line.c_str()) ;
return -1 ;
}
}
short valueAddress1 = (short)checkPresenceVar(value1) ;
commands.emplace_back(commandSA(currCellComm++, "LOAD ", variables[valueAddress1].address)) ;
/////////////////////////////////////// value2
if(regex_match(value2, numCheck)){
short temp = stoi(value2) ;
if (temp < -0x2000 || temp >0x1FFF){
printf("\033[38;5;196mInvalid line | The valid range for the value of the number from -0x2000 to 0x1FFF inclusive\033[0m \n\"%s\"\n", line.c_str()) ;
return -1 ;
}
}
short valueAddress2 = (short)checkPresenceVar(value2) ;
/////////////////////////////////////// action
if(sign == "+")
commands.emplace_back(commandSA(currCellComm++, "ADD ", variables[valueAddress2].address)) ;
else if(sign == "-")
commands.emplace_back(commandSA(currCellComm++, "SUB ", variables[valueAddress2].address)) ;
else if(sign == "*")
commands.emplace_back(commandSA(currCellComm++, "MUL ", variables[valueAddress2].address)) ;
else if (sign == "/")
commands.emplace_back(commandSA(currCellComm++, "DIVIDE", variables[valueAddress2].address)) ;
//////////////////////////////////////// var
short varAddress = checkPresenceVar(var) ;
commands.emplace_back(commandSA(currCellComm++, "STORE ", variables[varAddress].address)) ;
}
return 0 ;
}
int commEnd(const std::string& operand, const std::string& line){
if(!regex_match(operand, std::regex(R"(\s*)"))){
printf("\033[38;5;196mInvalid line | There should be nothing after \"end\"\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
commands.emplace_back(commandSA(currCellComm++, "HALT ", 0)) ;
return 0 ;
}
int commIf(const std::string& operand, const std::string& line){
std::cmatch ifLine ;
const std::regex ifConditionCheck(R"(([A-Z]|-?\d+)\s*(=|<|>)\s*([A-Z]|-?\d+)\s+(INPUT|PRINT|LET|GOTO|END)\s*(.*))") ;
if(!regex_match(operand.c_str(), ifLine, ifConditionCheck)){
printf("\033[38;5;196mInvalid line | There should be nothing after \"if\"\033[0m\n\"%s\"\n", line.c_str()) ;
return -1 ;
}
std::string value1 = ifLine[1] ;
std::string condition = ifLine[2] ;
std::string value2 = ifLine[3] ;
std::string comm = ifLine[4] ;
std::string op = ifLine[5] ;
short addressvalue1 = checkPresenceVar(value1) ;
short addressvalue2 = checkPresenceVar(value2) ;
if (condition == "="){
commands.emplace_back(commandSA(currCellComm++, "LOAD ", variables[addressvalue1].address)) ;
commands.emplace_back(commandSA(currCellComm++, "SUB ", variables[addressvalue2].address)) ;
commands.emplace_back(commandSA(currCellComm++, "JZ ", currCellComm + 2)) ;
}
else{
if (condition == "<"){
commands.emplace_back(commandSA(currCellComm++, "LOAD ", variables[addressvalue1].address)) ;
commands.emplace_back(commandSA(currCellComm++, "SUB ", variables[addressvalue2].address)) ;
}
else{
commands.emplace_back(commandSA(currCellComm++, "LOAD ", variables[addressvalue2].address)) ;
commands.emplace_back(commandSA(currCellComm++, "SUB ", variables[addressvalue1].address)) ;
}
commands.emplace_back(commandSA(currCellComm++, "JNEG ", currCellComm + 2)) ;
}
commands.emplace_back(commandSA(currCellComm++, "JUMP ", -1)) ;
short temp = commands.size() - 1 ;
if (comm == "INPUT"){
if (commInput(op, line))
return -1 ;
}
else if (comm == "PRINT"){
if (commPrint(op, line))
return -1 ;
}
else if (comm == "LET"){
if (commLet(op, line))
return -1 ;
}
else if (comm == "GOTO"){
if (commGoTo(op, line))
return -1 ;
}
else if (comm == "END"){
if (commEnd(op, line))
return -1 ;
}
commands[temp].operand = currCellComm ;
return 0 ;
}
Новосибирск 2019-20 уч. год