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:
+33
-17
@@ -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
@@ -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*);
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
Token* token = CreateToken(Line, NumberClass);
|
||||||
|
|
||||||
return CreateToken(lexeme, value, Line, NUMBER);
|
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, ®)) {
|
||||||
|
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
@@ -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);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user