Files
assm-test/src/main.c
T

256 lines
7.0 KiB
C

#include <bits/types/FILE.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sysexits.h>
#include "../includes/list.h"
#include "../includes/futil.h"
#include "../includes/scanner.h"
#include "../includes/parser.h"
List* LIST;
SymbolTable* Symbols;
unsigned char mem[128] = {0};
void print(void);
void assemble(void);
int main(int argc, char* args[]) {
if (argc == 1) {
printf("Usage: assm <file1.asm>\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);
IRState* state = ParseTokens(LIST);
Symbols = state->SymbolsTable;
free(source_code);
assemble();
printf("\nBytes:\n");
for(int 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;
}
unsigned short GetValueFromToken(Token* token) {
if (token->Class & IdentifierClass) {
Symbol* symbol;
if (TryGetSymbol(token->Lemexe, Symbols, &symbol)) {
printf("Returning %d for address of %s.\n", symbol->Address, symbol->Name);
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]));
PC2 += 2;
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]));
PC2 += 2;
break;
case COPYB:
CurrentIndex++;
WriteByte(current->Value.Mnemonic | ((Token*) LIST->content[CurrentIndex])->Value.Register);
CurrentIndex++;
WriteWord((unsigned char)GetValueFromToken(LIST->content[CurrentIndex]));
PC2 += 1;
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]));
PC2 += 2;
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]));
PC2 += 2;
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]));
PC2 += 2;
break;
case NOP:
case RET:
WriteByte(current->Value.Mnemonic);
break;
case CALL:
WriteByte(current->Value.Mnemonic);
CurrentIndex++;
WriteWord(GetValueFromToken(LIST->content[CurrentIndex]));
PC2 += 2;
default:
break;
}
CurrentIndex++;
}
}