Added some simple symbol handling to the Parser.
This commit is contained in:
+3
-5
@@ -1,12 +1,10 @@
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "list.h"
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
int address;
|
||||
} Symbol;
|
||||
#include "token.h"
|
||||
|
||||
void ParseTokens(List*);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.org 0x100
|
||||
.db msg "Hello, world!", 0
|
||||
.db more_stuff "And yet another string!", 0
|
||||
|
||||
copy r1, msg
|
||||
copy r2, 0
|
||||
|
||||
+8
-8
@@ -7,8 +7,6 @@
|
||||
#include "../includes/futil.h"
|
||||
#include "../includes/scanner.h"
|
||||
|
||||
List* get_strings(const char*);
|
||||
|
||||
int main(int argc, char* args[]) {
|
||||
if (argc == 1) {
|
||||
printf("Usage: assm <file1.asm>\n");
|
||||
@@ -22,13 +20,15 @@ int main(int argc, char* args[]) {
|
||||
|
||||
List* list = GenerateTokenList(source_code);
|
||||
|
||||
for(int i = 0; i < list->size; i++) {
|
||||
Token* t = (Token*) list->content[i];
|
||||
// for(int i = 0; i < list->size; i++) {
|
||||
// Token* t = (Token*) list->content[i];
|
||||
|
||||
printf("[%i] '%s'", t->type, t->lexeme);
|
||||
if (t->type == NUMBER || t->type == HEX) printf(" NUM: %ld", *((long *) t->value));
|
||||
printf("\n");
|
||||
}
|
||||
// printf("[%i] '%s'", t->type, t->lexeme);
|
||||
// if (t->type == LABEL) printf("*");
|
||||
// printf("\n");
|
||||
// }
|
||||
|
||||
ParseTokens(list);
|
||||
|
||||
free(source_code);
|
||||
}
|
||||
+73
-39
@@ -1,55 +1,89 @@
|
||||
#include "../includes/parser.h"
|
||||
#include "../includes/token.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//static List* SymbolsTable;
|
||||
//static unsigned int program_counter = 0;
|
||||
void ProcessDirective(List*);
|
||||
void ProcessVariableDeclaration(List*);
|
||||
typedef struct {
|
||||
Token* token;
|
||||
int address;
|
||||
} Symbol;
|
||||
|
||||
Symbol* CreateSymbol(Token*, int);
|
||||
void AddSymbol(Token*);
|
||||
void PrintSymbols(void);
|
||||
Token* GetSymbol(char*);
|
||||
List* SymbolsTable;
|
||||
unsigned int ProgramCounter = 0;
|
||||
|
||||
void ParseTokens(List* tokens) {
|
||||
// for(int i = 0; i < tokens->size; i++) {
|
||||
// if (((Token *) tokens->content[i])->type == TK_Directive){
|
||||
// ProcessDirective(tokens);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
SymbolsTable = CreateList();
|
||||
|
||||
void ProcessDirective(List* tokens) {
|
||||
if (tokens->size < 2) {
|
||||
printf("Directives failed\n");
|
||||
return;
|
||||
}
|
||||
for(int i = 0; i < tokens->size; i++){
|
||||
Token* t = tokens->content[i];
|
||||
|
||||
Token* directive = (Token *) tokens->content[0];
|
||||
|
||||
if (strcmp(".org", directive->value) == 0) {
|
||||
Token* address_start = (Token*) tokens->content[1];
|
||||
if (address_start->type == NUMBER) {
|
||||
long address = strtol(address_start->value, NULL, 10);
|
||||
printf("Address starting at '%ld'\n", address);
|
||||
}
|
||||
else if (address_start->type == HEX) {
|
||||
long address = strtol(address_start->value, NULL, 16);
|
||||
printf("Setting address to '%ld'\n", address);
|
||||
switch(t->type) {
|
||||
case IDENTIFIER:
|
||||
case LABEL:
|
||||
AddSymbol(t);
|
||||
break;
|
||||
case STRING:
|
||||
ProgramCounter += strlen(t->lexeme);
|
||||
break;
|
||||
case NUMBER:
|
||||
case HEX:
|
||||
if ((long) t->value < 256) ProgramCounter += 1;
|
||||
else ProgramCounter += 2;
|
||||
break;
|
||||
default:
|
||||
if (t->type > ORG) ProgramCounter += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(".db", directive->value) == 0) {
|
||||
ProcessVariableDeclaration(tokens);
|
||||
}
|
||||
PrintSymbols();
|
||||
DestroyList(SymbolsTable);
|
||||
printf("Program Counter: %d\n", ProgramCounter);
|
||||
}
|
||||
|
||||
void ProcessVariableDeclaration(List* tokens) {
|
||||
if (tokens->size < 3) {
|
||||
printf("Invalid variable delcaration\n");
|
||||
return;
|
||||
void PrintSymbols(void) {
|
||||
printf("-----SYMBOLS-----\n");
|
||||
for(int i = 0; i < SymbolsTable->size; i++) {
|
||||
Symbol* symbol = SymbolsTable->content[i];
|
||||
printf("[%#08X] %s\n", symbol->address, symbol->token->lexeme);
|
||||
}
|
||||
|
||||
Token* symbol_token = (Token*) tokens->content[1];
|
||||
Token* string_literal = (Token*) tokens->content[2];
|
||||
printf("-----SYMBOLS-----\n");
|
||||
}
|
||||
|
||||
printf("Found string literal.\n");
|
||||
printf("Name '%s' value: '%s'\n", symbol_token->lexeme, string_literal->lexeme);
|
||||
void AddSymbol(Token* token) {
|
||||
if (!token) return;
|
||||
if (token->type != IDENTIFIER && token->type != LABEL) return;
|
||||
|
||||
for(int i = 0; i < SymbolsTable->size; i++) {
|
||||
Symbol* s = SymbolsTable->content[i];
|
||||
|
||||
if (strcmp(s->token->lexeme, token->lexeme) == 0) return;
|
||||
}
|
||||
|
||||
Symbol* symbol = CreateSymbol(token, ProgramCounter);
|
||||
|
||||
AddListItem(symbol, sizeof(Symbol), SymbolsTable);
|
||||
}
|
||||
|
||||
Token* GetSymbol(char* name) {
|
||||
if (!name) return NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Symbol* CreateSymbol(Token* token, int offset) {
|
||||
Symbol* symbol = calloc(1, sizeof(Symbol));
|
||||
|
||||
if (!symbol) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
symbol->token = token;
|
||||
symbol->address = offset;
|
||||
|
||||
return symbol;
|
||||
}
|
||||
+5
-5
@@ -149,7 +149,6 @@ Token* ParseDirective(void) {
|
||||
|
||||
free(directive);
|
||||
|
||||
//Ignore the line
|
||||
IgnoreLine();
|
||||
|
||||
return NULL;
|
||||
@@ -164,9 +163,7 @@ Token* ParseString(void) {
|
||||
|
||||
int start = Position;
|
||||
|
||||
while(!ScannerAtEnd() && PeekScanner() != '"') {
|
||||
AdvanceScanner();
|
||||
}
|
||||
while(!ScannerAtEnd() && PeekScanner() != '"') AdvanceScanner();
|
||||
|
||||
int length = Position - start;
|
||||
|
||||
@@ -211,7 +208,10 @@ Token* ParseIdentifier(void) {
|
||||
|
||||
if (IsOpcode(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type);
|
||||
if (IsRegister(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type);
|
||||
if (lexeme[length - 1] == ':') return CreateToken(lexeme, lexeme, Line, LABEL);
|
||||
if (lexeme[length - 1] == ':') {
|
||||
lexeme[length - 1] = '\0'; //Bit hacky, but this makes the parser's job a bit easier.
|
||||
return CreateToken(lexeme, lexeme, Line, LABEL);
|
||||
}
|
||||
|
||||
return CreateToken(lexeme, lexeme, Line, IDENTIFIER);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user