Reworked the tokens to include a broad class to make parameter matching a bit easier, and removed the hexadecimal distinction.

This commit is contained in:
2022-05-12 20:26:14 +00:00
parent 72abf6c4ab
commit 72525959f6
6 changed files with 94 additions and 34 deletions
+5 -11
View File
@@ -7,29 +7,23 @@
#define OPCODECOUNT 10
#define REGISTERCOUNT 8
typedef enum {
None = 0,
Reg,
Imm8,
Imm16
} ParameterType;
typedef struct {
char* lexeme;
TokenType op;
ParameterType parameter_one;
ParameterType parameter_two;
} OpCode;
TokenClass parameter_one;
TokenClass parameter_two;
} Instruction;
typedef struct {
char* lexeme;
TokenType type;
} Register;
extern OpCode opcodes[OPCODECOUNT];
extern Instruction instructions[OPCODECOUNT];
extern Register registers[REGISTERCOUNT];
int IsOpcode(const char*, TokenType*);
int IsRegister(const char*, TokenType*);
const Instruction* GetOpcodeDetails(TokenType);
#endif
+8 -1
View File
@@ -21,7 +21,6 @@ typedef enum {
IDENTIFIER,
LABEL,
NUMBER,
HEX,
//Keywords
DB, ORG,
//Opcodes
@@ -31,11 +30,19 @@ typedef enum {
R1, R2, R3, R4, R5, R6, R7, R8
} TokenType;
typedef enum {
None,
Reg,
Immediate16,
Opcode
} TokenClass;
typedef struct {
TokenType type;
char* lexeme;
void* value;
int line;
TokenClass token_class;
} Token;
Token* CreateToken(char*, void*, int, TokenType);
+17 -9
View File
@@ -2,15 +2,15 @@
#include <stdlib.h>
#include <string.h>
OpCode opcodes[OPCODECOUNT] = {
{ "copy", COPY, Reg, Reg | Imm8 | Imm16 },
{ "add", ADD, Reg, Reg | Imm8 | Imm16 },
{ "sub", SUB, Reg, Reg | Imm8 | Imm16 },
{ "jz", JZ, Imm8 | Imm16, None },
{ "int", INT, Imm8, None },
Instruction instructions[OPCODECOUNT] = {
{ "copy", COPY, Reg, Reg | Immediate16 },
{ "add", ADD, Reg, Reg | Immediate16 },
{ "sub", SUB, Reg, Reg | Immediate16 },
{ "jz", JZ, Immediate16, None },
{ "int", INT, Immediate16, None },
{ "yld", YLD, None, None },
{ "ret", RET, None, None },
{ "cmp", CMP, Reg | Imm8 | Imm16, Reg | Imm8 | Imm16 },
{ "cmp", CMP, Reg | Immediate16, Reg | Immediate16 },
{ "in", IN, None, None},
{ "out", OUT, None, None}
};
@@ -26,12 +26,20 @@ Register registers[REGISTERCOUNT] = {
{ "r8", R8 }
};
const Instruction* GetOpcodeDetails(TokenType type) {
for(int i = 0; i < OPCODECOUNT; i++) {
if (instructions[i].op == type) return &instructions[i];
}
return NULL;
}
int IsOpcode(const char* text, TokenType* opcode) {
if (!text) return 0;
for(int i = 0; i < OPCODECOUNT; i++) {
if (strcmp(opcodes[i].lexeme, text) == 0) {
if (opcode) *opcode = opcodes[i].op;
if (strcmp(instructions[i].lexeme, text) == 0) {
if (opcode) *opcode = instructions[i].op;
return 1;
}
}
+43 -6
View File
@@ -1,4 +1,5 @@
#include "../includes/parser.h"
#include <stdarg.h>
#ifndef HIGHMEMORY
#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF
@@ -10,13 +11,24 @@ typedef struct {
} Symbol;
Symbol* CreateSymbol(Token*, int);
const List* TokensList;
int CurrentToken = 0;
void AddSymbol(Token*, int);
void PrintSymbols(void);
void HandleOperation(Token*);
void AdvanceParser(void);
Token* PeekToken(void);
int Expect(int, ...);
Token* GetSymbol(char*);
List* SymbolsTable;
unsigned int ProgramCounter = 0;
void ParseTokens(List* tokens) {
if (!tokens) return;
TokensList = tokens;
SymbolsTable = CreateList();
for(int i = 0; i < tokens->size; i++){
@@ -30,12 +42,13 @@ void ParseTokens(List* tokens) {
case STRING:
ProgramCounter += strlen(t->lexeme);
break;
case NUMBER:
case HEX: //Number's will be 2 bytes
case NUMBER: //Number's will be 2 bytes
ProgramCounter += 2;
break;
default: //Instructions are 1 byte wide.
if (IsOpcode(t->lexeme, NULL)) ProgramCounter += 1;
if (t->token_class == Opcode) {
ProgramCounter++;
}
break;
}
@@ -46,6 +59,32 @@ void ParseTokens(List* tokens) {
printf("Program Counter: %d\n", ProgramCounter);
}
void HandleOperation(Token* token) {
const Instruction* inst = GetOpcodeDetails(token->type);
if (!inst) return;
}
int Expect(int count, ...) {
va_list list;
va_start(list, count);
for(int i = 0; i < count; i++) {
if (va_arg(list, TokenClass) == PeekToken()->token_class) {
va_end(list);
//advance
return 1;
}
}
va_end(list);
return 0;
}
void PrintSymbols(void) {
printf("-----SYMBOLS-----\n");
for(int i = 0; i < SymbolsTable->size; i++) {
@@ -79,9 +118,7 @@ Token* GetSymbol(char* name) {
Symbol* CreateSymbol(Token* token, int address) {
Symbol* symbol = calloc(1, sizeof(Symbol));
if (!symbol) {
return NULL;
}
if (!symbol) return NULL;
symbol->token = token;
symbol->address = address;
+3 -7
View File
@@ -79,13 +79,11 @@ List* GenerateTokenList(const char* source) {
Token* ParseNumber(void) {
int start = Position;
int base = 10;
while(!ScannerAtEnd() && isdigit(PeekScanner()))
AdvanceScanner();
if (PeekScanner() == 'x' && isdigit(PeekAheadScanner())) {
base = 16;
AdvanceScanner(); //Consume the 'x'
while(!ScannerAtEnd() && isdigit(PeekScanner())) AdvanceScanner();
}
@@ -109,12 +107,10 @@ Token* ParseNumber(void) {
}
memcpy(lexeme, &SourceCode[start], length);
*value = strtol(lexeme, NULL, base);
// Setting the base to zero means the function will pick the base.
*value = strtol(lexeme, NULL, 0);
if (base == 10) return CreateToken(lexeme, value, Line, NUMBER);
return CreateToken(lexeme, value, Line, HEX);
return CreateToken(lexeme, value, Line, NUMBER);
}
Token* ParseDirective(void) {
+18
View File
@@ -1,5 +1,7 @@
#include "../includes/token.h"
TokenClass GetTokenClass(TokenType);
Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) {
Token* token = calloc(1, sizeof(Token));
@@ -12,10 +14,26 @@ Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) {
token->line = lineNumber;
token->lexeme = lexeme;
token->value = value;
token->token_class = GetTokenClass(type);
return token;
}
TokenClass GetTokenClass(TokenType type) {
if (type >= R1 && type <= R8) return Reg;
if (type >= COPY && type <= OUT) return Opcode;
switch(type) {
case STRING:
case IDENTIFIER:
case LABEL:
case NUMBER:
return Immediate16;
default:
return None;
}
}
void FreeToken(Token* token) {
if (!token) return;