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:
+5
-11
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user