In my assembler I've mapped all mnemonics to their word representation (same for registers):
Code:
#define ADDENTRY(m, c, w) m.insert(entry(c, w))
void CAssembler::Initialise()
{
typedef pair<char*, word> entry;
ADDENTRY(opcodes, "nop", 0x0000);
ADDENTRY(opcodes, "end", 0xFFFF);
ADDENTRY(opcodes, "push", 0x0001);
ADDENTRY(opcodes, "pop", 0x0002);
ADDENTRY(opcodes, "mov", 0x0003);
ADDENTRY(opcodes, "inc", 0x0004);
ADDENTRY(opcodes, "dec", 0x0005);
ADDENTRY(opcodes, "jmp", 0x0006);
ADDENTRY(opcodes, "cmp", 0x0007);
ADDENTRY(opcodes, "je", 0x0008);
ADDENTRY(opcodes, "jne", 0x0009);
ADDENTRY(opcodes, "jz", 0x000A);
ADDENTRY(opcodes, "jnz", 0x000B);
ADDENTRY(opcodes, "jgt", 0x000C);
ADDENTRY(opcodes, "jlt", 0x000D);
ADDENTRY(opcodes, "ld", 0x000E);
ADDENTRY(registers, "pc", 0xF000);
ADDENTRY(registers, "sp", 0xF001);
ADDENTRY(registers, "r0", 0xF002);
ADDENTRY(registers, "r1", 0xF003);
}
I've got this function which is supposed to return the word value from the map based on the token - it chooses which map to get it from:
Code:
word CAssembler::TranslateToken(char* token)
{
if (strcmp(token, "nop") == 0)
return opcodes[token];
else if (strcmp(token, "end") == 0)
return opcodes[token];
else if (strcmp(token, "push") == 0)
return opcodes[token];
else if (strcmp(token, "pop") == 0)
return opcodes[token];
else if (strcmp(token, "mov") == 0)
return opcodes[token];
else if (strcmp(token, "inc") == 0)
return opcodes[token];
else if (strcmp(token, "dec") == 0)
return opcodes[token];
else if (strcmp(token, "jmp") == 0)
return opcodes[token];
else if (strcmp(token, "cmp") == 0)
return opcodes[token];
else if (strcmp(token, "je") == 0)
return opcodes[token];
else if (strcmp(token, "jne") == 0)
return opcodes[token];
else if (strcmp(token, "jz") == 0)
return opcodes[token];
else if (strcmp(token, "jnz") == 0)
return opcodes[token];
else if (strcmp(token, "jgt") == 0)
return opcodes[token];
else if (strcmp(token, "jlt") == 0)
return opcodes[token];
else if (strcmp(token, "ld") == 0)
return opcodes[token];
else if (strcmp(token, "pc") == 0)
return registers[token];
else if (strcmp(token, "sp") == 0)
return registers[token];
else if (strcmp(token, "r0") == 0)
return registers[token];
else if (strcmp(token, "r1") == 0)
return registers[token];
else
throw ASInvalidToken();
}
But it doesn't return the word. Here's the code which uses it:
Code:
void CAssembler::Assemble(const char* fileName, const char* outFileName)
{
FILE* fin = 0, *fout = 0;
char* token = 0;
const char* delim = " ,\n";
char* line = new char[260];
word translated = 0;
fin = fopen(fileName, "r");
if (!fin) throw ASFileError();
while (fgets(line, 260, fin) != 0) {
token = strtok(line, delim);
while (token != 0) {
cout << token << "\t";
if (IsDigit(token))
translated = atoi(token);
else
translated = TranslateToken(token);
cout << translated << endl;
token = strtok(0, delim);
}
}
fclose(fin);
delete[] line;
}
Input:
Code:
ld r0, 10
ld r1, 20
push r1
pop r0
end
Output:
Code:
ld 0
r0 0
10 10
ld 0
r1 0
20 20
push 0
r1 0
pop 0
r0 0
end 0
Press any key to continue
So the literals get properly mapped to their, well, nothing because they're literal, but the opcodes & operands don't. I don't know, maybe it's not a map problem, just a logic problem.
Be gentle, it's late. (to me, I get up at the crack of dawn)
EDIT1:
Just ran this on each token as it's found:
Code:
for (unsigned i = 0; i < strlen(token); i++)
cout << (int) *(token + i) << " ";
Just to make sure nothing strange is causing strcmp() to fail.
EDIT2: I just realised how pointless EDIT1 was since if strcmp() returns 0 I throw en exception. I should design my projects on paper.