This feels like a trainwreck but eh. Changed the way the opcodes are managed. Hopefully this is the right direction when I add support for multiple ASM files.
This commit is contained in:
+2
-1
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#define OPCODECOUNT 13
|
#define OPCODECOUNT 13
|
||||||
#define REGISTERCOUNT 8
|
#define REGISTERCOUNT 8
|
||||||
|
//const unsigned char COPYADDRESSMASK = 0x80;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* lexeme;
|
char* lexeme;
|
||||||
@@ -25,6 +26,6 @@ extern Register registers[REGISTERCOUNT];
|
|||||||
int IsOpcode(const char*, TokenType*);
|
int IsOpcode(const char*, TokenType*);
|
||||||
int IsRegister(const char*, TokenType*);
|
int IsRegister(const char*, TokenType*);
|
||||||
const Instruction* GetOpcodeDetails(TokenType);
|
const Instruction* GetOpcodeDetails(TokenType);
|
||||||
unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType);
|
unsigned char GetInstructionMask(TokenType type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+30
-1
@@ -1,6 +1,7 @@
|
|||||||
#ifndef PARSER_H
|
#ifndef PARSER_H
|
||||||
#define PARSER_H
|
#define PARSER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
@@ -9,6 +10,34 @@
|
|||||||
|
|
||||||
#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF
|
#define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF
|
||||||
|
|
||||||
unsigned char* ParseTokens(List*);
|
typedef struct {
|
||||||
|
Token* token;
|
||||||
|
//unsigned char terminatingByte;
|
||||||
|
int address;
|
||||||
|
int resolved;
|
||||||
|
} Symbol;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TokenType Mnemonic;
|
||||||
|
TokenClass ParameterOneType;
|
||||||
|
TokenClass ParameterTwoType;
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint16_t Constant;
|
||||||
|
Symbol* Address;
|
||||||
|
} ParameterOne;
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint16_t Constant;
|
||||||
|
Symbol* Address;
|
||||||
|
} ParameterTwo;
|
||||||
|
} IROpcode;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
List* Opcodes;
|
||||||
|
List* SymbolsTable;
|
||||||
|
} IRState;
|
||||||
|
|
||||||
|
IRState* ParseTokens(List*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+1
-1
@@ -26,7 +26,7 @@ typedef enum {
|
|||||||
LineEnd,
|
LineEnd,
|
||||||
//Keywords
|
//Keywords
|
||||||
DB, ORG,
|
DB, ORG,
|
||||||
//Opcodes
|
//Mnemonics
|
||||||
COPY, ADD, SUB, JZ, INT, YLD, RET,
|
COPY, ADD, SUB, JZ, INT, YLD, RET,
|
||||||
CMP, NOP, JMP, CALL, IN, OUT,
|
CMP, NOP, JMP, CALL, IN, OUT,
|
||||||
//Registers
|
//Registers
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@
|
|||||||
.db msg "Hello, world!", 0
|
.db msg "Hello, world!", 0
|
||||||
.db more_stuff "AA", 0
|
.db more_stuff "AA", 0
|
||||||
copy r7, msg ; //
|
copy r7, msg ; //
|
||||||
cmp r8, msg ;1000 1111
|
;cmp r8, msg ;1000 1111
|
||||||
add r4, 0x42
|
;add r4, 0x42
|
||||||
sub r1, r8
|
;sub r1, r8
|
||||||
int 20
|
int 20
|
||||||
jz 45
|
jz 45
|
||||||
jmp msg
|
jmp msg
|
||||||
|
|||||||
+7
-4
@@ -36,14 +36,17 @@ int main(int argc, char* args[]) {
|
|||||||
// if (t->type == LABEL) printf("* ");
|
// if (t->type == LABEL) printf("* ");
|
||||||
// }
|
// }
|
||||||
|
|
||||||
unsigned char* image = ParseTokens(list);
|
IRState* image = ParseTokens(list);
|
||||||
//Disassemble(image);
|
//Disassemble(image);
|
||||||
|
for(int i = 0; i < image->Opcodes->size; i++) {
|
||||||
|
printf("%d\n", ((IROpcode*) image->Opcodes->content[i])->Mnemonic);
|
||||||
|
}
|
||||||
|
|
||||||
FILE* program = fopen("program.bin", "w+b");
|
//FILE* program = fopen("program.bin", "w+b");
|
||||||
|
|
||||||
fwrite(image, 1, image[2] + image[3], program);
|
//fwrite(image, 1, image[2] + image[3], program);
|
||||||
|
|
||||||
fclose(program);
|
//fclose(program);
|
||||||
|
|
||||||
free(source_code);
|
free(source_code);
|
||||||
}
|
}
|
||||||
+2
-4
@@ -18,12 +18,10 @@ Instruction instructions[OPCODECOUNT] = {
|
|||||||
{ "call", CALL, Address, None}
|
{ "call", CALL, Address, None}
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned char GetInstructionMask(TokenType type, TokenClass parameterOneType) {
|
unsigned char GetInstructionMask(TokenType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case COPY:
|
case COPY:
|
||||||
if (parameterOneType & Reg) return 0x20; //0b00100000;
|
return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address
|
||||||
|
|
||||||
return 0xA0;//0b10100000;
|
|
||||||
case ADD:
|
case ADD:
|
||||||
return 0x40;//0b01000000;
|
return 0x40;//0b01000000;
|
||||||
case SUB:
|
case SUB:
|
||||||
|
|||||||
+184
-114
@@ -4,24 +4,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Token* token;
|
|
||||||
int address;
|
|
||||||
} Symbol;
|
|
||||||
|
|
||||||
struct intr {
|
struct intr {
|
||||||
TokenType struction;
|
TokenType struction;
|
||||||
unsigned int parameter1;
|
unsigned int parameter1;
|
||||||
unsigned int parameter2;
|
unsigned int parameter2;
|
||||||
};
|
};
|
||||||
|
|
||||||
Symbol* CreateSymbol(Token* token, int address);
|
Symbol* CreateSymbol(Token* token, int address, int resolved);
|
||||||
const List* TokensList;
|
const List* TokensList;
|
||||||
int CurrentToken = 0;
|
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)
|
||||||
|
|
||||||
void AddSymbol(Token*, int);
|
IROpcode* CreateIROpcode(TokenType mnemonic);
|
||||||
|
Symbol* AddSymbol(Token* token, int address, int resolved);
|
||||||
void PrintSymbols(void);
|
void PrintSymbols(void);
|
||||||
void HandleOperation(void);
|
void HandleOperation(void);
|
||||||
void HandleAssemblerDirective(void);
|
void HandleAssemblerDirective(void);
|
||||||
@@ -30,22 +26,24 @@ Token* PeekToken(void);
|
|||||||
int ParserAtEnd(void);
|
int ParserAtEnd(void);
|
||||||
int Expect(int, ...);
|
int Expect(int, ...);
|
||||||
int ExpectTokenClass(int, ...);
|
int ExpectTokenClass(int, ...);
|
||||||
const Symbol* GetSymbol(char*);
|
Symbol* GetSymbol(char*);
|
||||||
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;
|
||||||
|
|
||||||
unsigned char* ParseTokens(List* tokens) {
|
IRState* ParseTokens(List* tokens) {
|
||||||
if (!tokens) return NULL;
|
if (!tokens) return NULL;
|
||||||
|
|
||||||
memset(Memory, 0, sizeof(Memory));
|
// memset(Memory, 0, sizeof(Memory));
|
||||||
memset(Heap, 0, sizeof(Heap));
|
// memset(Heap, 0, sizeof(Heap));
|
||||||
|
|
||||||
TokensList = tokens;
|
TokensList = tokens;
|
||||||
|
|
||||||
SymbolsTable = CreateList();
|
MachineState.SymbolsTable = CreateList();
|
||||||
|
MachineState.Opcodes = CreateList();
|
||||||
|
|
||||||
while(!ParserAtEnd()) {
|
while(!ParserAtEnd()) {
|
||||||
Token* t = PeekToken();
|
Token* t = PeekToken();
|
||||||
@@ -60,7 +58,7 @@ unsigned char* ParseTokens(List* tokens) {
|
|||||||
case Address:
|
case Address:
|
||||||
if (t->type == LABEL) {
|
if (t->type == LABEL) {
|
||||||
printf("%s: \n", t->lexeme);
|
printf("%s: \n", t->lexeme);
|
||||||
AddSymbol(t, ProgramCounter);
|
AddSymbol(t, ProgramCounter, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -70,16 +68,16 @@ unsigned char* ParseTokens(List* tokens) {
|
|||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SymbolsTable->size > 0) PrintSymbols();
|
if (MachineState.SymbolsTable->size > 0) PrintSymbols();
|
||||||
|
|
||||||
DestroyList(SymbolsTable);
|
//DestroyList(SymbolsTable);
|
||||||
|
|
||||||
memcpy(&Heap[HeapTop], Memory, ProgramCounter);
|
//memcpy(&Heap[HeapTop], Memory, ProgramCounter);
|
||||||
int totalSize = HeapTop + ProgramCounter;
|
int totalSize = HeapTop + ProgramCounter;
|
||||||
Heap[0] = 2 >> HeapTop & 0xFF;
|
// Heap[0] = 2 >> HeapTop & 0xFF;
|
||||||
Heap[1] = HeapTop & 0xFF;
|
// Heap[1] = HeapTop & 0xFF;
|
||||||
Heap[2] = 2 >> totalSize & 0xFF;
|
// Heap[2] = 2 >> totalSize & 0xFF;
|
||||||
Heap[3] = totalSize & 0xFF;
|
// Heap[3] = totalSize & 0xFF;
|
||||||
|
|
||||||
// for(int i = 0; i < 33; i++) {
|
// for(int i = 0; i < 33; i++) {
|
||||||
// if (i != 0 && i % 3 == 0) printf("\n");
|
// if (i != 0 && i % 3 == 0) printf("\n");
|
||||||
@@ -89,7 +87,7 @@ unsigned char* ParseTokens(List* tokens) {
|
|||||||
// printf("Program Counter: %d\n", ProgramCounter);
|
// printf("Program Counter: %d\n", ProgramCounter);
|
||||||
// printf("Heap Top: %#06X\n", HeapTop);
|
// printf("Heap Top: %#06X\n", HeapTop);
|
||||||
|
|
||||||
return Heap;
|
return &MachineState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleAssemblerDirective(void) {
|
void HandleAssemblerDirective(void) {
|
||||||
@@ -104,7 +102,7 @@ void HandleAssemblerDirective(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddSymbol(identifier, HeapTop);
|
Symbol* symbol = AddSymbol(identifier, HeapTop, 1);
|
||||||
|
|
||||||
identifier = PeekToken();
|
identifier = PeekToken();
|
||||||
|
|
||||||
@@ -112,10 +110,10 @@ void HandleAssemblerDirective(void) {
|
|||||||
case STRING:
|
case STRING:
|
||||||
//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++) {
|
||||||
//Memory[ProgramCounter + i] = PeekToken()->lexeme[i];
|
// //Memory[ProgramCounter + i] = PeekToken()->lexeme[i];
|
||||||
Heap[HeapTop + i] = identifier->lexeme[i];
|
// Heap[HeapTop + i] = identifier->lexeme[i];
|
||||||
}
|
// }
|
||||||
|
|
||||||
//ProgramCounter += strlen(PeekToken()->lexeme);
|
//ProgramCounter += strlen(PeekToken()->lexeme);
|
||||||
HeapTop += strlen(identifier->lexeme);
|
HeapTop += strlen(identifier->lexeme);
|
||||||
@@ -130,10 +128,11 @@ void HandleAssemblerDirective(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//Add the NULL byte.
|
//Hideous...
|
||||||
//Memory[ProgramCounter] = '\0';
|
int oldLength = strlen(identifier->lexeme);
|
||||||
Heap[HeapTop] = '\0';
|
identifier->lexeme = realloc(identifier->lexeme, oldLength + 2);
|
||||||
//ProgramCounter++;
|
identifier->value = identifier->lexeme;
|
||||||
|
identifier->lexeme[oldLength + 1] = '\0';//*PeekToken()->lexeme & 0x0F;
|
||||||
HeapTop++;
|
HeapTop++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -147,18 +146,32 @@ void HandleAssemblerDirective(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) {
|
void HandleRegisterBasedOpcode(unsigned char mask) {
|
||||||
Memory[ProgramCounter] = mask;
|
//Memory[ProgramCounter] = mask;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
const Token* token = PeekToken();
|
Token* token = PeekToken();
|
||||||
|
|
||||||
|
IROpcode* opcode = CreateIROpcode(token->type);
|
||||||
|
|
||||||
|
AdvanceParser();
|
||||||
|
|
||||||
|
token = PeekToken();
|
||||||
|
|
||||||
if (token->token_class == Reg) {
|
if (token->token_class == Reg) {
|
||||||
Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07;
|
//Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07;
|
||||||
|
opcode->ParameterOneType = Reg;
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
}
|
}
|
||||||
|
else if (token->token_class == Address && token->type == COPY) {
|
||||||
|
opcode->ParameterOneType = Address;
|
||||||
|
|
||||||
|
Symbol* symbol = GetSymbol(token->lexeme);
|
||||||
|
|
||||||
|
if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 0, 0);
|
||||||
|
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->line);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -167,39 +180,47 @@ void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) {
|
|||||||
token = PeekToken();
|
token = PeekToken();
|
||||||
|
|
||||||
if (!Expect(1, COMMA)) {
|
if (!Expect(1, COMMA)) {
|
||||||
fprintf(stderr, "[Error] Expected command one line %d.\n", token->line);
|
fprintf(stderr, "[Error] Expected comma on line %d.\n", token->line);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
token = PeekToken();
|
token = PeekToken();
|
||||||
|
|
||||||
if (token->type == IDENTIFIER || token->type == LABEL) {
|
if (token->type == IDENTIFIER || token->type == LABEL) {
|
||||||
const Symbol* symbol = GetSymbol(token->lexeme);
|
opcode->ParameterTwoType = Address;
|
||||||
|
Symbol* symbol = GetSymbol(token->lexeme);
|
||||||
|
|
||||||
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);
|
||||||
exit(1);
|
// exit(1);
|
||||||
}
|
// }
|
||||||
|
if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 0, 0);//CreateSymbol(token, 0, 0);
|
||||||
|
else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved);
|
||||||
|
|
||||||
Memory[ProgramCounter - 1] |= 0x10;//0b00010000;
|
// Memory[ProgramCounter - 1] |= 0x10;//0b00010000;
|
||||||
|
|
||||||
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
|
// Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
|
||||||
Memory[ProgramCounter + 1] = symbol->address & 0xFF;
|
// Memory[ProgramCounter + 1] = symbol->address & 0xFF;
|
||||||
|
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
}
|
}
|
||||||
else if (token->type == NUMBER) {
|
else if (token->type == NUMBER) {
|
||||||
Memory[ProgramCounter - 1] |= 0x08; //0b00001000;
|
opcode->ParameterTwoType = Constant;
|
||||||
|
|
||||||
int* value = PeekToken()->value;
|
opcode->ParameterTwo.Constant = *(int*)PeekToken()->value;
|
||||||
|
// Memory[ProgramCounter - 1] |= 0x08; //0b00001000;
|
||||||
|
|
||||||
Memory[ProgramCounter] = 2 >> *value & 0xFF;
|
// int* value = PeekToken()->value;
|
||||||
Memory[ProgramCounter + 1] = *value & 0xFF;
|
|
||||||
|
// Memory[ProgramCounter] = 2 >> *value & 0xFF;
|
||||||
|
// Memory[ProgramCounter + 1] = *value & 0xFF;
|
||||||
|
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
}
|
}
|
||||||
else if (token->token_class == Reg) {
|
else if (token->token_class == Reg) {
|
||||||
Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07;
|
opcode->ParameterTwoType = Reg;
|
||||||
|
opcode->ParameterTwo.Constant = (PeekToken()->type - R1) &0x07;
|
||||||
|
//Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07;
|
||||||
|
|
||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
|
|
||||||
@@ -212,49 +233,64 @@ void HandleRegisterBasedOpcode(unsigned char instruction, unsigned char mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProgramCounter += 2;
|
ProgramCounter += 2;
|
||||||
|
|
||||||
|
AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleOperation(void) {
|
void HandleOperation(void) {
|
||||||
const Instruction* inst = GetOpcodeDetails(PeekToken()->type);
|
Token* token = PeekToken();
|
||||||
|
//const Instruction* inst = GetOpcodeDetails(opcode->type);
|
||||||
const unsigned char registerBasedOpcodeMask = 0xE0;
|
const unsigned char registerBasedOpcodeMask = 0xE0;
|
||||||
|
|
||||||
if (!inst) return;
|
//if (!inst) return;
|
||||||
|
|
||||||
AdvanceParser();
|
// AdvanceParser();
|
||||||
|
|
||||||
unsigned char mask = GetInstructionMask(inst->op, inst->parameter_one);
|
unsigned char mask = GetInstructionMask(token->type);
|
||||||
|
|
||||||
if (mask & registerBasedOpcodeMask) {
|
if (mask & registerBasedOpcodeMask) {
|
||||||
HandleRegisterBasedOpcode(Memory[ProgramCounter], mask);
|
HandleRegisterBasedOpcode(mask);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IROpcode* opcode = CreateIROpcode(token->type);
|
||||||
|
opcode->ParameterTwoType = None;
|
||||||
|
|
||||||
|
AdvanceParser();
|
||||||
|
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case 0: //NOP
|
case 0: //NOP
|
||||||
Memory[ProgramCounter] = 0x00;
|
//Memory[ProgramCounter] = 0x00;
|
||||||
|
opcode->ParameterOneType = None;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
return;
|
return;
|
||||||
case 1: //JZ
|
case 1: //JZ
|
||||||
Memory[ProgramCounter] = 0x01;
|
//Memory[ProgramCounter] = 0x01;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
||||||
const Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
||||||
|
opcode->ParameterOneType = Address;
|
||||||
|
|
||||||
if (!symbol) {
|
if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0);
|
||||||
fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme);
|
else opcode->ParameterOne.Address = symbol;
|
||||||
exit(1);
|
// if (!symbol) {
|
||||||
}
|
// fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme);
|
||||||
|
// exit(1);
|
||||||
|
// }
|
||||||
|
|
||||||
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()->type == NUMBER) {
|
||||||
int* value = PeekToken()->value;
|
opcode->ParameterOneType = Constant;
|
||||||
|
opcode->ParameterOne.Constant = *(int*)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])->line);
|
||||||
@@ -265,15 +301,17 @@ void HandleOperation(void) {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
case 2: //INT
|
case 2: //INT
|
||||||
Memory[ProgramCounter] = 0x02;
|
//Memory[ProgramCounter] = 0x02;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
if (PeekToken()->type == NUMBER) {
|
if (PeekToken()->type == NUMBER) {
|
||||||
int* value = PeekToken()->value;
|
// int* value = PeekToken()->value;
|
||||||
|
opcode->ParameterOneType = Constant;
|
||||||
|
opcode->ParameterOne.Constant = *(int*)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 Interrupt vector.\n", PeekToken()->line);
|
fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->line);
|
||||||
@@ -284,30 +322,34 @@ void HandleOperation(void) {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
case 3: //YLD
|
case 3: //YLD
|
||||||
Memory[ProgramCounter] = 0x03;
|
//Memory[ProgramCounter] = 0x03;
|
||||||
|
opcode->ParameterOneType = None;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
break;
|
break;
|
||||||
case 4: //RET
|
case 4: //RET
|
||||||
Memory[ProgramCounter] = 0x04;
|
//Memory[ProgramCounter] = 0x04;
|
||||||
|
opcode->ParameterOneType = None;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
break;
|
break;
|
||||||
case 5: //CALL
|
case 5: //CALL
|
||||||
Memory[ProgramCounter] = 0x05;
|
//Memory[ProgramCounter] = 0x05;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
||||||
const Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
||||||
|
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);
|
||||||
exit(1);
|
// exit(1);
|
||||||
}
|
// }
|
||||||
|
if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0);
|
||||||
Memory[ProgramCounter] = 2 >> symbol->address & 0xFF;
|
else opcode->ParameterOne.Address = symbol;
|
||||||
Memory[ProgramCounter + 1] = symbol->address & 0xFF;
|
//Memory[ProgramCounter] = 2 >> 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()->line);
|
||||||
@@ -317,20 +359,23 @@ void HandleOperation(void) {
|
|||||||
ProgramCounter += 2;
|
ProgramCounter += 2;
|
||||||
break;
|
break;
|
||||||
case 6: //JMP
|
case 6: //JMP
|
||||||
Memory[ProgramCounter] = 0x06;
|
//Memory[ProgramCounter] = 0x06;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) {
|
||||||
const Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
Symbol* symbol = GetSymbol(PeekToken()->lexeme);
|
||||||
|
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);
|
||||||
exit(1);
|
// exit(1);
|
||||||
}
|
// }
|
||||||
|
if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 0, 0);
|
||||||
|
else opcode->ParameterOne.Address = symbol;
|
||||||
|
|
||||||
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 {
|
else {
|
||||||
fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line);
|
fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line);
|
||||||
@@ -340,15 +385,17 @@ void HandleOperation(void) {
|
|||||||
ProgramCounter += 2;
|
ProgramCounter += 2;
|
||||||
break;
|
break;
|
||||||
case 7: //IN
|
case 7: //IN
|
||||||
Memory[ProgramCounter] = 0x07;
|
//Memory[ProgramCounter] = 0x07;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
if (PeekToken()->type == NUMBER) {
|
if (PeekToken()->type == NUMBER) {
|
||||||
int* value = PeekToken()->value;
|
opcode->ParameterOneType = Constant;
|
||||||
|
opcode->ParameterOne.Constant = *(int*)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()->line);
|
||||||
@@ -358,15 +405,17 @@ void HandleOperation(void) {
|
|||||||
ProgramCounter += 2;
|
ProgramCounter += 2;
|
||||||
break;
|
break;
|
||||||
case 8: //OUT
|
case 8: //OUT
|
||||||
Memory[ProgramCounter] = 0x08;
|
//Memory[ProgramCounter] = 0x08;
|
||||||
|
|
||||||
ProgramCounter++;
|
ProgramCounter++;
|
||||||
|
|
||||||
if (PeekToken()->type == NUMBER) {
|
if (PeekToken()->type == NUMBER) {
|
||||||
int* value = PeekToken()->value;
|
opcode->ParameterOneType = Constant;
|
||||||
|
opcode->ParameterOne.Constant = *(int*)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()->line);
|
||||||
@@ -377,6 +426,8 @@ void HandleOperation(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,33 +471,43 @@ int Expect(int count, ...) {
|
|||||||
|
|
||||||
void PrintSymbols(void) {
|
void PrintSymbols(void) {
|
||||||
printf("-----SYMBOLS-----\n");
|
printf("-----SYMBOLS-----\n");
|
||||||
for(int i = 0; i < SymbolsTable->size; i++) {
|
for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
|
||||||
Symbol* symbol = 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->lexeme);
|
||||||
}
|
}
|
||||||
printf("-----SYMBOLS-----\n");
|
printf("-----SYMBOLS-----\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddSymbol(Token* token, int address) {
|
Symbol* AddSymbol(Token* token, int address, int resolved) {
|
||||||
if (!token) return;
|
if (!token) return NULL;
|
||||||
if (token->type != IDENTIFIER && token->type != LABEL) return;
|
if (token->type != IDENTIFIER && token->type != LABEL) return NULL;
|
||||||
|
|
||||||
for(int i = 0; i < SymbolsTable->size; i++) {
|
for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
|
||||||
Symbol* s = SymbolsTable->content[i];
|
Symbol* s = MachineState.SymbolsTable->content[i];
|
||||||
|
|
||||||
if (strcmp(s->token->lexeme, token->lexeme) == 0) return;
|
if (strcmp(s->token->lexeme, token->lexeme) == 0) {
|
||||||
|
if (s->resolved) {
|
||||||
|
fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->line, token->lexeme);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
s->resolved = resolved;
|
||||||
|
s->address = address;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* symbol = CreateSymbol(token, address);
|
Symbol* symbol = CreateSymbol(token, address, resolved);
|
||||||
|
|
||||||
AddListItem(symbol, sizeof(Symbol), SymbolsTable);
|
AddListItem(symbol, sizeof(Symbol), MachineState.SymbolsTable);
|
||||||
|
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Symbol* GetSymbol(char* name) {
|
Symbol* GetSymbol(char* name) {
|
||||||
if (!name) return NULL;
|
if (!name) return NULL;
|
||||||
|
|
||||||
for(int i = 0; i < SymbolsTable->size; i++) {
|
for(int i = 0; i < MachineState.SymbolsTable->size; i++) {
|
||||||
const Symbol* s = SymbolsTable->content[i];
|
Symbol* s = MachineState.SymbolsTable->content[i];
|
||||||
|
|
||||||
if (strcmp(s->token->lexeme, name) == 0) return s;
|
if (strcmp(s->token->lexeme, name) == 0) return s;
|
||||||
}
|
}
|
||||||
@@ -454,17 +515,26 @@ const Symbol* GetSymbol(char* name) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* CreateSymbol(Token* token, int address) {
|
Symbol* CreateSymbol(Token* token, int address, int resolved) {
|
||||||
Symbol* symbol = calloc(1, sizeof(Symbol));
|
Symbol* symbol = calloc(1, sizeof(Symbol));
|
||||||
|
|
||||||
if (!symbol) return NULL;
|
if (!symbol) return NULL;
|
||||||
|
|
||||||
symbol->token = token;
|
symbol->token = token;
|
||||||
symbol->address = address;
|
symbol->address = address;
|
||||||
|
symbol->resolved = resolved;
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IROpcode* CreateIROpcode(TokenType mnemonic) {
|
||||||
|
IROpcode* opcode = calloc(1, sizeof(IROpcode));
|
||||||
|
|
||||||
|
opcode->Mnemonic = mnemonic;
|
||||||
|
|
||||||
|
return opcode;
|
||||||
|
}
|
||||||
|
|
||||||
void AdvanceParser(void) {
|
void AdvanceParser(void) {
|
||||||
if (ParserAtEnd()) return;
|
if (ParserAtEnd()) return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user