diff --git a/includes/ast.h b/includes/ast.h new file mode 100644 index 0000000..157ddd3 --- /dev/null +++ b/includes/ast.h @@ -0,0 +1,4 @@ +#ifndef AST_H +#define AST_H + +#endif \ No newline at end of file diff --git a/includes/dictionary.h b/includes/dictionary.h new file mode 100644 index 0000000..3977ad4 --- /dev/null +++ b/includes/dictionary.h @@ -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 \ No newline at end of file diff --git a/includes/futil.h b/includes/futil.h new file mode 100644 index 0000000..d062d45 --- /dev/null +++ b/includes/futil.h @@ -0,0 +1,15 @@ +#ifndef FUTIL_H +#define FUTIL_H + +#include +#include +#include +#include + +#ifndef FUTIL_READ_SIZE +#define FUTIL_READ_SIZE 2097152 //Default here is 2MiB +#endif + +int ReadAllString(const char*, char**, size_t*); + +#endif \ No newline at end of file diff --git a/includes/keywords.h b/includes/keywords.h new file mode 100644 index 0000000..7a38f2e --- /dev/null +++ b/includes/keywords.h @@ -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 \ No newline at end of file diff --git a/includes/opcodes.h b/includes/opcodes.h index ee0481d..f3b9b05 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -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; diff --git a/includes/token.h b/includes/token.h new file mode 100644 index 0000000..0c2af4b --- /dev/null +++ b/includes/token.h @@ -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 \ No newline at end of file diff --git a/src/ast.c b/src/ast.c new file mode 100644 index 0000000..e69de29 diff --git a/src/dictionary.c b/src/dictionary.c new file mode 100644 index 0000000..0c8f940 --- /dev/null +++ b/src/dictionary.c @@ -0,0 +1,57 @@ +#include "../includes/dictionary.h" +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/src/futil.c b/src/futil.c new file mode 100644 index 0000000..b7aa659 --- /dev/null +++ b/src/futil.c @@ -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; +} \ No newline at end of file diff --git a/src/keywords.c b/src/keywords.c new file mode 100644 index 0000000..ab0c0cf --- /dev/null +++ b/src/keywords.c @@ -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; + } + } +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 267b874..07d2934 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,21 @@ #include +#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 \n"); + + return 2; + } + + if (!ReadAllString(argv[1], &file, &count)) { + printf("Failed to read file '%s'.", argv[1]); + + return 1; + } + + printf(file); } \ No newline at end of file diff --git a/src/opcodes.c b/src/opcodes.c index c9f03f3..1170796 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -3,52 +3,49 @@ #include #include -#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;