Incomplete, but I want to make sure the ideas I have here don't get wiped. Sadly this commit won't compile.

This commit is contained in:
2022-09-15 21:29:27 +00:00
parent 6d17dffcdf
commit 2ae60a607c
8 changed files with 238 additions and 210 deletions
+33 -17
View File
@@ -2,30 +2,46 @@
#define OPCODES_H #define OPCODES_H
#include <string.h> #include <string.h>
#include "token.h" #include "symbols_table.h"
#define OPCODECOUNT 13 #define OPCODECOUNT 13
#define REGISTERCOUNT 8
//const unsigned char COPYADDRESSMASK = 0x80; typedef enum {
R1, R2, R3, R4, R5, R6, R7, R8
} Registers;
typedef enum {
COPY, ADD, SUB, JZ, INT, YLD, RET,
CMP, NOP, JMP, CALL, IN, OUT,
} Mnemonic;
typedef enum {
None,
Constant,
Address
} OpcodeParameter;
typedef struct { typedef struct {
char* lexeme; Mnemonic Mnemonic;
TokenType op; OpcodeParameter ParameterOneType;
TokenClass parameter_one; OpcodeParameter ParameterTwoType;
TokenClass parameter_two;
union {
int Constant;
Symbol* Symbol;
} ParameterOne;
union {
int Constant;
Symbol* Symbol;
} ParameterTwo;
} Instruction; } Instruction;
typedef struct {
char* lexeme;
TokenType type;
} Register;
extern Instruction instructions[OPCODECOUNT]; extern Instruction instructions[OPCODECOUNT];
extern Register registers[REGISTERCOUNT];
int IsOpcode(const char*, TokenType*); int IsOpcode(const char*, Mnemonic*);
int IsRegister(const char*, TokenType*); int IsRegister(const char*, Registers*);
const Instruction* GetOpcodeDetails(TokenType); //const Instruction* GetOpcodeDetails(Mnemonic);
unsigned char GetInstructionMask(TokenType type); unsigned char GetInstructionMask(Mnemonic type);
#endif #endif
+9 -8
View File
@@ -7,18 +7,19 @@
#include "list.h" #include "list.h"
#include "token.h" #include "token.h"
#include "opcodes.h" #include "opcodes.h"
#include "symbols_table.h"
#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF #define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF
typedef struct { // typedef struct {
Token* token; // Token* token;
int length; // int length;
int address; // int address;
int resolved; // int resolved;
} Symbol; // } Symbol;
typedef struct { typedef struct {
TokenType Mnemonic; Mnemonic Mnemonic;
TokenClass ParameterOneType; TokenClass ParameterOneType;
TokenClass ParameterTwoType; TokenClass ParameterTwoType;
@@ -35,7 +36,7 @@ typedef struct {
typedef struct { typedef struct {
List* Opcodes; List* Opcodes;
List* SymbolsTable; SymbolTable* SymbolsTable;
} IRState; } IRState;
IRState* ParseTokens(List*); IRState* ParseTokens(List*);
+1
View File
@@ -12,6 +12,7 @@ typedef struct {
void* Value; void* Value;
char* Name; char* Name;
int Length; int Length;
int Resolved;
} Symbol; } Symbol;
typedef struct { typedef struct {
+40 -36
View File
@@ -5,50 +5,54 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include "opcodes.h"
typedef enum { typedef enum {
PLUS, Plus = '+',
MINUS, Minus = '-',
STAR, Star = '*',
SLASH, Slash = '/',
POWER, Power = '^',
LPARAM, LParan = '(',
RPARAM, RParan = ')',
LBRACKET, LBracket = '[',
RBracket, RBracket = ']',
COMMA, Comma = ',',
STRING, NewLine = '\n'
IDENTIFIER, } TokenPunctuation;
LABEL,
NUMBER,
LineEnd,
//Keywords
DB, ORG,
//Mnemonics
COPY, ADD, SUB, JZ, INT, YLD, RET,
CMP, NOP, JMP, CALL, IN, OUT,
//Registers
R1, R2, R3, R4, R5, R6, R7, R8
} TokenType;
typedef enum { typedef enum {
None = 0, DB,
Reg = 1, Origin
Constant = 2, } Directive;
Address = 4,
Mnemonic = 8, typedef enum {
Directive = 16 RegisterClass = 0,
NumberClass = 1,
CharacterClass = 2,
MnemonicClass = 4,
DirectiveClass = 8,
PunctuationClass = 16,
IdentifierClass = 32,
LabelClass = 64,
AddressClass = LabelClass | IdentifierClass
} TokenClass; } TokenClass;
typedef struct { typedef struct {
TokenType type; char* Lemexe;
char* lexeme; TokenClass Class;
void* value; int LineNumber;
int line;
TokenClass token_class; union {
TokenPunctuation Punctuation;
Registers Register;
Mnemonic Mnemonic;
Directive Directive;
int Number;
} Value;
} Token; } Token;
Token* CreateToken(char*, void*, int, TokenType); Token* CreateToken(int lineNumber, TokenClass tokenClass);
void FreeToken(Token*); void FreeToken(Token* token);
#endif #endif
+11 -13
View File
@@ -18,7 +18,7 @@ Instruction instructions[OPCODECOUNT] = {
{ "call", CALL, Address, None} { "call", CALL, Address, None}
}; };
unsigned char GetInstructionMask(TokenType type) { unsigned char GetInstructionMask(Mnemonic type) {
switch (type) { switch (type) {
case COPY: case COPY:
return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address
@@ -93,7 +93,7 @@ Register registers[REGISTERCOUNT] = {
{ "r8", R8 } { "r8", R8 }
}; };
const Instruction* GetOpcodeDetails(TokenType 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];
} }
@@ -101,12 +101,12 @@ const Instruction* GetOpcodeDetails(TokenType type) {
return NULL; return NULL;
} }
int IsOpcode(const char* text, TokenType* 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].lexeme, text) == 0) { if (strcmp(instructions[i], text) == 0) {
if (opcode) *opcode = instructions[i].op; if (opcode) *opcode = instructions[i].Mnemonic;
return 1; return 1;
} }
} }
@@ -114,15 +114,13 @@ int IsOpcode(const char* text, TokenType* opcode) {
return 0; return 0;
} }
int IsRegister(const char* text, TokenType* reg) { int IsRegister(const char* text, Registers* reg) {
if (!text) return 0; if (!text) return 0;
for(int i = 0; i < REGISTERCOUNT; i++) { int length = strlen(text);
if (strcmp(registers[i].lexeme, text) == 0) {
*reg = registers[i].type;
return 1;
}
}
return 0; if (length != 2) return 0;
if (text[0] != 'r') return 0;
return text[1] >= '1' && text[1] <= '8';
} }
+82 -86
View File
@@ -10,8 +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(TokenType mnemonic); IROpcode* CreateIROpcode(Mnemonic mnemonic);
Symbol* AddSymbol(Token* token, int length, int address, int resolved);
void PrintSymbols(void); void PrintSymbols(void);
void HandleOperation(void); void HandleOperation(void);
void HandleAssemblerDirective(void); void HandleAssemblerDirective(void);
@@ -19,7 +18,6 @@ void AdvanceParser(void);
Token* PeekToken(void); Token* PeekToken(void);
int ParserAtEnd(void); int ParserAtEnd(void);
int Expect(int, ...); int Expect(int, ...);
Symbol* GetSymbol(char*);
//List* SymbolsTable; //List* SymbolsTable;
unsigned int HeapTop = 4; unsigned int HeapTop = 4;
unsigned int ProgramCounter = 0; unsigned int ProgramCounter = 0;
@@ -35,24 +33,22 @@ IRState* ParseTokens(List* tokens) {
TokensList = tokens; TokensList = tokens;
MachineState.SymbolsTable = CreateList(); MachineState.SymbolsTable = CreateSymbolTable();
MachineState.Opcodes = CreateList(); MachineState.Opcodes = CreateList();
while(!ParserAtEnd()) { while(!ParserAtEnd()) {
Token* t = PeekToken(); Token* t = PeekToken();
switch(t->token_class) { switch(t->Class) {
case Directive: case DirectiveClass:
HandleAssemblerDirective(); HandleAssemblerDirective();
break; break;
case Mnemonic: case MnemonicClass:
HandleOperation(); HandleOperation();
break; break;
case Address: case LabelClass:
if (t->type == LABEL) { printf("%s: \n", t->Lemexe);
printf("%s: \n", t->lexeme); AddSymbol(t, 2, ProgramCounter, 1);
AddSymbol(t, 2, ProgramCounter, 1);
}
break; break;
default: default:
break; break;
@@ -61,7 +57,7 @@ IRState* ParseTokens(List* tokens) {
AdvanceParser(); AdvanceParser();
} }
if (MachineState.SymbolsTable->size > 0) PrintSymbols(); if (MachineState.SymbolsTable->Size > 0) PrintSymbols();
//DestroyList(SymbolsTable); //DestroyList(SymbolsTable);
@@ -85,22 +81,22 @@ IRState* ParseTokens(List* tokens) {
void HandleAssemblerDirective(void) { void HandleAssemblerDirective(void) {
if (PeekToken()->type == DB) { if (PeekToken()->Value.Directive == DB) {
AdvanceParser(); AdvanceParser();
Token* identifier = PeekToken(); Token* identifier = PeekToken();
if (!Expect(1, IDENTIFIER)) { if (!Expect(1, IdentifierClass)) {
fprintf(stderr, "Expected identifier on line %d\n", identifier->line); fprintf(stderr, "Expected identifier on line %d\n", identifier->LineNumber);
exit(1); exit(1);
} }
Symbol* symbol = AddSymbol(identifier, 0, HeapTop, 1); Symbol* symbol = AddSymbolToTable(identifier->Lemexe, NULL, strlen(identifier->Lemexe), MachineState.SymbolsTable);
identifier = PeekToken(); identifier = PeekToken();
switch(identifier->type) { switch(identifier->Class) {
case STRING: case CharacterClass:
//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++) {
@@ -109,16 +105,16 @@ void HandleAssemblerDirective(void) {
// } // }
//ProgramCounter += strlen(PeekToken()->lexeme); //ProgramCounter += strlen(PeekToken()->lexeme);
HeapTop += strlen(identifier->lexeme); HeapTop += strlen(identifier->Lemexe);
symbol->length = strlen(identifier->lexeme); symbol->Length = strlen(identifier->Lemexe);
AdvanceParser(); AdvanceParser();
if (PeekToken()->type == COMMA) { if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) {
AdvanceParser(); AdvanceParser();
if (PeekToken()-> type != NUMBER) { if (PeekToken()-> Class != NumberClass) {
fprintf(stderr, "Expected string termination byte on line %d\n", PeekToken()->line); fprintf(stderr, "Expected string termination byte on line %d\n", PeekToken()->LineNumber);
exit(1); exit(1);
} }
else { else {
@@ -127,15 +123,15 @@ void HandleAssemblerDirective(void) {
// identifier->lexeme = realloc(identifier->lexeme, oldLength + 2); // identifier->lexeme = realloc(identifier->lexeme, oldLength + 2);
// 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;
} }
} }
case NUMBER: case NumberClass:
break; break;
default: default:
fprintf(stderr, "[Line: %d] Expected either a number or string after identifier '%s'.\n", PeekToken()->line, identifier->lexeme); fprintf(stderr, "[Line: %d] Expected either a number or string after identifier '%s'.\n", PeekToken()->LineNumber, identifier->Lemexe);
exit(1); exit(1);
} }
} }
@@ -148,42 +144,42 @@ void HandleRegisterBasedOpcode(unsigned char mask) {
Token* token = PeekToken(); Token* token = PeekToken();
IROpcode* opcode = CreateIROpcode(token->type); IROpcode* opcode = CreateIROpcode(token->Value.Mnemonic);
AdvanceParser(); AdvanceParser();
token = PeekToken(); token = PeekToken();
if (token->token_class == Reg) { if (token->Class == RegisterClass) {
//Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; //Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07;
opcode->ParameterOneType = Reg; opcode->ParameterOneType = RegisterClass;
AdvanceParser(); AdvanceParser();
} }
else if (token->token_class == Address && token->type == COPY) { else if (token->Class & AddressClass && token->Value.Mnemonic == COPY) {
opcode->ParameterOneType = Address; //opcode->ParameterOneType = Address;
Symbol* symbol = GetSymbol(token->lexeme); Symbol* symbol = GetSymbol(token->Lemexe);
if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 2, 0, 0); if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 2, 0, 0);
else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved); 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->LineNumber);
exit(1); exit(1);
} }
token = PeekToken(); token = PeekToken();
if (!Expect(1, COMMA)) { if (!Expect(1, Comma)) {
fprintf(stderr, "[Error] Expected comma on line %d.\n", token->line); fprintf(stderr, "[Error] Expected comma on line %d.\n", token->LineNumber);
exit(1); exit(1);
} }
token = PeekToken(); token = PeekToken();
if (token->type == IDENTIFIER || token->type == LABEL) { if (token->Class & AddressClass) {
opcode->ParameterTwoType = Address; opcode->ParameterTwoType = IdentifierClass;
Symbol* symbol = GetSymbol(token->lexeme); Symbol* symbol = GetSymbol(token->Lemexe);
// 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);
@@ -199,10 +195,10 @@ void HandleRegisterBasedOpcode(unsigned char mask) {
AdvanceParser(); AdvanceParser();
} }
else if (token->type == NUMBER) { else if (token->Class == NumberClass) {
opcode->ParameterTwoType = Constant; //opcode->ParameterTwoType = ;
opcode->ParameterTwo.Constant = *(int*)PeekToken()->value; opcode->ParameterTwo.Constant = PeekToken()->Value.Number;
// Memory[ProgramCounter - 1] |= 0x08; //0b00001000; // Memory[ProgramCounter - 1] |= 0x08; //0b00001000;
// int* value = PeekToken()->value; // int* value = PeekToken()->value;
@@ -212,9 +208,9 @@ void HandleRegisterBasedOpcode(unsigned char mask) {
AdvanceParser(); AdvanceParser();
} }
else if (token->token_class == Reg) { else if (token->Class == RegisterClass) {
opcode->ParameterTwoType = Reg; //opcode->ParameterTwoType = ;
opcode->ParameterTwo.Constant = (PeekToken()->type - R1) &0x07; opcode->ParameterTwo.Constant = PeekToken()->Value.Register &0x07;
//Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07; //Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07;
AdvanceParser(); AdvanceParser();
@@ -223,7 +219,7 @@ void HandleRegisterBasedOpcode(unsigned char mask) {
return; return;
} }
else { else {
fprintf(stderr, "[Error] Expected operand, got %s\n", token->lexeme); fprintf(stderr, "[Error] Expected operand, got %s\n", token->Lemexe);
exit(1); exit(1);
} }
@@ -241,22 +237,22 @@ void HandleOperation(void) {
// AdvanceParser(); // AdvanceParser();
unsigned char mask = GetInstructionMask(token->type); unsigned char mask = GetInstructionMask(token->Value.Mnemonic);
if (mask & registerBasedOpcodeMask) { if (mask & registerBasedOpcodeMask) {
HandleRegisterBasedOpcode(mask); HandleRegisterBasedOpcode(mask);
return; return;
} }
IROpcode* opcode = CreateIROpcode(token->type); IROpcode* opcode = CreateIROpcode(token->Value.Mnemonic);
opcode->ParameterTwoType = None; //opcode->ParameterTwoType = None;
AdvanceParser(); AdvanceParser();
switch (mask) { switch (mask) {
case 0: //NOP case 0: //NOP
//Memory[ProgramCounter] = 0x00; //Memory[ProgramCounter] = 0x00;
opcode->ParameterOneType = None; //opcode->ParameterOneType = None;
ProgramCounter++; ProgramCounter++;
return; return;
@@ -265,9 +261,9 @@ void HandleOperation(void) {
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { if (PeekToken()->Class == IdentifierClass || PeekToken()->Class == LabelClass) {
Symbol* symbol = GetSymbol(PeekToken()->lexeme); Symbol* symbol = GetSymbol(PeekToken()->Lemexe);
opcode->ParameterOneType = Address; //opcode->ParameterOneType = Address;
if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 2, 0, 0); if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 2, 0, 0);
else opcode->ParameterOne.Address = symbol; else opcode->ParameterOne.Address = symbol;
@@ -279,16 +275,16 @@ void HandleOperation(void) {
// 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()->Class == NumberClass) {
opcode->ParameterOneType = Constant; //opcode->ParameterOneType = Constant;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value; opcode->ParameterOne.Constant = PeekToken()->Value.Number;
// int* value = 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])->LineNumber);
exit(1); exit(1);
} }
@@ -300,16 +296,16 @@ void HandleOperation(void) {
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == NUMBER) { if (PeekToken()->Class == NumberClass) {
// int* value = PeekToken()->value; // int* value = PeekToken()->value;
opcode->ParameterOneType = Constant; //opcode->ParameterOneType = ;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value; opcode->ParameterOne.Constant = PeekToken()->Value.Number;
// 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()->LineNumber);
exit(1); exit(1);
} }
@@ -318,13 +314,13 @@ void HandleOperation(void) {
return; return;
case 3: //YLD case 3: //YLD
//Memory[ProgramCounter] = 0x03; //Memory[ProgramCounter] = 0x03;
opcode->ParameterOneType = None; //opcode->ParameterOneType = ;
ProgramCounter++; ProgramCounter++;
break; break;
case 4: //RET case 4: //RET
//Memory[ProgramCounter] = 0x04; //Memory[ProgramCounter] = 0x04;
opcode->ParameterOneType = None; //opcode->ParameterOneType = ;
ProgramCounter++; ProgramCounter++;
break; break;
@@ -333,9 +329,9 @@ void HandleOperation(void) {
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { if (PeekToken()->Class == IdentifierClass || PeekToken()->Class == LabelClass) {
Symbol* symbol = GetSymbol(PeekToken()->lexeme); Symbol* symbol = GetSymbol(PeekToken()->Lemexe);
opcode->ParameterOneType = Address; //opcode->ParameterOneType = ;
// 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);
@@ -347,7 +343,7 @@ void HandleOperation(void) {
//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()->LineNumber);
exit(1); exit(1);
} }
@@ -358,9 +354,9 @@ void HandleOperation(void) {
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { if (PeekToken()->Class == IdentifierClass || PeekToken()->Class == LabelClass) {
Symbol* symbol = GetSymbol(PeekToken()->lexeme); Symbol* symbol = GetSymbol(PeekToken()->Lemexe);
opcode->ParameterOneType = Address; //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);
@@ -373,7 +369,7 @@ void HandleOperation(void) {
// 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()->LineNumber);
exit(1); exit(1);
} }
@@ -384,16 +380,16 @@ void HandleOperation(void) {
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == NUMBER) { if (PeekToken()->Class == NumberClass) {
opcode->ParameterOneType = Constant; //opcode->ParameterOneType = ;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value; opcode->ParameterOne.Constant = PeekToken()->Value.Number;
// int* value = 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()->LineNumber);
exit(1); exit(1);
} }
@@ -404,16 +400,16 @@ void HandleOperation(void) {
ProgramCounter++; ProgramCounter++;
if (PeekToken()->type == NUMBER) { if (PeekToken()->Class == NumberClass) {
opcode->ParameterOneType = Constant; //opcode->ParameterOneType = ;
opcode->ParameterOne.Constant = *(int*)PeekToken()->value; opcode->ParameterOne.Constant = PeekToken()->Value.Number;
// int* value = 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()->LineNumber);
exit(1); exit(1);
} }
@@ -433,7 +429,7 @@ int Expect(int count, ...) {
va_start(list, count); va_start(list, count);
for(int i = 0; i < count; i++) { for(int i = 0; i < count; i++) {
if (va_arg(list, TokenType) == token->type) { if (va_arg(list, TokenClass) == token->Class) {
va_end(list); va_end(list);
AdvanceParser(); AdvanceParser();
return 1; return 1;
@@ -449,21 +445,21 @@ void PrintSymbols(void) {
printf("-----SYMBOLS-----\n"); printf("-----SYMBOLS-----\n");
for(int i = 0; i < MachineState.SymbolsTable->size; i++) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
Symbol* symbol = MachineState.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->Lemexe);
} }
printf("-----SYMBOLS-----\n"); printf("-----SYMBOLS-----\n");
} }
Symbol* AddSymbol(Token* token, int length, int address, int resolved) { Symbol* AddSymbol(Token* token, int length, int address, int resolved) {
if (!token) return NULL; if (!token) return NULL;
if (token->type != IDENTIFIER && token->type != LABEL) return NULL; if (token->Class != IdentifierClass && token->Class != LabelClass) return NULL;
for(int i = 0; i < MachineState.SymbolsTable->size; i++) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
Symbol* s = MachineState.SymbolsTable->content[i]; Symbol* s = MachineState.SymbolsTable->content[i];
if (strcmp(s->token->lexeme, token->lexeme) == 0) { if (strcmp(s->token->Lemexe, token->Lemexe) == 0) {
if (s->resolved) { if (s->resolved) {
fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->line, token->lexeme); fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->LineNumber, token->Lemexe);
exit(1); exit(1);
} }
s->resolved = resolved; s->resolved = resolved;
@@ -486,7 +482,7 @@ Symbol* GetSymbol(char* name) {
for(int i = 0; i < MachineState.SymbolsTable->size; i++) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
Symbol* s = MachineState.SymbolsTable->content[i]; Symbol* s = MachineState.SymbolsTable->content[i];
if (strcmp(s->token->lexeme, name) == 0) return s; if (strcmp(s->token->Lemexe, name) == 0) return s;
} }
return NULL; return NULL;
@@ -504,7 +500,7 @@ Symbol* CreateSymbol(Token* token, int length, int address, int resolved) {
return symbol; return symbol;
} }
IROpcode* CreateIROpcode(TokenType mnemonic) { IROpcode* CreateIROpcode(Mnemonic mnemonic) {
IROpcode* opcode = calloc(1, sizeof(IROpcode)); IROpcode* opcode = calloc(1, sizeof(IROpcode));
opcode->Mnemonic = mnemonic; opcode->Mnemonic = mnemonic;
+59 -23
View File
@@ -37,7 +37,8 @@ List* GenerateTokenList(const char* source) {
AdvanceScanner(); AdvanceScanner();
break; //Ignore whitespace break; //Ignore whitespace
case '\n': case '\n':
token = CreateToken("^", NULL, Line, LineEnd); token = CreateToken(Line, PunctuationClass);
token->Value.Punctuation = NewLine;
AddListItem(token, sizeof(Token), tokens); AddListItem(token, sizeof(Token), tokens);
AdvanceScanner(); AdvanceScanner();
Line++; Line++;
@@ -95,24 +96,20 @@ Token* ParseNumber(void) {
if (length == 0) return NULL; if (length == 0) return NULL;
char* lexeme = calloc(sizeof(char), length + 1); char* lexeme = calloc(sizeof(char), length + 1);
long* value = calloc(1, sizeof(long));
if (!lexeme) { if (!lexeme) {
fprintf(stderr, "Failed to calloc space for number. %s.\n", strerror(errno)); fprintf(stderr, "Failed to calloc space for number. %s.\n", strerror(errno));
return NULL; return NULL;
} }
if (!value) {
free(lexeme);
fprintf(stderr, "Failed to calloc space for the raw numeric value of a token. %s.\n", strerror(errno));
return NULL;
}
memcpy(lexeme, &SourceCode[start], length); memcpy(lexeme, &SourceCode[start], length);
// Setting the base to zero means the function will pick the base.
*value = strtol(lexeme, NULL, 0);
return CreateToken(lexeme, value, Line, NUMBER); Token* token = CreateToken(Line, NumberClass);
token->Value.Number = strtol(lexeme, NULL, 0);
token->Lemexe = lexeme;
return token;
} }
Token* ParseDirective(void) { Token* ParseDirective(void) {
@@ -133,12 +130,17 @@ Token* ParseDirective(void) {
memcpy(directive, &SourceCode[start], length); memcpy(directive, &SourceCode[start], length);
Token* token = CreateToken(Line, DirectiveClass);
if (strcmp(directive, ".db") == 0) { if (strcmp(directive, ".db") == 0) {
return CreateToken(directive, directive, Line, DB); token->Value.Directive = DB;
return token;
} }
else if (strcmp(directive, ".org") == 0) { else if (strcmp(directive, ".org") == 0) {
fprintf(stderr, "[Warning] Org is not a supported directive.\n"); fprintf(stderr, "[Warning] Org is not a supported directive.\n");
free(directive); free(directive);
free(token);
IgnoreLine(); IgnoreLine();
return NULL; return NULL;
} }
@@ -178,7 +180,9 @@ Token* ParseString(void) {
AdvanceScanner(); //Consume the trailing double quote. AdvanceScanner(); //Consume the trailing double quote.
Token* token = CreateToken(lexeme, lexeme, Line, STRING); Token* token = CreateToken(Line, CharacterClass);
token->Lemexe = lexeme;
return token; return token;
} }
@@ -194,7 +198,8 @@ Token* ParseIdentifier(void) {
if (length == 0) return NULL; if (length == 0) return NULL;
TokenType type; Mnemonic mnemonics;
Registers reg;
char* lexeme = calloc(sizeof(char), length + 1); char* lexeme = calloc(sizeof(char), length + 1);
if (!lexeme) { if (!lexeme) {
@@ -204,14 +209,33 @@ Token* ParseIdentifier(void) {
memcpy(lexeme, &SourceCode[start], length); memcpy(lexeme, &SourceCode[start], length);
if (IsOpcode(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type); if (IsOpcode(lexeme, &mnemonics)) {
if (IsRegister(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type); Token* token = CreateToken(Line, MnemonicClass);
token->Value.Mnemonic = mnemonics;
return token;
}
if (IsRegister(lexeme, &reg)) {
Token* token = CreateToken(Line, RegisterClass);
token->Value.Register = reg;
return token;
}
if (lexeme[length - 1] == ':') { if (lexeme[length - 1] == ':') {
lexeme[length - 1] = '\0'; //Bit hacky, but this makes the parser's job a bit easier. lexeme[length - 1] = '\0'; //Bit hacky, but this makes the parser's job a bit easier.
return CreateToken(lexeme, lexeme, Line, LABEL); Token* token = CreateToken(Line, LabelClass);
token->Lemexe = lexeme;
return token;
} }
return CreateToken(lexeme, lexeme, Line, IDENTIFIER); Token* token = CreateToken(Line, IdentifierClass);
token->Lemexe = lexeme;
return token;
} }
char PeekScanner(void) { char PeekScanner(void) {
@@ -250,18 +274,30 @@ int IsPunctuation(char c) {
} }
Token* ParsePunctuation(char c) { Token* ParsePunctuation(char c) {
TokenPunctuation punctuation;
switch(c) { switch(c) {
case '[': case '[':
return CreateToken("[", NULL, Line, LBRACKET); punctuation = LBracket;
break;
case ']': case ']':
return CreateToken("]", NULL, Line, RBracket); punctuation = RBracket;
break;
case '(': case '(':
return CreateToken("(", NULL, Line, LPARAM); punctuation = LParan;
break;
case ')': case ')':
return CreateToken(")", NULL, Line, RPARAM); punctuation = RParan;
break;
case ',': case ',':
return CreateToken(",", NULL, Line, COMMA); punctuation = Comma;
break;
default: default:
return NULL; return NULL;
} }
Token* token = CreateToken(Line, PunctuationClass);
token->Value.Punctuation = punctuation;
return token;
} }
+3 -27
View File
@@ -1,8 +1,6 @@
#include "../includes/token.h" #include "../includes/token.h"
TokenClass GetTokenClass(TokenType); Token* CreateToken(int lineNumber, TokenClass tokenClass) {
Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) {
Token* token = calloc(1, sizeof(Token)); Token* token = calloc(1, sizeof(Token));
if (!token) { if (!token) {
@@ -10,36 +8,14 @@ Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) {
return NULL; return NULL;
} }
token->type = type; token->Class = tokenClass;
token->line = lineNumber; token->LineNumber = lineNumber;
token->lexeme = lexeme;
token->value = value;
token->token_class = GetTokenClass(type);
return token; return token;
} }
TokenClass GetTokenClass(TokenType type) {
if (type >= R1 && type <= R8) return Reg;
if (type >= COPY && type <= OUT) return Mnemonic;
if (type >= DB && type <= ORG) return Directive;
switch(type) {
case STRING:
case IDENTIFIER:
case LABEL:
return Address;
case NUMBER:
return Constant;
default:
return None;
}
}
void FreeToken(Token* token) { void FreeToken(Token* token) {
if (!token) return; if (!token) return;
if (token->value && (token->type >= STRING || token->type == NUMBER)) free(token->value);
free(token); free(token);
} }