Some refactoring to update everything to use the new structures and some new considerations for how Symbols and Instructions shoudl be represented.
This commit is contained in:
+8
-6
@@ -4,8 +4,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "symbols_table.h"
|
#include "symbols_table.h"
|
||||||
|
|
||||||
#define OPCODECOUNT 13
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
R1, R2, R3, R4, R5, R6, R7, R8
|
R1, R2, R3, R4, R5, R6, R7, R8
|
||||||
} Registers;
|
} Registers;
|
||||||
@@ -16,9 +14,10 @@ typedef enum {
|
|||||||
} Mnemonic;
|
} Mnemonic;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
None,
|
NoParameter,
|
||||||
Constant,
|
ConstantParameter,
|
||||||
Address
|
AddressParameter,
|
||||||
|
RegisterParameter
|
||||||
} OpcodeParameter;
|
} OpcodeParameter;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -37,10 +36,13 @@ typedef struct {
|
|||||||
} ParameterTwo;
|
} ParameterTwo;
|
||||||
} Instruction;
|
} Instruction;
|
||||||
|
|
||||||
extern Instruction instructions[OPCODECOUNT];
|
//extern Instruction instructions[OPCODECOUNT];
|
||||||
|
|
||||||
|
Instruction* CreateInstruction(Mnemonic mnemonic);
|
||||||
|
void FreeInstruction(Instruction* instruction);
|
||||||
int IsOpcode(const char*, Mnemonic*);
|
int IsOpcode(const char*, Mnemonic*);
|
||||||
int IsRegister(const char*, Registers*);
|
int IsRegister(const char*, Registers*);
|
||||||
|
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]);
|
||||||
//const Instruction* GetOpcodeDetails(Mnemonic);
|
//const Instruction* GetOpcodeDetails(Mnemonic);
|
||||||
unsigned char GetInstructionMask(Mnemonic type);
|
unsigned char GetInstructionMask(Mnemonic type);
|
||||||
|
|
||||||
|
|||||||
+14
-14
@@ -18,24 +18,24 @@
|
|||||||
// int resolved;
|
// int resolved;
|
||||||
// } Symbol;
|
// } Symbol;
|
||||||
|
|
||||||
typedef struct {
|
// typedef struct {
|
||||||
Mnemonic Mnemonic;
|
// Mnemonic Mnemonic;
|
||||||
TokenClass ParameterOneType;
|
// TokenClass ParameterOneType;
|
||||||
TokenClass ParameterTwoType;
|
// TokenClass ParameterTwoType;
|
||||||
|
|
||||||
union {
|
// union {
|
||||||
uint16_t Constant;
|
// uint16_t Constant;
|
||||||
Symbol* Address;
|
// Symbol* Address;
|
||||||
} ParameterOne;
|
// } ParameterOne;
|
||||||
|
|
||||||
union {
|
// union {
|
||||||
uint16_t Constant;
|
// uint16_t Constant;
|
||||||
Symbol* Address;
|
// Symbol* Address;
|
||||||
} ParameterTwo;
|
// } ParameterTwo;
|
||||||
} IROpcode;
|
// } IROpcode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
List* Opcodes;
|
List* Instructions;
|
||||||
SymbolTable* SymbolsTable;
|
SymbolTable* SymbolsTable;
|
||||||
} IRState;
|
} IRState;
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,21 @@
|
|||||||
|
|
||||||
#define SYMBOLSTABLE_DEFAULT_CAPACITY 128
|
#define SYMBOLSTABLE_DEFAULT_CAPACITY 128
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Data,
|
||||||
|
Address
|
||||||
|
} SymbolType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* Value;
|
|
||||||
char* Name;
|
char* Name;
|
||||||
int Length;
|
int Length;
|
||||||
int Resolved;
|
int Resolved;
|
||||||
|
|
||||||
|
union {
|
||||||
|
char* Text;
|
||||||
|
int Number;
|
||||||
|
//Instruction Instruction;
|
||||||
|
} Value;
|
||||||
} Symbol;
|
} Symbol;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
+69
-31
@@ -2,22 +2,49 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
Instruction instructions[OPCODECOUNT] = {
|
#define OPCODECOUNT 13
|
||||||
{ "copy", COPY, Reg | Address, Reg | Constant | Address },
|
|
||||||
{ "add", ADD, Reg, Reg | Constant },
|
struct _instruction {
|
||||||
{ "sub", SUB, Reg, Reg | Constant },
|
char* Name;
|
||||||
{ "jz", JZ, Address, None },
|
Mnemonic Mnemonic;
|
||||||
{ "int", INT, Constant, None },
|
|
||||||
{ "yld", YLD, None, None },
|
|
||||||
{ "ret", RET, None, None },
|
|
||||||
{ "cmp", CMP, Reg, Reg | Constant },
|
|
||||||
{ "in", IN, Constant | Reg, None},
|
|
||||||
{ "out", OUT, None, None},
|
|
||||||
{ "nop", NOP, None, None},
|
|
||||||
{ "jmp", JMP, Address, None},
|
|
||||||
{ "call", CALL, Address, None}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _instruction instructions[OPCODECOUNT] = {
|
||||||
|
{ "copy", COPY },//, Reg | Address, Reg | Constant | Address },
|
||||||
|
{ "add", ADD },//, Reg, Reg | Constant },
|
||||||
|
{ "sub", SUB },//, Reg, Reg | Constant },
|
||||||
|
{ "jz", JZ },//, Address, None },
|
||||||
|
{ "int", INT },//, Constant, None },
|
||||||
|
{ "yld", YLD },//, None, None },
|
||||||
|
{ "ret", RET },//, None, None },
|
||||||
|
{ "cmp", CMP },//, Reg, Reg | Constant },
|
||||||
|
{ "in", IN },//, Constant | Reg, None},
|
||||||
|
{ "out", OUT },//, None, None},
|
||||||
|
{ "nop", NOP },//, None, None},
|
||||||
|
{ "jmp", JMP },//, Address, None},
|
||||||
|
{ "call", CALL },//, Address, None}
|
||||||
|
};
|
||||||
|
|
||||||
|
Instruction* CreateInstruction(Mnemonic mnemonic) {
|
||||||
|
Instruction* instruction = calloc(1, sizeof(Instruction));
|
||||||
|
|
||||||
|
if (!instruction) {
|
||||||
|
fprintf(stderr, "Failed to calloc room for an Instruction. %s.\n", strerror(errno));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
instruction->Mnemonic = mnemonic;
|
||||||
|
|
||||||
|
return instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeInstruction(Instruction* instruction) {
|
||||||
|
if (!instruction) return;
|
||||||
|
|
||||||
|
free(instruction);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char GetInstructionMask(Mnemonic type) {
|
unsigned char GetInstructionMask(Mnemonic type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case COPY:
|
case COPY:
|
||||||
@@ -49,6 +76,17 @@ unsigned char GetInstructionMask(Mnemonic type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]) {
|
||||||
|
memset(buffer, '\0', 12);
|
||||||
|
|
||||||
|
for(int i = 0; i < OPCODECOUNT; i++) {
|
||||||
|
if (instructions[i].Mnemonic == mnemonic) {
|
||||||
|
strncpy(buffer, instructions[i].Name, 11);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NOP - 0000 0000 NOP
|
NOP - 0000 0000 NOP
|
||||||
JZ - 0000 0001 JZ Address
|
JZ - 0000 0001 JZ Address
|
||||||
@@ -82,30 +120,30 @@ unsigned char GetInstructionMask(Mnemonic type) {
|
|||||||
//Address XXX1 0XXX
|
//Address XXX1 0XXX
|
||||||
//R1 XXXX X000 -> XXXX X111 (R1 to R8)
|
//R1 XXXX X000 -> XXXX X111 (R1 to R8)
|
||||||
|
|
||||||
Register registers[REGISTERCOUNT] = {
|
// Register registers[REGISTERCOUNT] = {
|
||||||
{ "r1", R1 },
|
// { "r1", R1 },
|
||||||
{ "r2", R2 },
|
// { "r2", R2 },
|
||||||
{ "r3", R3 },
|
// { "r3", R3 },
|
||||||
{ "r4", R4 },
|
// { "r4", R4 },
|
||||||
{ "r5", R5 },
|
// { "r5", R5 },
|
||||||
{ "r6", R6 },
|
// { "r6", R6 },
|
||||||
{ "r7", R7 },
|
// { "r7", R7 },
|
||||||
{ "r8", R8 }
|
// { "r8", R8 }
|
||||||
};
|
// };
|
||||||
|
|
||||||
const Instruction* GetOpcodeDetails(Mnemonic type) {
|
// const Instruction* GetOpcodeDetails(Mnemonic type) {
|
||||||
for(int i = 0; i < OPCODECOUNT; i++) {
|
// for(int i = 0; i < OPCODECOUNT; i++) {
|
||||||
if (instructions[i].op == type) return &instructions[i];
|
// if (instructions[i].op == type) return &instructions[i];
|
||||||
}
|
// }
|
||||||
|
|
||||||
return NULL;
|
// return NULL;
|
||||||
}
|
// }
|
||||||
|
|
||||||
int IsOpcode(const char* text, Mnemonic* opcode) {
|
int IsOpcode(const char* text, Mnemonic* opcode) {
|
||||||
if (!text) return 0;
|
if (!text) return 0;
|
||||||
|
|
||||||
for(int i = 0; i < OPCODECOUNT; i++) {
|
for(int i = 0; i < OPCODECOUNT; i++) {
|
||||||
if (strcmp(instructions[i], text) == 0) {
|
if (strcmp(instructions[i].Name, text) == 0) {
|
||||||
if (opcode) *opcode = instructions[i].Mnemonic;
|
if (opcode) *opcode = instructions[i].Mnemonic;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-12
@@ -10,7 +10,7 @@ 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)
|
||||||
|
|
||||||
IROpcode* CreateIROpcode(Mnemonic mnemonic);
|
//IROpcode* CreateIROpcode(Mnemonic mnemonic);
|
||||||
void PrintSymbols(void);
|
void PrintSymbols(void);
|
||||||
void HandleOperation(void);
|
void HandleOperation(void);
|
||||||
void HandleAssemblerDirective(void);
|
void HandleAssemblerDirective(void);
|
||||||
@@ -19,8 +19,8 @@ Token* PeekToken(void);
|
|||||||
int ParserAtEnd(void);
|
int ParserAtEnd(void);
|
||||||
int Expect(int, ...);
|
int Expect(int, ...);
|
||||||
//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;
|
IRState MachineState;
|
||||||
@@ -34,7 +34,7 @@ IRState* ParseTokens(List* tokens) {
|
|||||||
TokensList = tokens;
|
TokensList = tokens;
|
||||||
|
|
||||||
MachineState.SymbolsTable = CreateSymbolTable();
|
MachineState.SymbolsTable = CreateSymbolTable();
|
||||||
MachineState.Opcodes = CreateList();
|
MachineState.Instructions = CreateList();
|
||||||
|
|
||||||
while(!ParserAtEnd()) {
|
while(!ParserAtEnd()) {
|
||||||
Token* t = PeekToken();
|
Token* t = PeekToken();
|
||||||
@@ -48,7 +48,8 @@ IRState* ParseTokens(List* tokens) {
|
|||||||
break;
|
break;
|
||||||
case LabelClass:
|
case LabelClass:
|
||||||
printf("%s: \n", t->Lemexe);
|
printf("%s: \n", t->Lemexe);
|
||||||
AddSymbol(t, 2, ProgramCounter, 1);
|
AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable);
|
||||||
|
//AddSymbol(t, 2, ProgramCounter, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -105,7 +106,7 @@ void HandleAssemblerDirective(void) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
//ProgramCounter += strlen(PeekToken()->lexeme);
|
//ProgramCounter += strlen(PeekToken()->lexeme);
|
||||||
HeapTop += strlen(identifier->Lemexe);
|
//HeapTop += strlen(identifier->Lemexe);
|
||||||
symbol->Length = strlen(identifier->Lemexe);
|
symbol->Length = strlen(identifier->Lemexe);
|
||||||
|
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
@@ -124,7 +125,7 @@ void HandleAssemblerDirective(void) {
|
|||||||
// identifier->value = identifier->lexeme;
|
// identifier->value = identifier->lexeme;
|
||||||
// identifier->lexeme[oldLength + 1] = '\0';//*PeekToken()->lexeme & 0x0F;
|
// identifier->lexeme[oldLength + 1] = '\0';//*PeekToken()->lexeme & 0x0F;
|
||||||
symbol->Length++; //Basically, read in the NULL byte at the end of the string.
|
symbol->Length++; //Basically, read in the NULL byte at the end of the string.
|
||||||
HeapTop++;
|
//HeapTop++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,11 +141,11 @@ void HandleAssemblerDirective(void) {
|
|||||||
void HandleRegisterBasedOpcode(unsigned char mask) {
|
void HandleRegisterBasedOpcode(unsigned char mask) {
|
||||||
//Memory[ProgramCounter] = mask;
|
//Memory[ProgramCounter] = mask;
|
||||||
|
|
||||||
ProgramCounter++;
|
//ProgramCounter++;
|
||||||
|
|
||||||
Token* token = PeekToken();
|
Token* token = PeekToken();
|
||||||
|
|
||||||
IROpcode* opcode = CreateIROpcode(token->Value.Mnemonic);
|
Instruction* opcode = CreateInstruction(token->Value.Mnemonic); //CreateIROpcode(token->Value.Mnemonic);
|
||||||
|
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
|
|
||||||
@@ -152,15 +153,19 @@ void HandleRegisterBasedOpcode(unsigned char mask) {
|
|||||||
|
|
||||||
if (token->Class == RegisterClass) {
|
if (token->Class == RegisterClass) {
|
||||||
//Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07;
|
//Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07;
|
||||||
opcode->ParameterOneType = RegisterClass;
|
opcode->ParameterOneType = RegisterParameter;
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
}
|
}
|
||||||
else if (token->Class & AddressClass && token->Value.Mnemonic == COPY) {
|
else if (token->Class & AddressClass && token->Value.Mnemonic == COPY) {
|
||||||
//opcode->ParameterOneType = Address;
|
//opcode->ParameterOneType = Address;
|
||||||
|
|
||||||
Symbol* symbol = GetSymbol(token->Lemexe);
|
Symbol* symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable); //GetSymbol(token->Lemexe);
|
||||||
|
|
||||||
if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 2, 0, 0);
|
if (!symbol) {
|
||||||
|
opcode->ParameterOneType = AddressParameter;
|
||||||
|
//AddSymbol(token, 2, 0, 0);
|
||||||
|
opcode->ParameterOne.Symbol = AddSymbolToTable(token->Lemexe, NULL, strlen(token->Lemexe), MachineState.SymbolsTable);
|
||||||
|
}
|
||||||
else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved);
|
else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user