Updated the way symbols are represented and how they are marked as resolved.
This commit is contained in:
+1
-1
@@ -11,6 +11,6 @@
|
|||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
#include "symbols_table.h"
|
#include "symbols_table.h"
|
||||||
|
|
||||||
SymbolTable* ParseTokens(List* tokens);
|
void ParseTokens(List* tokens, SymbolTable** symbolsTable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -12,12 +12,23 @@
|
|||||||
|
|
||||||
#define SYMBOLSTABLE_DEFAULT_CAPACITY 128
|
#define SYMBOLSTABLE_DEFAULT_CAPACITY 128
|
||||||
|
|
||||||
typedef struct {
|
typedef enum {
|
||||||
|
RefUnknown,
|
||||||
|
RefLiteral,
|
||||||
|
RefExpression,
|
||||||
|
RefPointer
|
||||||
|
} ReferenceType;
|
||||||
|
|
||||||
|
typedef struct _symbol {
|
||||||
char* Name;
|
char* Name;
|
||||||
int Address;
|
int Address;
|
||||||
int Resolved;
|
|
||||||
int Length;
|
int Length;
|
||||||
Token* References;
|
union {
|
||||||
|
Token* Mnemonic;
|
||||||
|
struct _symbol* Symbol;
|
||||||
|
unsigned short Number;
|
||||||
|
} Value;
|
||||||
|
ReferenceType Type;
|
||||||
} Symbol;
|
} Symbol;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -28,8 +39,9 @@ typedef struct {
|
|||||||
|
|
||||||
SymbolTable* CreateSymbolTable(void);
|
SymbolTable* CreateSymbolTable(void);
|
||||||
int TryGetSymbol(char* name, SymbolTable* table, Symbol** outSymbol);
|
int TryGetSymbol(char* name, SymbolTable* table, Symbol** outSymbol);
|
||||||
Symbol* AddSymbolToTable(char* name, int address, int resolved, SymbolTable* table);
|
Symbol* AddSymbolToTable(char* name, int address, SymbolTable* table);
|
||||||
void FreeSymbolTable(SymbolTable* table);
|
void FreeSymbolTable(SymbolTable* table);
|
||||||
void FreeSymbol(Symbol* symbol);
|
void FreeSymbol(Symbol* symbol);
|
||||||
|
int SymbolResolved(Symbol* symbol);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
.db MAX_MEM 0xFFFF
|
.db MAX_MEM 0xFFFF
|
||||||
.db VIDEO_MEM 0xF37F
|
.db VIDEO_MEM 0xF37F
|
||||||
.db MAX_LENGTH 32;MAX_MEM - MAX_LENGTH
|
.db MAX_LENGTH MAX_MEM; - MAX_LENGTH
|
||||||
.db MSG "Hello, World!", 0
|
.db MSG "Hello, World!", 0
|
||||||
|
|
||||||
__start:
|
__start:
|
||||||
|
|||||||
+2
-2
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
const char* MagicStartName = "__start";
|
const char* MagicStartName = "__start";
|
||||||
List* LIST;
|
List* LIST;
|
||||||
SymbolTable* Symbols;
|
SymbolTable* Symbols = NULL;
|
||||||
|
|
||||||
unsigned char mem[128] = {0};
|
unsigned char mem[128] = {0};
|
||||||
void print(void);
|
void print(void);
|
||||||
@@ -31,7 +31,7 @@ int main(int argc, char* args[]) {
|
|||||||
|
|
||||||
LIST = GenerateTokenList(source_code);
|
LIST = GenerateTokenList(source_code);
|
||||||
|
|
||||||
Symbols = ParseTokens(LIST);
|
ParseTokens(LIST, &Symbols);
|
||||||
|
|
||||||
free(source_code);
|
free(source_code);
|
||||||
|
|
||||||
|
|||||||
+43
-33
@@ -21,7 +21,7 @@ int ParserAtEnd(void);
|
|||||||
|
|
||||||
void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options);
|
void ExpectPuncuation(TokenPunctuation punctuation, ExpectOptions options);
|
||||||
void ExpectRegister(void);
|
void ExpectRegister(void);
|
||||||
Symbol* ExpectIdentifier(int resolved, ExpectOptions options);
|
Symbol* ExpectIdentifier(ExpectOptions options, int expectUnresolved);
|
||||||
void ExpectCharacterClass(Symbol* symbol);
|
void ExpectCharacterClass(Symbol* symbol);
|
||||||
void ExpectLineEndOrFileEnd(ExpectOptions options);
|
void ExpectLineEndOrFileEnd(ExpectOptions options);
|
||||||
|
|
||||||
@@ -30,12 +30,15 @@ SymbolTable* SymbolsTable;
|
|||||||
//int HeapSize = 0;
|
//int HeapSize = 0;
|
||||||
int PC = 0;
|
int PC = 0;
|
||||||
|
|
||||||
SymbolTable* ParseTokens(List* tokens) {
|
void ParseTokens(List* tokens, SymbolTable** symbols) {
|
||||||
if (!tokens) return NULL;
|
if (!tokens) return;
|
||||||
|
if (!symbols) return;
|
||||||
|
|
||||||
TokensList = tokens;
|
TokensList = tokens;
|
||||||
|
|
||||||
SymbolsTable = CreateSymbolTable();
|
if (!*symbols) *symbols = CreateSymbolTable();
|
||||||
|
|
||||||
|
SymbolsTable = *symbols;
|
||||||
|
|
||||||
while(!ParserAtEnd()) {
|
while(!ParserAtEnd()) {
|
||||||
Token* t = PeekToken();
|
Token* t = PeekToken();
|
||||||
@@ -53,23 +56,23 @@ SymbolTable* ParseTokens(List* tokens) {
|
|||||||
Symbol* symbol;
|
Symbol* symbol;
|
||||||
int found = TryGetSymbol(t->Lemexe, SymbolsTable, &symbol);
|
int found = TryGetSymbol(t->Lemexe, SymbolsTable, &symbol);
|
||||||
|
|
||||||
if (found && symbol->Resolved) {
|
if (found && SymbolResolved(symbol)) {
|
||||||
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe);
|
fprintf(stderr, "[Error] Line %d: Redefinition of symbol '%s'\n", t->LineNumber, t->Lemexe);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) symbol = AddSymbolToTable(t->Lemexe, PC, 1, SymbolsTable);
|
if (!found) symbol = AddSymbolToTable(t->Lemexe, PC, SymbolsTable);
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
symbol->Address = PC;
|
symbol->Address = PC;
|
||||||
symbol->Resolved = 1;
|
symbol->Type = RefPointer;
|
||||||
}
|
//}
|
||||||
|
|
||||||
RemoveCurrentToken(); //label
|
RemoveCurrentToken(); //label
|
||||||
|
|
||||||
ExpectLineEndOrFileEnd(RemoveExpected);
|
ExpectLineEndOrFileEnd(RemoveExpected);
|
||||||
|
|
||||||
symbol->References = ExpectMnemonic();
|
symbol->Value.Mnemonic = ExpectMnemonic();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -81,8 +84,6 @@ SymbolTable* ParseTokens(List* tokens) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrintSymbols();
|
PrintSymbols();
|
||||||
|
|
||||||
return SymbolsTable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleAssemblerDirective() {
|
void HandleAssemblerDirective() {
|
||||||
@@ -93,10 +94,12 @@ void HandleAssemblerDirective() {
|
|||||||
{
|
{
|
||||||
RemoveCurrentToken();
|
RemoveCurrentToken();
|
||||||
|
|
||||||
Symbol* symbol = ExpectIdentifier(1, RemoveExpected);
|
Symbol* symbol = ExpectIdentifier(RemoveExpected, 1);
|
||||||
|
|
||||||
if (PeekToken()->Class == CharacterClass) {
|
if (PeekToken()->Class == CharacterClass) {
|
||||||
ExpectCharacterClass(symbol);
|
ExpectCharacterClass(symbol);
|
||||||
|
|
||||||
|
symbol->Type = RefLiteral;
|
||||||
}
|
}
|
||||||
else if (PeekToken()->Class == NumberClass) {
|
else if (PeekToken()->Class == NumberClass) {
|
||||||
symbol->Length = 2;
|
symbol->Length = 2;
|
||||||
@@ -104,11 +107,17 @@ void HandleAssemblerDirective() {
|
|||||||
RemoveCurrentToken(); //Clear the number token.
|
RemoveCurrentToken(); //Clear the number token.
|
||||||
|
|
||||||
ExpectLineEndOrFileEnd(RemoveExpected);
|
ExpectLineEndOrFileEnd(RemoveExpected);
|
||||||
|
|
||||||
|
symbol->Type = RefLiteral;
|
||||||
}
|
}
|
||||||
else if (PeekToken()->Class == IdentifierClass) {
|
else if (PeekToken()->Class == IdentifierClass) {
|
||||||
symbol = ExpectIdentifier(0, RemoveExpected);
|
symbol->Type = RefExpression;
|
||||||
|
|
||||||
|
symbol = ExpectIdentifier(RemoveExpected, 0);
|
||||||
symbol->Length = 2;
|
symbol->Length = 2;
|
||||||
|
|
||||||
|
//TODO: This needs to be expanded to handle expressions, a symbol to symbol reg is not allowed.
|
||||||
|
|
||||||
ExpectLineEndOrFileEnd(RemoveExpected);
|
ExpectLineEndOrFileEnd(RemoveExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +196,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
opcode->Lemexe = isByte ? "copyab" : "copya";
|
opcode->Lemexe = isByte ? "copyab" : "copya";
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ExpectPuncuation(LBracket, RemoveExpected);
|
ExpectPuncuation(LBracket, RemoveExpected);
|
||||||
@@ -245,7 +254,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
opcode->Value.Mnemonic = CMPI;
|
opcode->Value.Mnemonic = CMPI;
|
||||||
opcode->Lemexe = "CMPI";
|
opcode->Lemexe = "CMPI";
|
||||||
|
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
|
|
||||||
PC += 2;
|
PC += 2;
|
||||||
}
|
}
|
||||||
@@ -302,7 +311,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
Token* arg = PeekToken();
|
Token* arg = PeekToken();
|
||||||
|
|
||||||
if (arg->Class & IdentifierClass) {
|
if (arg->Class & IdentifierClass) {
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
|
|
||||||
opcode->Value.Mnemonic = JMP;
|
opcode->Value.Mnemonic = JMP;
|
||||||
opcode->Lemexe = "jmp";
|
opcode->Lemexe = "jmp";
|
||||||
@@ -326,7 +335,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
{
|
{
|
||||||
PC++;
|
PC++;
|
||||||
|
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
|
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
@@ -338,7 +347,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
{
|
{
|
||||||
PC++;
|
PC++;
|
||||||
|
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
|
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
@@ -350,7 +359,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
{
|
{
|
||||||
PC++;
|
PC++;
|
||||||
|
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
|
|
||||||
PC += 2;
|
PC += 2;
|
||||||
|
|
||||||
@@ -370,7 +379,7 @@ Token* ExpectMnemonic(void) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpectIdentifier(0, ForwardParser);
|
ExpectIdentifier(ForwardParser, 0);
|
||||||
|
|
||||||
PC += 2;
|
PC += 2;
|
||||||
}
|
}
|
||||||
@@ -407,7 +416,7 @@ void ExpectRegister() {
|
|||||||
AdvanceParser();
|
AdvanceParser();
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* ExpectIdentifier(int resolved, ExpectOptions options) {
|
Symbol* ExpectIdentifier(ExpectOptions options, int expectUnresolved) {
|
||||||
Token* token = PeekToken();
|
Token* token = PeekToken();
|
||||||
|
|
||||||
if (token->Class != IdentifierClass) {
|
if (token->Class != IdentifierClass) {
|
||||||
@@ -419,17 +428,18 @@ Symbol* ExpectIdentifier(int resolved, ExpectOptions options) {
|
|||||||
|
|
||||||
int found = TryGetSymbol(token->Lemexe, SymbolsTable, &symbol);
|
int found = TryGetSymbol(token->Lemexe, SymbolsTable, &symbol);
|
||||||
|
|
||||||
if (found && symbol->Resolved && resolved) {
|
if (found && SymbolResolved(symbol) && expectUnresolved) {
|
||||||
fprintf(stderr, "[Line %d] Redefinition of symbol '%s'.\n", token->LineNumber, token->Lemexe);
|
fprintf(stderr, "[Line %d] Redefinition of symbol '%s'.\n", token->LineNumber, token->Lemexe);
|
||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (!found) {
|
||||||
symbol->Resolved = resolved || symbol->Resolved;
|
//symbol->Resolved = resolved || symbol->Resolved(symbol);
|
||||||
}
|
symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
|
||||||
else {
|
|
||||||
symbol = AddSymbolToTable(token->Lemexe, PC, resolved, SymbolsTable);
|
|
||||||
}
|
}
|
||||||
|
// else {
|
||||||
|
// symbol = AddSymbolToTable(token->Lemexe, PC, SymbolsTable);
|
||||||
|
// }
|
||||||
|
|
||||||
if (options & RemoveExpected) RemoveCurrentToken();
|
if (options & RemoveExpected) RemoveCurrentToken();
|
||||||
if (options & ForwardParser) AdvanceParser();
|
if (options & ForwardParser) AdvanceParser();
|
||||||
@@ -494,11 +504,11 @@ void PrintSymbols(void) {
|
|||||||
for(int i = 0; i < SymbolsTable->Size; i++) {
|
for(int i = 0; i < SymbolsTable->Size; i++) {
|
||||||
Symbol* symbol = SymbolsTable->Symbols[i];
|
Symbol* symbol = SymbolsTable->Symbols[i];
|
||||||
|
|
||||||
if (!symbol->References)
|
if (symbol->Type != RefPointer)
|
||||||
printf("[%s] %s [%d] [Width: %d]", symbol->Resolved == 0 ? "Unresolved" : "Resolved", symbol->Name, symbol->Address, symbol->Length);
|
printf("[%s] %s [%d] [Width: %d] <%d>", SymbolResolved(symbol) == 0 ? "Unresolved" : "Resolved", symbol->Name, symbol->Address, symbol->Length, symbol->Type);
|
||||||
else {
|
else {
|
||||||
GetMnemonicText(symbol->References->Value.Mnemonic, mn);
|
GetMnemonicText(symbol->Value.Mnemonic->Value.Mnemonic, mn);
|
||||||
printf("[%s] %s [%d] [Width: %d] -> [%s] Line %d", symbol->Resolved == 0 ? "Unresolved" : "Resolved", symbol->Name, symbol->Address, symbol->Length, mn, symbol->References->LineNumber);
|
printf("[%s] %s [%d] [Width: %d] -> [%s] Line %d <%d>", SymbolResolved(symbol) == 0 ? "Unresolved" : "Resolved", symbol->Name, symbol->Address, symbol->Length, mn, symbol->Value.Mnemonic->LineNumber, symbol->Type);
|
||||||
|
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|||||||
+19
-4
@@ -3,6 +3,21 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
int SymbolResolved(Symbol* symbol) {
|
||||||
|
if (!symbol) return 0;
|
||||||
|
|
||||||
|
switch (symbol->Type) {
|
||||||
|
case RefLiteral:
|
||||||
|
return 1;
|
||||||
|
case RefExpression:
|
||||||
|
return 0;
|
||||||
|
case RefPointer:
|
||||||
|
return symbol->Value.Mnemonic != 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SymbolTable* CreateSymbolTable(void){
|
SymbolTable* CreateSymbolTable(void){
|
||||||
SymbolTable* table = calloc(1, sizeof(SymbolTable));
|
SymbolTable* table = calloc(1, sizeof(SymbolTable));
|
||||||
|
|
||||||
@@ -25,7 +40,7 @@ SymbolTable* CreateSymbolTable(void){
|
|||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* CreateSymbol(char* name, int address, int resolved) {
|
Symbol* CreateSymbol(char* name, int address) {
|
||||||
Symbol* symbol = calloc(1, sizeof(Symbol));
|
Symbol* symbol = calloc(1, sizeof(Symbol));
|
||||||
|
|
||||||
if (!symbol) {
|
if (!symbol) {
|
||||||
@@ -36,7 +51,7 @@ Symbol* CreateSymbol(char* name, int address, int resolved) {
|
|||||||
|
|
||||||
symbol->Address = address;
|
symbol->Address = address;
|
||||||
symbol->Name = name;
|
symbol->Name = name;
|
||||||
symbol->Resolved = resolved;
|
symbol->Type = RefUnknown;
|
||||||
|
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
@@ -56,7 +71,7 @@ int TryGetSymbol(char* name, SymbolTable* table, Symbol** outSymbol) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* AddSymbolToTable(char* name, int address, int resolved, SymbolTable* table) {
|
Symbol* AddSymbolToTable(char* name, int address, SymbolTable* table) {
|
||||||
//if (!name || !value || !table || length == 0) return NULL;
|
//if (!name || !value || !table || length == 0) return NULL;
|
||||||
|
|
||||||
for(int i = 0; i < table->Size; i++) {
|
for(int i = 0; i < table->Size; i++) {
|
||||||
@@ -80,7 +95,7 @@ Symbol* AddSymbolToTable(char* name, int address, int resolved, SymbolTable* tab
|
|||||||
table->Symbols = newBlock;
|
table->Symbols = newBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* symbol = CreateSymbol(name, address, resolved);
|
Symbol* symbol = CreateSymbol(name, address);
|
||||||
|
|
||||||
table->Symbols[table->Size] = symbol;
|
table->Symbols[table->Size] = symbol;
|
||||||
table->Size++;
|
table->Size++;
|
||||||
|
|||||||
Reference in New Issue
Block a user