Added / started some infrastructure / boilerplate code.
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
#ifndef AST_H
|
||||||
|
#define AST_H
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
@@ -10,7 +10,7 @@ typedef enum {
|
|||||||
} Registers;
|
} Registers;
|
||||||
|
|
||||||
typedef enum {
|
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
|
OUTB, INB, HLT, ENI, INT, LIVT, PUSHA, POPA, CALL, RET, PUSH, POP
|
||||||
} Mnemonic;
|
} Mnemonic;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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 <stdio.h>
|
||||||
|
#include "../includes/futil.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define OPCODECOUNT 34
|
#define OPCODE_COUNT 34
|
||||||
|
|
||||||
struct _instruction {
|
struct _instruction {
|
||||||
char* Name;
|
char* Name;
|
||||||
Mnemonic Mnemonic;
|
Mnemonic Mnemonic;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _instruction instructions[OPCODECOUNT] = {
|
struct _instruction instructions[OPCODE_COUNT] = {
|
||||||
{ "copya", COPYA },
|
|
||||||
{ "copyab", COPYAB },
|
|
||||||
{ "copyra", COPYRA },
|
|
||||||
{ "copyrab", COPYRAB },
|
|
||||||
{ "copyrara", COPYRARA },
|
|
||||||
{ "copyrarab", COPYRARAB },
|
|
||||||
{ "copy", COPY },
|
|
||||||
{ "copyi", COPYI },
|
|
||||||
{ "copyb", COPYB },
|
|
||||||
{ "cmp", CMP },
|
|
||||||
{ "cmpi", CMPI },
|
|
||||||
{ "add", ADD },
|
{ "add", ADD },
|
||||||
{ "sub", SUB },
|
{ "sub", SUB },
|
||||||
|
{ "mul", MUL },
|
||||||
|
{ "div", DIV },
|
||||||
|
{ "mov", MOV },
|
||||||
{ "and", AND },
|
{ "and", AND },
|
||||||
{ "xor", XOR },
|
|
||||||
{ "or", OR },
|
{ "or", OR },
|
||||||
|
{ "xor", XOR },
|
||||||
{ "not", NOT },
|
{ "not", NOT },
|
||||||
{ "shr", SHR },
|
|
||||||
{ "shl", SHL },
|
{ "shl", SHL },
|
||||||
{ "inc", INC },
|
{ "shr", SHR },
|
||||||
{ "dec", DEC },
|
{ "nop", NOP },
|
||||||
{ "push", PUSH },
|
{ "cmp", CMP },
|
||||||
{ "pop", POP },
|
|
||||||
{ "jmpi", JMPI },
|
|
||||||
{ "jmp", JMP },
|
|
||||||
{ "jz", JZ },
|
{ "jz", JZ },
|
||||||
{ "jg", JG },
|
{ "jg", JG },
|
||||||
{ "jl", JL },
|
{ "jl", JL },
|
||||||
{ "nop", NOP },
|
{ "outb", OUTB },
|
||||||
|
{ "inb", INB },
|
||||||
|
{ "hlt", HLT },
|
||||||
|
{ "cli", CLI },
|
||||||
|
{ "eni", ENI },
|
||||||
|
{ "int", INT },
|
||||||
|
{ "livt", LIVT },
|
||||||
|
{ "pusha", PUSHA },
|
||||||
|
{ "popa", POPA },
|
||||||
{ "call", CALL },
|
{ "call", CALL },
|
||||||
{ "ret", RET }
|
{ "ret", RET },
|
||||||
//yld
|
{ "push", PUSH },
|
||||||
|
{ "pop", POP }
|
||||||
};
|
};
|
||||||
|
|
||||||
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]) {
|
void GetMnemonicText(Mnemonic mnemonic, char buffer[12]) {
|
||||||
memset(buffer, '\0', 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) {
|
if (instructions[i].Mnemonic == mnemonic) {
|
||||||
strncpy(buffer, instructions[i].Name, 11);
|
strncpy(buffer, instructions[i].Name, 11);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user