Added / started some infrastructure / boilerplate code.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
#include "../includes/dictionary.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DEFAULT_DICT_SIZE 64
|
||||
|
||||
struct _dictionary {
|
||||
int Capacity;
|
||||
int Size;
|
||||
KeyValPair** Pairs;
|
||||
};
|
||||
|
||||
struct _dictionary* DictionaryCreate(void) {
|
||||
struct _dictionary* dict = calloc(1, sizeof(Dictionary));
|
||||
dict->Pairs = calloc(sizeof(KeyValPair*), DEFAULT_DICT_SIZE);
|
||||
|
||||
dict->Capacity = DEFAULT_DICT_SIZE;
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
KeyValPair* KeyValPairCreate(const char* key, void* value) {
|
||||
KeyValPair* pair = calloc(1, sizeof(KeyValPair));
|
||||
|
||||
pair->Key = key;
|
||||
pair->Value = value;
|
||||
|
||||
return pair;
|
||||
}
|
||||
|
||||
int DictionaryAdd(struct _dictionary* dict, const char* key, void* value) {
|
||||
if (!dict) return 0;
|
||||
|
||||
if (dict->Size = dict->Capacity) {
|
||||
dict->Pairs = realloc(dict->Pairs, sizeof(KeyValPair*) * dict->Capacity * 2);
|
||||
}
|
||||
|
||||
dict->Pairs[dict->Size] = KeyValPairCreate(key, value);
|
||||
dict->Size++;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void* DictionaryGetValue(const struct _dictionary* dict, const char* key) {
|
||||
if (!dict) return NULL;
|
||||
|
||||
for(int i = 0; i < dict->Size; i++) {
|
||||
KeyValPair* pair = dict->Pairs[i];
|
||||
|
||||
if (strcmp(pair->Key, key) == 0) {
|
||||
return pair->Value;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
#include "../includes/futil.h"
|
||||
|
||||
int ReadAllString(const char* path, char** content_ptr, size_t* bytes_read) {
|
||||
if (!path || !content_ptr || !bytes_read) return 0;
|
||||
|
||||
FILE *file = fopen(path, "rb"); //Always open the file in binary mode.
|
||||
|
||||
if (!file) {
|
||||
fprintf(stderr, "Failed to open '%s'. %s.\n", path, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *content = NULL, *temp;
|
||||
size_t used = 0, capacity = 0, read = 0; //Always initialize stack allocated values to zero!
|
||||
|
||||
while(1) {
|
||||
if (used + FUTIL_READ_SIZE + 1 > capacity) {
|
||||
capacity = used + FUTIL_READ_SIZE + 1;
|
||||
|
||||
temp = realloc(content, capacity);
|
||||
|
||||
if (!temp) {
|
||||
fprintf(stderr, "Failed to realloc space for file contents. %s.\n", strerror(errno));
|
||||
free(content);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
content = temp;
|
||||
}
|
||||
|
||||
read = fread(content + used, 1, FUTIL_READ_SIZE, file);
|
||||
|
||||
if (read == 0) break;
|
||||
|
||||
used += read;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
//Shrink the buffer to fit just the contents of the buffer.
|
||||
temp = realloc(content, used + 1);
|
||||
|
||||
if (!temp) {
|
||||
fprintf(stderr, "Failed to realloc to only hold the file contents. %s.\n", strerror(errno));
|
||||
free(content);
|
||||
return 0;
|
||||
}
|
||||
|
||||
content = temp;
|
||||
content[used] = '\0';
|
||||
|
||||
*content_ptr = content;
|
||||
*bytes_read = used;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "../includes/keywords.h"
|
||||
|
||||
#define KEYWORD_COUNT 2
|
||||
|
||||
struct _keyword {
|
||||
char* Name;
|
||||
Keyword Word;
|
||||
};
|
||||
|
||||
struct _keyword keywords[KEYWORD_COUNT] = {
|
||||
{ "fn", FN },
|
||||
{ "org", ORG }
|
||||
}
|
||||
|
||||
int IsKeyword(const char* text, Keyword* keyword) {
|
||||
if (!text) return 0;
|
||||
|
||||
for(unsigned long i = 0; i < KEYWORD_COUNT; i++) {
|
||||
if (strcmp(keywords[i].Name, text) == 0) {
|
||||
if (keyword) *keyword = instructions[i].Word;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetKeywordText(Keyword keyword, char buffer[16]) {
|
||||
memset(buffer, '\0', sizeof(buffer));
|
||||
|
||||
for(int i = 0; i < KEYWORD_COUNT; i++) {
|
||||
if (instructions[i].Word == keyword) {
|
||||
strncpy(buffer, instructions[i].Name, sizeof(buffer));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-1
@@ -1,5 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include "../includes/futil.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
printf("Hello World\n");
|
||||
char* file;
|
||||
size_t count;
|
||||
|
||||
if (argc <= 1) {
|
||||
printf("Usage: assm <file.asm>\n");
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!ReadAllString(argv[1], &file, &count)) {
|
||||
printf("Failed to read file '%s'.", argv[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf(file);
|
||||
}
|
||||
+22
-25
@@ -3,52 +3,49 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define OPCODECOUNT 34
|
||||
#define OPCODE_COUNT 34
|
||||
|
||||
struct _instruction {
|
||||
char* Name;
|
||||
Mnemonic Mnemonic;
|
||||
};
|
||||
|
||||
struct _instruction instructions[OPCODECOUNT] = {
|
||||
{ "copya", COPYA },
|
||||
{ "copyab", COPYAB },
|
||||
{ "copyra", COPYRA },
|
||||
{ "copyrab", COPYRAB },
|
||||
{ "copyrara", COPYRARA },
|
||||
{ "copyrarab", COPYRARAB },
|
||||
{ "copy", COPY },
|
||||
{ "copyi", COPYI },
|
||||
{ "copyb", COPYB },
|
||||
{ "cmp", CMP },
|
||||
{ "cmpi", CMPI },
|
||||
struct _instruction instructions[OPCODE_COUNT] = {
|
||||
{ "add", ADD },
|
||||
{ "sub", SUB },
|
||||
{ "mul", MUL },
|
||||
{ "div", DIV },
|
||||
{ "mov", MOV },
|
||||
{ "and", AND },
|
||||
{ "xor", XOR },
|
||||
{ "or", OR },
|
||||
{ "xor", XOR },
|
||||
{ "not", NOT },
|
||||
{ "shr", SHR },
|
||||
{ "shl", SHL },
|
||||
{ "inc", INC },
|
||||
{ "dec", DEC },
|
||||
{ "push", PUSH },
|
||||
{ "pop", POP },
|
||||
{ "jmpi", JMPI },
|
||||
{ "jmp", JMP },
|
||||
{ "shr", SHR },
|
||||
{ "nop", NOP },
|
||||
{ "cmp", CMP },
|
||||
{ "jz", JZ },
|
||||
{ "jg", JG },
|
||||
{ "jl", JL },
|
||||
{ "nop", NOP },
|
||||
{ "outb", OUTB },
|
||||
{ "inb", INB },
|
||||
{ "hlt", HLT },
|
||||
{ "cli", CLI },
|
||||
{ "eni", ENI },
|
||||
{ "int", INT },
|
||||
{ "livt", LIVT },
|
||||
{ "pusha", PUSHA },
|
||||
{ "popa", POPA },
|
||||
{ "call", CALL },
|
||||
{ "ret", RET }
|
||||
//yld
|
||||
{ "ret", RET },
|
||||
{ "push", PUSH },
|
||||
{ "pop", POP }
|
||||
};
|
||||
|
||||
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]) {
|
||||
memset(buffer, '\0', 12);
|
||||
|
||||
for(int i = 0; i < OPCODECOUNT; i++) {
|
||||
for(int i = 0; i < OPCODE_COUNT; i++) {
|
||||
if (instructions[i].Mnemonic == mnemonic) {
|
||||
strncpy(buffer, instructions[i].Name, 11);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user