This feels like a trainwreck but eh. Changed the way the opcodes are managed. Hopefully this is the right direction when I add support for multiple ASM files.

This commit is contained in:
2022-09-01 18:46:59 +00:00
parent 13f8ff194b
commit 7004fff659
7 changed files with 230 additions and 129 deletions
+2 -1
View File
@@ -6,6 +6,7 @@
#define OPCODECOUNT 13 #define OPCODECOUNT 13
#define REGISTERCOUNT 8 #define REGISTERCOUNT 8
//const unsigned char COPYADDRESSMASK = 0x80;
typedef struct { typedef struct {
char* lexeme; char* lexeme;
@@ -25,6 +26,6 @@ extern Register registers[REGISTERCOUNT];
int IsOpcode(const char*, TokenType*); int IsOpcode(const char*, TokenType*);
int IsRegister(const char*, TokenType*); int IsRegister(const char*, TokenType*);
const Instruction* GetOpcodeDetails(TokenType); const Instruction* GetOpcodeDetails(TokenType);
unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType); unsigned char GetInstructionMask(TokenType type);
#endif #endif
+30 -1
View File
@@ -1,6 +1,7 @@
#ifndef PARSER_H #ifndef PARSER_H
#define PARSER_H #define PARSER_H
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "list.h" #include "list.h"
@@ -9,6 +10,34 @@
#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF #define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF
unsigned char* ParseTokens(List*); typedef struct {
Token* token;
//unsigned char terminatingByte;
int address;
int resolved;
} Symbol;
typedef struct {
TokenType Mnemonic;
TokenClass ParameterOneType;
TokenClass ParameterTwoType;
union {
uint16_t Constant;
Symbol* Address;
} ParameterOne;
union {
uint16_t Constant;
Symbol* Address;
} ParameterTwo;
} IROpcode;
typedef struct {
List* Opcodes;
List* SymbolsTable;
} IRState;
IRState* ParseTokens(List*);
#endif #endif
+1 -1
View File
@@ -26,7 +26,7 @@ typedef enum {
LineEnd, LineEnd,
//Keywords //Keywords
DB, ORG, DB, ORG,
//Opcodes //Mnemonics
COPY, ADD, SUB, JZ, INT, YLD, RET, COPY, ADD, SUB, JZ, INT, YLD, RET,
CMP, NOP, JMP, CALL, IN, OUT, CMP, NOP, JMP, CALL, IN, OUT,
//Registers //Registers
+3 -3
View File
@@ -2,9 +2,9 @@
.db msg "Hello, world!", 0 .db msg "Hello, world!", 0
.db more_stuff "AA", 0 .db more_stuff "AA", 0
copy r7, msg ; // copy r7, msg ; //
cmp r8, msg ;1000 1111 ;cmp r8, msg ;1000 1111
add r4, 0x42 ;add r4, 0x42
sub r1, r8 ;sub r1, r8
int 20 int 20
jz 45 jz 45
jmp msg jmp msg
+7 -4
View File
@@ -36,14 +36,17 @@ int main(int argc, char* args[]) {
// if (t->type == LABEL) printf("* "); // if (t->type == LABEL) printf("* ");
// } // }
unsigned char* image = ParseTokens(list); IRState* image = ParseTokens(list);
//Disassemble(image); //Disassemble(image);
for(int i = 0; i < image->Opcodes->size; i++) {
printf("%d\n", ((IROpcode*) image->Opcodes->content[i])->Mnemonic);
}
FILE* program = fopen("program.bin", "w+b"); //FILE* program = fopen("program.bin", "w+b");
fwrite(image, 1, image[2] + image[3], program); //fwrite(image, 1, image[2] + image[3], program);
fclose(program); //fclose(program);
free(source_code); free(source_code);
} }
+2 -4
View File
@@ -18,12 +18,10 @@ Instruction instructions[OPCODECOUNT] = {
{ "call", CALL, Address, None} { "call", CALL, Address, None}
}; };
unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) { unsigned char GetInstructionMask(TokenType type) {
switch (type) { switch (type) {
case COPY: case COPY:
if (parameterOneType & Reg) return 0x20; //0b00100000; return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address
return 0xA0;//0b10100000;
case ADD: case ADD:
return 0x40;//0b01000000; return 0x40;//0b01000000;
case SUB: case SUB:
+184 -114
View File
@@ -4,24 +4,20 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
typedef struct {
Token* token;
int address;
} Symbol;
struct intr { struct intr {
TokenType struction; TokenType struction;
unsigned int parameter1; unsigned int parameter1;
unsigned int parameter2; unsigned int parameter2;
}; };
Symbol* CreateSymbol(Token* token, int address); Symbol* CreateSymbol(Token* token, int address, int resolved);
const List* TokensList; const List* TokensList;
int CurrentToken = 0; int CurrentToken = 0;
//int HeapStart = 4; // zero indexed, used for declared variables. //int HeapStart = 4; // zero indexed, used for declared variables.
//int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header) //int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header)
void AddSymbol(Token*, int); IROpcode* CreateIROpcode(TokenType mnemonic);
Symbol* AddSymbol(Token* token, int address, int resolved);
void PrintSymbols(void); void PrintSymbols(void);
void HandleOperation(void); void HandleOperation(void);
void HandleAssemblerDirective(void); void HandleAssemblerDirective(void);
@@ -30,22 +26,24 @@ Token* PeekToken(void);
int ParserAtEnd(void); int ParserAtEnd(void);
int Expect(int, ...); int Expect(int, ...);
int ExpectTokenClass(int, ...); int ExpectTokenClass(int, ...);
const Symbol* GetSymbol(char*); Symbol* GetSymbol(char*);
List* SymbolsTable; //List* SymbolsTable;
unsigned int HeapTop = 4; unsigned int HeapTop = 4;
unsigned int ProgramCounter = 0; unsigned int ProgramCounter = 0;
unsigned char Heap[HIGHMEMORY]; // unsigned char Heap[HIGHMEMORY];
unsigned char Memory[HIGHMEMORY]; // unsigned char Memory[HIGHMEMORY];
IRState MachineState;
unsigned char* ParseTokens(List* tokens) { IRState* ParseTokens(List* tokens) {
if (!tokens) return NULL; if (!tokens) return NULL;
memset(Memory, 0, sizeof(Memory)); // memset(Memory, 0, sizeof(Memory));
memset(Heap, 0, sizeof(Heap)); // memset(Heap, 0, sizeof(Heap));
TokensList = tokens; TokensList = tokens;
SymbolsTable = CreateList(); MachineState.SymbolsTable = CreateList();
MachineState.Opcodes = CreateList();
while(!ParserAtEnd()) { while(!ParserAtEnd()) {
Token* t = PeekToken(); Token* t = PeekToken();
@@ -60,7 +58,7 @@ unsigned char* ParseTokens(List* tokens) {
case Address: case Address:
if (t->type == LABEL) { if (t->type == LABEL) {
printf("%s: \n", t->lexeme); printf("%s: \n", t->lexeme);
AddSymbol(t, ProgramCounter); AddSymbol(t, ProgramCounter, 1);
} }
break; break;
default: default:
@@ -70,16 +68,16 @@ unsigned char* ParseTokens(List* tokens) {
AdvanceParser(); AdvanceParser();
} }
if (SymbolsTable->size > 0) PrintSymbols(); if (MachineState.SymbolsTable->size > 0) PrintSymbols();
DestroyList(SymbolsTable); //DestroyList(SymbolsTable);
memcpy(&Heap[HeapTop], Memory, ProgramCounter); //memcpy(&Heap[HeapTop], Memory, ProgramCounter);
int totalSize = HeapTop + ProgramCounter; int totalSize = HeapTop + ProgramCounter;
Heap[0] = 2 >> HeapTop & 0xFF; // Heap[0] = 2 >> HeapTop & 0xFF;
Heap[1] = HeapTop & 0xFF; // Heap[1] = HeapTop & 0xFF;
Heap[2] = 2 >> totalSize & 0xFF; // Heap[2] = 2 >> totalSize & 0xFF;
Heap[3] = totalSize & 0xFF; // Heap[3] = totalSize & 0xFF;
// for(int i = 0; i < 33; i++) { // for(int i = 0; i < 33; i++) {
// if (i != 0 && i % 3 == 0) printf("\n"); // if (i != 0 && i % 3 == 0) printf("\n");
@@ -89,7 +87,7 @@ unsigned char* ParseTokens(List* tokens) {
// printf("Program Counter: %d\n", ProgramCounter); // printf("Program Counter: %d\n", ProgramCounter);
// printf("Heap Top: %#06X\n", HeapTop); // printf("Heap Top: %#06X\n", HeapTop);
return Heap; return &MachineState;
} }
void HandleAssemblerDirective(void) { void HandleAssemblerDirective(void) {
@@ -104,7 +102,7 @@ void HandleAssemblerDirective(void) {
exit(1); exit(1);
} }
AddSymbol(identifier, HeapTop); Symbol* symbol = AddSymbol(identifier, HeapTop, 1);
identifier = PeekToken(); identifier = PeekToken();
@@ -112,10 +110,10 @@ void HandleAssemblerDirective(void) {
case STRING: case STRING:
//printf("[INFO] %s = '%s' (%#04X)\n", identifier->lexeme, identifier->lexeme, HeapTop); //printf("[INFO] %s = '%s' (%#04X)\n", identifier->lexeme, identifier->lexeme, HeapTop);
for(int i = 0; i < strlen(identifier->lexeme); i++) { // for(int i = 0; i < strlen(identifier->lexeme); i++) {
//Memory[ProgramCounter + i] = PeekToken()->lexeme[i]; // //Memory[ProgramCounter + i] = PeekToken()->lexeme[i];
Heap[HeapTop + i] = identifier->lexeme[i]; // Heap[HeapTop + i] = identifier->lexeme[i];
} // }
//ProgramCounter += strlen(PeekToken()->lexeme); //ProgramCounter += strlen(PeekToken()->lexeme);
HeapTop += strlen(identifier->lexeme); HeapTop += strlen(identifier->lexeme);
@@ -130,10 +128,11 @@ void HandleAssemblerDirective(void) {
exit(1); exit(1);
} }
else { else {
//Add the NULL byte. //Hideous...
//Memory[ProgramCounter] = '\0'; int oldLength = strlen(identifier->lexeme);
Heap[HeapTop] = '\0'; identifier->lexeme = realloc(identifier->lexeme, oldLength + 2);
//ProgramCounter++; identifier->value = identifier->lexeme;
identifier->lexeme[oldLength + 1] = '\0';//*PeekToken()->lexeme & 0x0F;
HeapTop++; HeapTop++;
return; return;
} }
@@ -147,18 +146,32 @@ void HandleAssemblerDirective(void) {
} }
} }
void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) { void HandleRegisterBasedOpcode(unsigned char mask) {
Memory[ProgramCounter] = mask; //Memory[ProgramCounter] = mask;
ProgramCounter++; ProgramCounter++;
const Token* token = PeekToken(); Token* token = PeekToken();
IROpcode* opcode = CreateIROpcode(token->type);
AdvanceParser();
token = PeekToken();
if (token->token_class == Reg) { if (token->token_class == Reg) {
Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; //Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07;
opcode->ParameterOneType = Reg;
AdvanceParser(); AdvanceParser();
} }
else if (token->token_class == Address && token->type == COPY) {
opcode->ParameterOneType = Address;
Symbol* symbol = GetSymbol(token->lexeme);
if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 0, 0);
else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved);
}
else { else {
fprintf(stderr, "[Error] Line %d: Expected register operand.\n", token->line); fprintf(stderr, "[Error] Line %d: Expected register operand.\n", token->line);
exit(1); exit(1);
@@ -167,39 +180,47 @@ void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) {
token = PeekToken(); token = PeekToken();
if (!Expect(1, COMMA)) { if (!Expect(1, COMMA)) {
fprintf(stderr, "[Error] Expected command one line %d.\n", token->line); fprintf(stderr, "[Error] Expected comma on line %d.\n", token->line);
exit(1); exit(1);
} }
token = PeekToken(); token = PeekToken();
if (token->type == IDENTIFIER || token->type == LABEL) { if (token->type == IDENTIFIER || token->type == LABEL) {
const Symbol* symbol = GetSymbol(token->lexeme); opcode->ParameterTwoType = Address;
Symbol* symbol = GetSymbol(token->lexeme);
if (!symbol) { // if (!symbol) {
fprintf(stderr, "[Error] Line %d: %s is undefined.\n", token->line, token->lexeme); // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", token->line, token->lexeme);
exit(1); // exit(1);
} // }
if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 0, 0);//CreateSymbol(token, 0, 0);
else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved);
Memory[ProgramCounter - 1] |= 0x10;//0b00010000; // Memory[ProgramCounter - 1] |= 0x10;//0b00010000;
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
Memory[ProgramCounter + 1] = symbol->address & 0xFF; // Memory[ProgramCounter + 1] = symbol->address & 0xFF;
AdvanceParser(); AdvanceParser();
} }
else if (token->type == NUMBER) { else if (token->type == NUMBER) {
Memory[ProgramCounter - 1] |= 0x08; //0b00001000; opcode->ParameterTwoType = Constant;
int* value = PeekToken()->value; opcode->ParameterTwo.Constant = *(int*)PeekToken()->value;
// Memory[ProgramCounter - 1] |= 0x08; //0b00001000;
Memory[ProgramCounter] = 2 >> *value & 0xFF; // int* value = PeekToken()->value;
Memory[ProgramCounter + 1] = *value & 0xFF;
// Memory[ProgramCounter] = 2 >> *value & 0xFF;
// Memory[ProgramCounter + 1] = *value & 0xFF;
AdvanceParser(); AdvanceParser();
} }
else if (token->token_class == Reg) { else if (token->token_class == Reg) {
Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07; opcode->ParameterTwoType = Reg;
opcode->ParameterTwo.Constant = (PeekToken()->type - R1) &0x07;
//Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07;
AdvanceParser(); AdvanceParser();
@@ -212,49 +233,64 @@ void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) {
} }
ProgramCounter += 2; ProgramCounter += 2;
AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes);
} }
void HandleOperation(void) { void HandleOperation(void) {
const Instruction* inst = GetOpcodeDetails(PeekToken()->type); Token* token = PeekToken();
//const Instruction* inst = GetOpcodeDetails(opcode->type);
const unsigned char registerBasedOpcodeMask = 0xE0; const unsigned char registerBasedOpcodeMask = 0xE0;
if (!inst) return; //if (!inst) return;
AdvanceParser(); // AdvanceParser();
unsigned char mask = GetInstructionMask(inst->op, inst->parameter_one); unsigned char mask = GetInstructionMask(token->type);
if (mask & registerBasedOpcodeMask) { if (mask & registerBasedOpcodeMask) {
HandleRegisterBasedOpcode(Memory[ProgramCounter], mask); HandleRegisterBasedOpcode(mask);
return; return;
} }
IROpcode* opcode = CreateIROpcode(token->type);
opcode->ParameterTwoType = None;
AdvanceParser();
switch (mask) { switch (mask) {
case 0: //NOP case 0: //NOP
Memory[ProgramCounter] = 0x00; //Memory[ProgramCounter] = 0x00;
opcode->ParameterOneType = None;
ProgramCounter++; ProgramCounter++;
return; return;
case 1: //JZ case 1: //JZ
Memory[ProgramCounter] = 0x01; //Memory[ProgramCounter] = 0x01;
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
const Symbol* symbol = GetSymbol(PeekToken()->lexeme); Symbol* symbol = GetSymbol(PeekToken()->lexeme);
opcode->ParameterOneType = Address;
if (!symbol) { if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0);
fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme); else opcode->ParameterOne.Address = symbol;
exit(1); // if (!symbol) {
} // fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme);
// exit(1);
// }
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
Memory[ProgramCounter + 1] = symbol->address & 0xFF; // Memory[ProgramCounter + 1] = symbol->address & 0xFF;
} }
else if (PeekToken()->type == NUMBER) { else if (PeekToken()->type == NUMBER) {
int* value = PeekToken()->value; opcode->ParameterOneType = Constant;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value;
// int* value = PeekToken()->value;
Memory[ProgramCounter] = 2 >> *value & 0xFF; // Memory[ProgramCounter] = 2 >> *value & 0xFF;
Memory[ProgramCounter + 1] = *value & 0xFF; // Memory[ProgramCounter + 1] = *value & 0xFF;
} }
else { else {
fprintf(stderr, "[Error] Line: %d: Expected address after jump if zero (JZ) instruction.\n", ((Token*) TokensList->content[CurrentToken - 1])->line); fprintf(stderr, "[Error] Line: %d: Expected address after jump if zero (JZ) instruction.\n", ((Token*) TokensList->content[CurrentToken - 1])->line);
@@ -265,15 +301,17 @@ void HandleOperation(void) {
return; return;
case 2: //INT case 2: //INT
Memory[ProgramCounter] = 0x02; //Memory[ProgramCounter] = 0x02;
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == NUMBER) { if (PeekToken()->type == NUMBER) {
int* value = PeekToken()->value; // int* value = PeekToken()->value;
opcode->ParameterOneType = Constant;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value;
Memory[ProgramCounter] = 2 >> *value & 0xFF; // Memory[ProgramCounter] = 2 >> *value & 0xFF;
Memory[ProgramCounter + 1] = *value & 0xFF; // Memory[ProgramCounter + 1] = *value & 0xFF;
} }
else { else {
fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->line); fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->line);
@@ -284,30 +322,34 @@ void HandleOperation(void) {
return; return;
case 3: //YLD case 3: //YLD
Memory[ProgramCounter] = 0x03; //Memory[ProgramCounter] = 0x03;
opcode->ParameterOneType = None;
ProgramCounter++; ProgramCounter++;
break; break;
case 4: //RET case 4: //RET
Memory[ProgramCounter] = 0x04; //Memory[ProgramCounter] = 0x04;
opcode->ParameterOneType = None;
ProgramCounter++; ProgramCounter++;
break; break;
case 5: //CALL case 5: //CALL
Memory[ProgramCounter] = 0x05; //Memory[ProgramCounter] = 0x05;
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
const Symbol* symbol = GetSymbol(PeekToken()->lexeme); Symbol* symbol = GetSymbol(PeekToken()->lexeme);
opcode->ParameterOneType = Address;
if (!symbol) { // if (!symbol) {
fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme);
exit(1); // exit(1);
} // }
if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0);
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; else opcode->ParameterOne.Address = symbol;
Memory[ProgramCounter + 1] = symbol->address & 0xFF; //Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
//Memory[ProgramCounter + 1] = symbol->address & 0xFF;
} }
else { else {
fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line);
@@ -317,20 +359,23 @@ void HandleOperation(void) {
ProgramCounter += 2; ProgramCounter += 2;
break; break;
case 6: //JMP case 6: //JMP
Memory[ProgramCounter] = 0x06; //Memory[ProgramCounter] = 0x06;
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
const Symbol* symbol = GetSymbol(PeekToken()->lexeme); Symbol* symbol = GetSymbol(PeekToken()->lexeme);
opcode->ParameterOneType = Address;
if (!symbol) { // if (!symbol) {
fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme);
exit(1); // exit(1);
} // }
if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0);
else opcode->ParameterOne.Address = symbol;
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
Memory[ProgramCounter + 1] = symbol->address & 0xFF; // Memory[ProgramCounter + 1] = symbol->address & 0xFF;
} }
else { else {
fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line);
@@ -340,15 +385,17 @@ void HandleOperation(void) {
ProgramCounter += 2; ProgramCounter += 2;
break; break;
case 7: //IN case 7: //IN
Memory[ProgramCounter] = 0x07; //Memory[ProgramCounter] = 0x07;
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == NUMBER) { if (PeekToken()->type == NUMBER) {
int* value = PeekToken()->value; opcode->ParameterOneType = Constant;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value;
// int* value = PeekToken()->value;
Memory[ProgramCounter] = 2 >> *value & 0xFF; // Memory[ProgramCounter] = 2 >> *value & 0xFF;
Memory[ProgramCounter + 1] = *value & 0xFF; // Memory[ProgramCounter + 1] = *value & 0xFF;
} }
else { else {
fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line); fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line);
@@ -358,15 +405,17 @@ void HandleOperation(void) {
ProgramCounter += 2; ProgramCounter += 2;
break; break;
case 8: //OUT case 8: //OUT
Memory[ProgramCounter] = 0x08; //Memory[ProgramCounter] = 0x08;
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == NUMBER) { if (PeekToken()->type == NUMBER) {
int* value = PeekToken()->value; opcode->ParameterOneType = Constant;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value;
// int* value = PeekToken()->value;
Memory[ProgramCounter] = 2 >> *value & 0xFF; // Memory[ProgramCounter] = 2 >> *value & 0xFF;
Memory[ProgramCounter + 1] = *value & 0xFF; // Memory[ProgramCounter + 1] = *value & 0xFF;
} }
else { else {
fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line); fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->line);
@@ -377,6 +426,8 @@ void HandleOperation(void) {
break; break;
} }
AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes);
return; return;
} }
@@ -420,33 +471,43 @@ int Expect(int count, ...) {
void PrintSymbols(void) { void PrintSymbols(void) {
printf("-----SYMBOLS-----\n"); printf("-----SYMBOLS-----\n");
for(int i = 0; i < SymbolsTable->size; i++) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
Symbol* symbol = SymbolsTable->content[i]; Symbol* symbol = MachineState.SymbolsTable->content[i];
printf("[%#06X] %s\n", symbol->address, symbol->token->lexeme); printf("[%#06X] %s\n", symbol->address, symbol->token->lexeme);
} }
printf("-----SYMBOLS-----\n"); printf("-----SYMBOLS-----\n");
} }
void AddSymbol(Token* token, int address) { Symbol* AddSymbol(Token* token, int address, int resolved) {
if (!token) return; if (!token) return NULL;
if (token->type != IDENTIFIER && token->type != LABEL) return; if (token->type != IDENTIFIER && token->type != LABEL) return NULL;
for(int i = 0; i < SymbolsTable->size; i++) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
Symbol* s = SymbolsTable->content[i]; Symbol* s = MachineState.SymbolsTable->content[i];
if (strcmp(s->token->lexeme, token->lexeme) == 0) return; if (strcmp(s->token->lexeme, token->lexeme) == 0) {
if (s->resolved) {
fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->line, token->lexeme);
exit(1);
}
s->resolved = resolved;
s->address = address;
return s;
}
} }
Symbol* symbol = CreateSymbol(token, address); Symbol* symbol = CreateSymbol(token, address, resolved);
AddListItem(symbol, sizeof(Symbol), SymbolsTable); AddListItem(symbol, sizeof(Symbol), MachineState.SymbolsTable);
return symbol;
} }
const Symbol* GetSymbol(char* name) { Symbol* GetSymbol(char* name) {
if (!name) return NULL; if (!name) return NULL;
for(int i = 0; i < SymbolsTable->size; i++) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
const Symbol* s = SymbolsTable->content[i]; Symbol* s = MachineState.SymbolsTable->content[i];
if (strcmp(s->token->lexeme, name) == 0) return s; if (strcmp(s->token->lexeme, name) == 0) return s;
} }
@@ -454,17 +515,26 @@ const Symbol* GetSymbol(char* name) {
return NULL; return NULL;
} }
Symbol* CreateSymbol(Token* token, int address) { Symbol* CreateSymbol(Token* token, int address, int resolved) {
Symbol* symbol = calloc(1, sizeof(Symbol)); Symbol* symbol = calloc(1, sizeof(Symbol));
if (!symbol) return NULL; if (!symbol) return NULL;
symbol->token = token; symbol->token = token;
symbol->address = address; symbol->address = address;
symbol->resolved = resolved;
return symbol; return symbol;
} }
IROpcode* CreateIROpcode(TokenType mnemonic) {
IROpcode* opcode = calloc(1, sizeof(IROpcode));
opcode->Mnemonic = mnemonic;
return opcode;
}
void AdvanceParser(void) { void AdvanceParser(void) {
if (ParserAtEnd()) return; if (ParserAtEnd()) return;