#include #include #include #include #include #include "../includes/token.h" #include "../includes/futil.h" #include "../includes/scanner.h" #include "../includes/parser.h" const char* MagicStartName = "__start"; TokenList* LIST; SymbolTable* Symbols = NULL; unsigned char mem[128] = {0}; void print(void); void assemble(void); int main(int argc, char* args[]) { if (argc == 1) { printf("Usage: assm \n"); return EX_USAGE; } atexit(print); char* source_code; size_t bytes_read; if (!ReadAllString(args[1], &source_code, &bytes_read)) return EX_IOERR; LIST = GenerateTokenList(source_code); ParseTokens(LIST, &Symbols); free(source_code); assemble(); printf("\nBytes:\n"); for(unsigned long i = 0; i < sizeof(mem); i++) { if (i != 0 && i % 8 == 0) printf("\n"); printf("%02X ", mem[i] & 0xFF); } printf("\n"); } void print(void) { char mnemonic[12]; printf("printing tokens...\n"); for(int i = 0; i < LIST->size; i++) { Token* t = (Token*) LIST->content[i]; if (t->EndOfFile) { printf("EOF\n"); break; } if (t->Class == PunctuationClass){ if(t->Value.Punctuation == NewLine) { printf("<%d>\n", t->LineNumber); continue; } printf("[P]%c", t->Value.Punctuation); continue; } if (t->Class == LabelClass) { printf("[L]%s*", t->Lemexe); continue; } if (t->Class == IdentifierClass) { printf("[I]%s ", t->Lemexe); continue; } if (t->Class == RegisterClass) { printf("[R]%d", t->Value.Register); continue; } if (t->Class == NumberClass) { printf("[N]%d ", t->Value.Number); continue; } if (t->Class == MnemonicClass) { GetMnemonicText(t->Value.Mnemonic, mnemonic); printf("[M]%s ", mnemonic); continue; } if (t->Class == DirectiveClass) { printf("[D]%d ", t->Value.Directive); } if (t->Class == CharacterClass) { printf("[C]'%s'", t->Lemexe); } } } int CurrentIndex = 0; int PC2 = 0; void WriteByte(unsigned char byte) { mem[PC2] = byte; PC2++; } void WriteWord(unsigned short word) { mem[PC2] = (word >> 8) & 0xFF; mem[PC2 + 1] = word & 0xFF; PC2 += 2; } unsigned short GetValueFromToken(Token* token) { if (token->Class & IdentifierClass) { Symbol* symbol; if (TryGetSymbol(token->Lemexe, Symbols, &symbol)) { return symbol->Address; } else { fprintf(stderr, "Failed to find symbol %s while assembling.\n", token->Lemexe); exit(1); } } else if (token->Class == NumberClass) return token->Value.Number; fprintf(stderr, "Failed to find token '%d' while assmbling.\n", token->Class); exit(1); } int IsAtEnd(void){ return CurrentIndex >= LIST->size; } void assemble() { while(!IsAtEnd()) { Token* current = LIST->content[CurrentIndex]; switch(current->Value.Mnemonic) { case COPYA: case COPYAB: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteWord(GetValueFromToken(LIST->content[CurrentIndex])); break; case COPYRA: case COPYRAB: case COPYRARA: case COPYRARAB: case COPY: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteByte(((Token*) LIST->content[CurrentIndex])->Value.Register); break; case COPYI: //TODO: should explicitly get number from value I feel CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteWord(GetValueFromToken(LIST->content[CurrentIndex])); break; case COPYB: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteByte((unsigned char)GetValueFromToken(LIST->content[CurrentIndex])); break; case CMP: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteByte(((Token*) LIST->content[CurrentIndex])->Value.Register); break; case CMPI: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteWord(GetValueFromToken(LIST->content[CurrentIndex])); break; case ADD: case SUB: case AND: case OR: case XOR: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteByte(((Token*) LIST->content[CurrentIndex])->Value.Register); break; case SHL: case SHR: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); CurrentIndex++; WriteWord(GetValueFromToken(LIST->content[CurrentIndex])); break; case INC: case DEC: case PUSH: case POP: case JMPI: CurrentIndex++; WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register); break; case JMP: case JZ: case JG: case JL: WriteByte(current->Value.Mnemonic); CurrentIndex++; WriteWord(GetValueFromToken(LIST->content[CurrentIndex])); break; case NOP: case RET: WriteByte(current->Value.Mnemonic); break; case CALL: WriteByte(current->Value.Mnemonic); CurrentIndex++; WriteWord(GetValueFromToken(LIST->content[CurrentIndex])); default: break; } CurrentIndex++; } }