2

So i've been trying to tidy my code a lot and was wondering if there was a way to declare my map's and also populate them within other files, or even other functions.

Here is my code thus far: (this uses an inbuilt tokeniser which i dont have the code for, but basically the maps store the binary for the input machine-code, and will output a-instructions and c-instructions depending on the input)

CODE:

// convert Hack assembly into binary

#include <iostream>
#include "tokens.h"
#include <bitset>
#include <cctype>
#include <string>
#include <map>

using namespace std ;

bool isNumber(string s){
    for (size_t n = 0; n < s.length(); n++){
        if (!(isdigit(s[n]))){
            return false;
        } else {
            return true;
        }
    }    
}

int main(){
// Declaring lookup tables (want to make this global [seperate file])
std::map<std::string, std::string> compTable;
std::map<std::string, std::string> destTable;
std::map<std::string, std::string> jumpTable;

// Inserting table data (want to make this global [seperate file])
// Jump Table Data
    jumpTable.insert(pair<string, string> ("NULL", "000"));
    jumpTable.insert(pair<string, string> ("JGT", "001"));
    jumpTable.insert(pair<string, string> ("JEQ", "010"));
    jumpTable.insert(pair<string, string> ("JGE", "011"));
    jumpTable.insert(pair<string, string> ("JLT", "100"));
    jumpTable.insert(pair<string, string> ("JNE", "101"));
    jumpTable.insert(pair<string, string> ("JLE", "110"));
    jumpTable.insert(pair<string, string> ("JMP", "111"));

// Dest Table Data
    destTable.insert(pair<string, string> ("NULL", "000"));
    destTable.insert(pair<string, string> ("M", "001"));
    destTable.insert(pair<string, string> ("D", "010"));
    destTable.insert(pair<string, string> ("MD", "011"));
    destTable.insert(pair<string, string> ("A", "100"));
    destTable.insert(pair<string, string> ("AM", "101"));
    destTable.insert(pair<string, string> ("AD", "110"));
    destTable.insert(pair<string, string> ("AMD", "111"));

// Comp Table Data
    // When a=1
    compTable.insert(pair<string, string> ("0", "1110101010"));
    compTable.insert(pair<string, string> ("1", "1110111111"));
    compTable.insert(pair<string, string> ("-1", "1110111010"));
    compTable.insert(pair<string, string> ("D", "1110001100"));
    compTable.insert(pair<string, string> ("A", "1110110000"));
    compTable.insert(pair<string, string> ("!D", "1110001101"));
    compTable.insert(pair<string, string> ("!A", "1110110001"));
    compTable.insert(pair<string, string> ("-D", "1110001111"));
    compTable.insert(pair<string, string> ("-A", "1110110011"));
    compTable.insert(pair<string, string> ("D+1", "1110011111"));
    compTable.insert(pair<string, string> ("A+1", "1110110111"));
    compTable.insert(pair<string, string> ("D-1", "1110001110"));
    compTable.insert(pair<string, string> ("A-1", "1110110010"));
    compTable.insert(pair<string, string> ("D+A", "1110000010"));
    compTable.insert(pair<string, string> ("D-A", "1110010011"));
    compTable.insert(pair<string, string> ("A-D", "1110000111"));
    compTable.insert(pair<string, string> ("D&A", "1110000000"));
    compTable.insert(pair<string, string> ("D|A", "1110010101"));
    // when a=0
    compTable.insert(pair<string, string> ("M", "1111110000"));
    compTable.insert(pair<string, string> ("!M", "1111110001"));
    compTable.insert(pair<string, string> ("-M", "1111110011"));
    compTable.insert(pair<string, string> ("M+1", "1111110111"));
    compTable.insert(pair<string, string> ("M-1", "1111110010"));
    compTable.insert(pair<string, string> ("D+M", "1111000010"));
    compTable.insert(pair<string, string> ("D-M", "1111010011"));
    compTable.insert(pair<string, string> ("M-D", "1111000111"));
    compTable.insert(pair<string, string> ("D&M", "1111000000"));
    compTable.insert(pair<string, string> ("D|M", "1111010101"));

// Declaring Variables
    string temp;
    string tempValue;
    int skipLine = 0;
    int tokenCounter = 0;

// create a new assembler tokeniser then read the first token
tokens *tokeniser = new tokens(getchar) ;
std::string token = tokeniser->next_token() ;

while ( token != "?" )          // stop at EOF, "?" denotes EOF
{
    if(tokenCounter > 0) {
        cout << endl;
    }
    if(skipLine == 1) {
        cout << endl;
    }
    skipLine = 0;
    if(token == "address"){
        string adrsStr = tokeniser->token_value();
        if(isNumber(adrsStr)==true){
            int adrs = stoi(adrsStr);
            cout << bitset<16>(adrs);
        }
    }
    if(token == "comp" || token == "dest" || token == "dest-comp?" || token == "null"){
        tempValue = tokeniser->token_value();
        temp = token;
        token = tokeniser->next_token() ;
        if(token == "equals"){
            token = tokeniser->next_token() ;
            if(temp == "null") {
                    std::cout << compTable.find(tokeniser->token_value())->second;
                    std::cout << destTable.find("NULL")->second;
                    std::cout << jumpTable.find("NULL")->second;
            }else if(temp == "dest" || temp == "dest-comp?"){
                if (token == "comp" || token == "dest-comp?"){
                    std::cout << compTable.find(tokeniser->token_value())->second;
                    std::cout << destTable.find(tempValue)->second;
                    std::cout << jumpTable.find("NULL")->second;
                }
            }
        }else if(token == "semi") {
            std::cout << compTable.find(tempValue)->second;
            std::cout << destTable.find("NULL")->second;    
            token = tokeniser->next_token() ;
            if (token == "jump"){
                std::cout << jumpTable.find(tokeniser->token_value())->second;
            } else if(token == "null") {
                std::cout <<jumpTable.find("NULL")->second;
            }
        }else if (token != "equal" || token != "semi"){
            std::cout << compTable.find(tempValue)->second;
            std::cout << destTable.find("NULL")->second;  
            std::cout << jumpTable.find("NULL")->second;
            if (token!= "semi" || token!="equals"){
                skipLine=1;
                continue;
            }
        }
    }
    tokenCounter++;
    token = tokeniser->next_token() ;


}
cout << endl;
/*cout << jumpTable.find("NULL")->second << endl;
cout << compTable.find("A")->second << endl;
cout << destTable.find("A")->second << endl;*/
return 0 ;
}

The preferred format for the map would contain a create() function which will be used to declare the maps externally and an insert() function to populate the map

Is this possible?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Swallows
  • 199
  • 1
  • 1
  • 11

3 Answers3

2

You can do something like:

std::map<std::string, std::string> make_jump_table()
{
    return {
        {"NULL", "000"},
        {"JGT", "001"},
        {"JEQ", "010"},
        {"JGE", "011"},
        {"JLT", "100"},
        {"JNE", "101"},
        {"JLE", "110"},
        {"JMP", "111"}
    };
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
1

How about doing it the old fashioned way? By using extern and providing a function that main() should call, that performs all the insertions.

I wrote an example, based on this, based on which you could write your code (that I am not able to do so because I don't have the token header of yours).

main.cpp

#include <iostream>
#include <map>
#include "myMap.h"

std::map<char,int> mymap;

int main ()
{
  myMapInsertions(mymap);

  std::cout << "mymap contains:\n";
  for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

myMap.h

#ifndef MYMAP_H_
#define MYMAP_H_

#include <map>

extern std::map<char,int> mymap;

void myMapInsertions(std::map<char,int>& mymap);

#endif // MYMAP_H_

myMap.cpp

#include "myMap.h"

void myMapInsertions(std::map<char,int>& mymap)
{
    mymap.insert ( std::pair<char,int>('a',100) );
    mymap.insert ( std::pair<char,int>('z',200) );
}

Compile like this:

g++ -Wall main.cpp myMap.cpp -o main


Read about the extern keyword here: When to use extern in C++?

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

Another way to check if a string is number in C++11:

bool isNumber(const string& str) {
    int res = std::accumulate(str.begin(), str.end(), 0, [](int r, char c){return r += isdigit(c);});

    return (res == str.size());
}
cartman
  • 732
  • 2
  • 8
  • 20