Added / started some infrastructure / boilerplate code.

This commit is contained in:
2024-10-30 00:28:11 -05:00
parent 8923a2006d
commit 2c85077031
12 changed files with 273 additions and 27 deletions
+4
View File
@@ -0,0 +1,4 @@
#ifndef AST_H
#define AST_H
#endif
+16
View File
@@ -0,0 +1,16 @@
#ifndef DICTIONARY_H
#define DICTIONARY_H
typedef struct {
const char* Key;
void* Value;
} KeyValPair;
typedef struct _dictionary Dictionary;
Dictionary* DictionaryCreate(void);
KeyValPair* KeyValPairCreate(const char* key, void* value);
int DictionaryAdd(Dictionary* dict, const char* key, void* value);
void* DictionaryGetValue(const Dictionary* dict, const char* key);
#endif
+15
View File
@@ -0,0 +1,15 @@
#ifndef FUTIL_H
#define FUTIL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifndef FUTIL_READ_SIZE
#define FUTIL_READ_SIZE 2097152 //Default here is 2MiB
#endif
int ReadAllString(const char*, char**, size_t*);
#endif
+11
View File
@@ -0,0 +1,11 @@
#ifndef KEYWORDS_H
#define KEYWORDS_H
typedef enum {
FN, ORG
} Keyword;
int IsKeyword(const char* text, Keyword* keyword);
void GetKeywordText(Keyword keyword, char buffer[16]);
#endif
+1 -1
View File
@@ -10,7 +10,7 @@ typedef enum {
} Registers;
typedef enum {
ADD = 0x01, SUB, MUL, DIV, AND, OR, XOR, NOT, SHL, SHR, NOP, CMP, JMP, JG, JL,
ADD = 0x01, SUB, MUL, DIV, MOV, AND, OR, XOR, NOT, SHL, SHR, NOP, CMP, JMP, JG, JL,
OUTB, INB, HLT, ENI, INT, LIVT, PUSHA, POPA, CALL, RET, PUSH, POP
} Mnemonic;
+35
View File
@@ -0,0 +1,35 @@
#ifndef TOKEN_H
#define TOKEN_H
enum TokenType {
Empty,
String,
Number,
Symbol,
Plus = '+',
Minus = '-',
Star = '*',
Slash = '/',
Carot = '^',
OpenParen = '(',
CloseParen = ')',
FileEnd
};
typedef struct _token {
TokenType Type;
char* Name;
union {
char* String;
int Number;
} Value;
int LineNumber;
int ColumnNumber;
int Index;
int Length;
int Resolved;
} Token;
Token* TokenCreate(char* name, TokenType type, int lineNumber, int columnNumber, int index, int length, int resolved);
#endif
View File
+57
View File
@@ -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
View File
@@ -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;
}
+39
View File
@@ -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
View File
@@ -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
View File
@@ -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;