Kajetan Johannes Hammerle 2 years ago
parent
commit
e28454ac64
14 changed files with 289 additions and 208 deletions
  1. 33 24
      Compiler.c
  2. 21 0
      Error.c
  3. 23 0
      Error.h
  4. 5 3
      Main.c
  5. 5 3
      Test.c
  6. 2 1
      meson.build
  7. 0 23
      tokenizer/File.h
  8. 72 4
      tokenizer/FileReader.c
  9. 27 0
      tokenizer/FileReader.h
  10. 4 44
      tokenizer/Token.c
  11. 4 13
      tokenizer/Token.h
  12. 83 83
      tokenizer/Tokenizer.c
  13. 3 9
      tokenizer/Tokenizer.h
  14. 7 1
      utils/ByteCodePrinter.c

+ 33 - 24
Compiler.c

@@ -12,7 +12,13 @@
 #include "vm/Operation.h"
 
 #define ERROR_LENGTH 256
-#define RETURN_BUFFER 16
+static char error[ERROR_LENGTH] = {'\0'};
+static ByteCode* code;
+static int16 line = 1;
+
+static jmp_buf errorJump;
+
+/*#define RETURN_BUFFER 16
 #define BREAK_BUFFER 32
 
 #define DT_OPERATION(op)                                                       \
@@ -23,12 +29,6 @@
 
 typedef DataType (*Parser)(void);
 
-static jmp_buf errorJump;
-static char error[ERROR_LENGTH] = {'\0'};
-
-static ByteCode* code;
-
-static int16 line = 1;
 static bool onLine = false;
 
 static Variables vars;
@@ -146,7 +146,7 @@ static void cAddLine(int16 i) {
 }
 
 static Token cReadTokenAndLine() {
-    hasReturn--;
+    // hasReturn--;
     Token t = tReadToken();
     if(tReadInt16(&line)) {
         return t;
@@ -230,18 +230,17 @@ static DataType cReadType(Token t, bool force) {
         case T_INT64: return cExtendType(dtInt64(), c);
         case T_BOOL: return cExtendType(dtBool(), c);
         case T_FLOAT: return cExtendType(dtFloat(), c);
-        case T_LITERAL:
-            {
-                Struct* st = stsSearch(&structs, cReadString());
-                if(st == NULL) {
-                    if(force) {
-                        cError("struct %s does not exist");
-                    } else {
-                        return dtVoid();
-                    }
+        case T_LITERAL: {
+            Struct* st = stsSearch(&structs, cReadString());
+            if(st == NULL) {
+                if(force) {
+                    cError("struct %s does not exist");
+                } else {
+                    return dtVoid();
                 }
-                return cExtendType(dtStruct(st), c);
             }
+            return cExtendType(dtStruct(st), c);
+        }
         default:
             if(force) {
                 cUnexpectedToken(t);
@@ -1157,10 +1156,19 @@ static void cLinkQueuedFunctions() {
         }
         cSetInt32(f->address, found->address);
     }
+}*/
+
+static void cScanForFunctions() {
+    /*while(true) {
+        Token t = cReadTokenAndLine();
+        if(t == T_END) {
+            break;
+        }
+    }*/
 }
 
 static void cAllocAndCompile() {
-    forWhileStack = 0;
+    /*forWhileStack = 0;
     breakIndex = 0;
     returnType = dtVoid();
     onLine = false;
@@ -1168,16 +1176,17 @@ static void cAllocAndCompile() {
     vsInit(&globalVars);
     fsInit(&functions);
     fsInit(&functionQueue);
-    stsInit(&structs);
+    stsInit(&structs);*/
     if(!setjmp(errorJump)) {
-        cForEachLine();
-        cLinkQueuedFunctions();
+        cScanForFunctions();
+        // cForEachLine();
+        // cLinkQueuedFunctions();
     }
-    stsDelete(&structs);
+    /*stsDelete(&structs);
     fsDelete(&functionQueue);
     fsDelete(&functions);
     vsDelete(&globalVars);
-    vsDelete(&vars);
+    vsDelete(&vars);*/
 }
 
 ByteCode* cCompile() {

+ 21 - 0
Error.c

@@ -0,0 +1,21 @@
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "Error.h"
+
+void eInitError(Error* e, int line, const char* format, ...) {
+    e->line = line;
+    va_list args;
+    va_start(args, format);
+    vsnprintf(e->message, sizeof(e->message), format, args);
+    va_end(args);
+}
+
+void eInitSuccess(Error* e) {
+    e->line = -1;
+    e->message[0] = '\0';
+}
+
+bool eHasError(const Error* e) {
+    return e->line >= 0;
+}

+ 23 - 0
Error.h

@@ -0,0 +1,23 @@
+#ifndef SNUVI_ERROR_H
+#define SNUVI_ERROR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+typedef struct Error {
+    int line;
+    char message[256];
+} Error;
+
+void eInitError(Error* e, int line, const char* format, ...);
+void eInitSuccess(Error* e);
+bool eHasError(const Error* e);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 5 - 3
Main.c

@@ -20,9 +20,11 @@ static void start(int argAmount, const char** args) {
     if(argAmount >= 3 && strcmp(args[1], "test") == 0) {
         tsStart(args[2]);
     } else if(argAmount >= 2) {
-        if(tTokenize(args[1])) {
-            puts(tGetError());
-            printf("line: %d\n", tGetLine());
+        Error e;
+        tTokenize(args[1], &e);
+        if(eHasError(&e)) {
+            puts(e.message);
+            printf("line: %d\n", e.line);
             return;
         }
         ByteCode* code = cCompile();

+ 5 - 3
Test.c

@@ -135,10 +135,12 @@ static void tsCheckScript(Script* sc) {
 
 static void tsCheckFile() {
     allTests++;
-    if(tTokenize(path)) {
+    Error e;
+    tTokenize(path, &e);
+    if(eHasError(&e)) {
         puts(path);
-        puts(tGetError());
-        printf("line: %d\n", tGetLine());
+        puts(e.message);
+        printf("line: %d\n", e.line);
         return;
     }
     ByteCode* bc = cCompile();

+ 2 - 1
meson.build

@@ -3,13 +3,14 @@ project('lonelytiger', 'c')
 src = [
     'tokenizer/Tokenizer.c', 
     'tokenizer/Token.c', 
-    'tokenizer/File.c', 
+    'tokenizer/FileReader.c', 
     'utils/SnuviUtils.c', 
     'utils/Variables.c',
     'utils/Functions.c',
     'utils/ByteCodePrinter.c',
     'Compiler.c', 
     'DataType.c', 
+    'Error.c', 
     'Test.c', 
     'vm/ByteCode.c',
     'vm/Script.c', 

+ 0 - 23
tokenizer/File.h

@@ -1,23 +0,0 @@
-#ifndef FILE_H
-#define FILE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdbool.h>
-
-typedef void (*FileError)(const char*, ...);
-
-void fOpen(const char* path, FileError fe);
-void fClose();
-
-int fRead();
-int fPeek();
-bool fReadIf(int c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 72 - 4
tokenizer/File.c → tokenizer/FileReader.c

@@ -1,11 +1,79 @@
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "tokenizer/File.h"
-#include "utils/SnuviUtils.h"
+#include "tokenizer/FileReader.h"
 
-#define MAX_INDEX 50
+static void frFullRead(FILE* file, const char* path, FileReader* fr, Error* e) {
+    if(fseek(file, 0, SEEK_END)) {
+        eInitError(e, 1, "cannot seek end of file '%s': %s", path,
+                   strerror(errno));
+        return;
+    }
+    long length = ftell(file);
+    if(length < 0) {
+        eInitError(e, 1, "cannot tell end of file '%s': %s", path,
+                   strerror(errno));
+        return;
+    }
+    rewind(file);
+    fr->data = malloc(length + 1);
+    fr->length = length;
+    int readValues = fread(fr->data, 1, length, file);
+    if(readValues != length) {
+        eInitError(e, 1, "cannot read file '%s': %s", path, strerror(errno));
+        fr->data[0] = '\0';
+        return;
+    }
+    fr->data[length] = '\0';
+    eInitSuccess(e);
+}
+
+void frInit(const char* path, FileReader* fr, Error* e) {
+    fr->data = NULL;
+    fr->length = 0;
+    fr->readIndex = 0;
+
+    FILE* file = fopen(path, "r");
+    if(file == NULL) {
+        eInitError(e, 1, "cannot open file '%s': %s", path, strerror(errno));
+        return;
+    }
+    frFullRead(file, path, fr, e);
+    fclose(file);
+}
+
+void frDelete(FileReader* fr) {
+    free(fr->data);
+    fr->data = NULL;
+    fr->length = 0;
+    fr->readIndex = 0;
+}
+
+int frRead(FileReader* fr) {
+    if(fr->readIndex < fr->length) {
+        return fr->data[fr->readIndex++];
+    }
+    return -1;
+}
+
+int frPeek(FileReader* fr) {
+    if(fr->readIndex < fr->length) {
+        return fr->data[fr->readIndex];
+    }
+    return -1;
+}
+
+bool frReadIf(FileReader* fr, int c) {
+    if(frPeek(fr) == c) {
+        frRead(fr);
+        return true;
+    }
+    return false;
+}
+
+/*#define MAX_INDEX 50
 
 typedef struct {
     char* content;
@@ -376,4 +444,4 @@ bool fReadIf(int c) {
         return true;
     }
     return false;
-}
+}*/

+ 27 - 0
tokenizer/FileReader.h

@@ -0,0 +1,27 @@
+#ifndef FILE_READER_H
+#define FILE_READER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "Error.h"
+
+typedef struct FileReader {
+    int length;
+    int readIndex;
+    unsigned char* data;
+} FileReader;
+
+void frInit(const char* path, FileReader* fr, Error* e);
+void frDelete(FileReader* fr);
+
+int frRead(FileReader* fr);
+int frPeek(FileReader* fr);
+bool frReadIf(FileReader* fr, int c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 4 - 44
tokenizer/Token.c

@@ -1,22 +1,14 @@
-#include <stdbool.h>
-#include <string.h>
-
 #include "tokenizer/Token.h"
 
 const char* tGetName(Token token) {
     switch(token) {
         case T_VOID: return "void";
-        case T_INT32: return "int";
-        case T_INT64: return "long";
-        case T_BOOL: return "bool";
+        case T_INT: return "int";
+        case T_INT_VALUE: return "int value";
         case T_FLOAT: return "float";
-        case T_CONST_INT32: return "const int";
-        case T_CONST_INT64: return "const long";
-        case T_CONST_FLOAT: return "const float";
+        case T_FLOAT_VALUE: return "float value";
         case T_TEXT: return "text";
-        case T_NULLPTR: return "nullptr";
-        case T_TRUE: return "true";
-        case T_FALSE: return "false";
+        case T_NULL: return "nullptr";
         case T_ADD: return "+";
         case T_SUB: return "-";
         case T_MUL: return "*";
@@ -66,43 +58,11 @@ const char* tGetName(Token token) {
         case T_OPEN_CURVED_BRACKET: return "{";
         case T_CLOSE_CURVED_BRACKET: return "}";
         case T_POINT: return ".";
-        case T_ARROW: return "->";
         case T_OPEN_SQUARE_BRACKET: return "[";
         case T_CLOSE_SQUARE_BRACKET: return "]";
         case T_NEW: return "new";
-        case T_DELETE: return "delete";
         case T_LENGTH: return "length";
-        case T_CONST: return "const";
         case T_END: return "end";
     }
     return "unknown";
-}
-
-#define MATCH_TOKEN(tokenName, token)                                          \
-    if(strcmp(name, tokenName) == 0) {                                         \
-        return token;                                                          \
-    }
-
-Token tFromName(const char* name) {
-    MATCH_TOKEN("nullptr", T_NULLPTR);
-    MATCH_TOKEN("true", T_TRUE);
-    MATCH_TOKEN("false", T_FALSE);
-    MATCH_TOKEN("return", T_RETURN);
-    MATCH_TOKEN("if", T_IF);
-    MATCH_TOKEN("else", T_ELSE);
-    MATCH_TOKEN("while", T_WHILE);
-    MATCH_TOKEN("for", T_FOR);
-    MATCH_TOKEN("break", T_BREAK);
-    MATCH_TOKEN("continue", T_CONTINUE);
-    MATCH_TOKEN("int", T_INT32);
-    MATCH_TOKEN("long", T_INT64);
-    MATCH_TOKEN("void", T_VOID);
-    MATCH_TOKEN("bool", T_BOOL);
-    MATCH_TOKEN("float", T_FLOAT);
-    MATCH_TOKEN("struct", T_STRUCT);
-    MATCH_TOKEN("new", T_NEW);
-    MATCH_TOKEN("delete", T_DELETE);
-    MATCH_TOKEN("length", T_LENGTH);
-    MATCH_TOKEN("const", T_CONST);
-    return T_END;
 }

+ 4 - 13
tokenizer/Token.h

@@ -7,17 +7,12 @@ extern "C" {
 
 typedef enum {
     T_VOID,
-    T_INT32,
-    T_INT64,
-    T_BOOL,
+    T_INT,
+    T_INT_VALUE,
     T_FLOAT,
-    T_CONST_INT32,
-    T_CONST_INT64,
-    T_CONST_FLOAT,
+    T_FLOAT_VALUE,
     T_TEXT,
-    T_NULLPTR,
-    T_TRUE,
-    T_FALSE,
+    T_NULL,
     T_ADD,
     T_SUB,
     T_MUL,
@@ -67,18 +62,14 @@ typedef enum {
     T_OPEN_CURVED_BRACKET,
     T_CLOSE_CURVED_BRACKET,
     T_POINT,
-    T_ARROW,
     T_OPEN_SQUARE_BRACKET,
     T_CLOSE_SQUARE_BRACKET,
     T_NEW,
-    T_DELETE,
     T_LENGTH,
-    T_CONST,
     T_END
 } Token;
 
 const char* tGetName(Token token);
-Token tFromName(const char* name);
 
 #ifdef __cplusplus
 }

+ 83 - 83
tokenizer/Tokenizer.c

@@ -1,30 +1,33 @@
 #include <limits.h>
 #include <setjmp.h>
-#include <stdarg.h>
+//#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#include "tokenizer/File.h"
+#include "tokenizer/FileReader.h"
 #include "tokenizer/Tokenizer.h"
 #include "utils/SnuviUtils.h"
 
 #define TOKEN_BUFFER_LENGTH (1024 * 1024)
 #define ERROR_LENGTH 256
 
+static FileReader fileReader;
 static jmp_buf errorJump;
+static Error* error;
+
 static char tokenBuffer[TOKEN_BUFFER_LENGTH];
 static int writeIndex = 0;
 static int readIndex = 0;
 static int16 line = 1;
-static char error[ERROR_LENGTH] = {'\0'};
 
 static void tError(const char* format, ...) {
-    va_list args;
+    /*va_list args;
     va_start(args, format);
     vsnprintf(error, ERROR_LENGTH, format, args);
     va_end(args);
-    longjmp(errorJump, 0);
+    longjmp(errorJump, 0);*/
+    (void)format;
 }
 
 static void tAdd(const void* data, int length) {
@@ -43,27 +46,60 @@ static void tAddToken(Token token) {
 
 static bool tReadTokens(void* dest, int length) {
     if(readIndex + length > writeIndex) {
-        return false;
+        return true;
     }
     memcpy(dest, tokenBuffer + readIndex, length);
     readIndex += length;
-    return true;
+    return false;
 }
 
 static void tParseLiteral(int c) {
     int index = 1;
     char buffer[64];
     buffer[0] = c;
-    while(isAllowedInName(fPeek())) {
+    while(isAllowedInName(frPeek(&fileReader))) {
         if(index >= 63) {
             tError("literal is too long");
         }
-        buffer[index++] = fRead();
+        buffer[index++] = frRead(&fileReader);
     }
     buffer[index] = '\0';
-    Token t = tFromName(buffer);
-    if(t != T_END) {
-        tAddToken(t);
+    if(strcmp(buffer, "null") == 0) {
+        tAddToken(T_NULL);
+    } else if(strcmp(buffer, "return") == 0) {
+        tAddToken(T_RETURN);
+    } else if(strcmp(buffer, "if") == 0) {
+        tAddToken(T_IF);
+    } else if(strcmp(buffer, "else") == 0) {
+        tAddToken(T_ELSE);
+    } else if(strcmp(buffer, "while") == 0) {
+        tAddToken(T_WHILE);
+    } else if(strcmp(buffer, "for") == 0) {
+        tAddToken(T_FOR);
+    } else if(strcmp(buffer, "break") == 0) {
+        tAddToken(T_BREAK);
+    } else if(strcmp(buffer, "continue") == 0) {
+        tAddToken(T_CONTINUE);
+    } else if(strcmp(buffer, "int") == 0) {
+        tAddToken(T_INT);
+    } else if(strcmp(buffer, "void") == 0) {
+        tAddToken(T_VOID);
+    } else if(strcmp(buffer, "float") == 0) {
+        tAddToken(T_FLOAT);
+    } else if(strcmp(buffer, "struct") == 0) {
+        tAddToken(T_STRUCT);
+    } else if(strcmp(buffer, "new") == 0) {
+        tAddToken(T_NEW);
+    } else if(strcmp(buffer, "length") == 0) {
+        tAddToken(T_LENGTH);
+    } else if(strcmp(buffer, "true") == 0) {
+        int32 i = 1;
+        tAddToken(T_INT_VALUE);
+        tAdd(&i, sizeof(int32));
+    } else if(strcmp(buffer, "false") == 0) {
+        int32 i = 0;
+        tAddToken(T_INT_VALUE);
+        tAdd(&i, sizeof(int32));
     } else {
         tAddToken(T_LITERAL);
         tAdd(buffer, index + 1);
@@ -92,7 +128,7 @@ static void tParseNumber(int c) {
     buffer[0] = c;
     bool point = false;
     while(true) {
-        int c = fPeek();
+        int c = frPeek(&fileReader);
         if(c == '.') {
             point = true;
         } else if(!isNumber(c)) {
@@ -100,28 +136,16 @@ static void tParseNumber(int c) {
         } else if(index >= 63) {
             tError("number is too long");
         }
-        buffer[index++] = fRead();
+        buffer[index++] = frRead(&fileReader);
     }
     buffer[index] = '\0';
-    if(fPeek() == 'L' || fPeek() == 'l') {
-        fRead();
-        if(point) {
-            tError("invalid mix of long and float", line);
-        }
-        long long l;
-        if(tParseInt(buffer, index, &l) || l > INT64_MAX) {
-            tError("invalid long on line %d", line);
-        }
-        int64 i = l;
-        tAddToken(T_CONST_INT64);
-        tAdd(&i, sizeof(int64));
-    } else if(point) {
+    if(point) {
         char* end = NULL;
         float f = strtof(buffer, &end);
         if(end[0] != '\0') {
             tError("invalid float on line %d", line);
         }
-        tAddToken(T_CONST_FLOAT);
+        tAddToken(T_FLOAT_VALUE);
         tAdd(&f, sizeof(float));
     } else {
         long long l;
@@ -129,14 +153,14 @@ static void tParseNumber(int c) {
             tError("invalid int on line %d", line);
         }
         int32 i = l;
-        tAddToken(T_CONST_INT32);
+        tAddToken(T_INT_VALUE);
         tAdd(&i, sizeof(int32));
     }
 }
 
 static int32 tUnicode(int32 c) {
     if(c == '\\') {
-        switch(fRead()) {
+        switch(frRead(&fileReader)) {
             case '"': c = '"'; break;
             case '\\': c = '\\'; break;
             case 'n': c = '\n'; break;
@@ -146,14 +170,14 @@ static int32 tUnicode(int32 c) {
         }
     }
     if((c & 0xE0) == 0xC0) {
-        c = ((c & 0x1F) << 6) | (fRead() & 0x3F);
+        c = ((c & 0x1F) << 6) | (frRead(&fileReader) & 0x3F);
     } else if((c & 0xF0) == 0xE0) {
-        c = ((c & 0xF) << 12) | ((fRead() & 0x3F) << 6);
-        c |= fRead() & 0x3F;
+        c = ((c & 0xF) << 12) | ((frRead(&fileReader) & 0x3F) << 6);
+        c |= frRead(&fileReader) & 0x3F;
     } else if((c & 0xF8) == 0xF0) {
-        c = ((c & 0x7) << 18) | ((fRead() & 0x3F) << 12);
-        c |= (fRead() & 0x3F) << 6;
-        c |= fRead() & 0x3F;
+        c = ((c & 0x7) << 18) | ((frRead(&fileReader) & 0x3F) << 12);
+        c |= (frRead(&fileReader) & 0x3F) << 6;
+        c |= frRead(&fileReader) & 0x3F;
     }
     return c;
 }
@@ -161,7 +185,7 @@ static int32 tUnicode(int32 c) {
 static void tAddString() {
     tAddToken(T_TEXT);
     while(true) {
-        int32 c = fRead();
+        int32 c = frRead(&fileReader);
         if(c == '"') {
             break;
         } else if(c == EOF) {
@@ -175,17 +199,17 @@ static void tAddString() {
 }
 
 static void tAddUnicode() {
-    int32 c = fRead();
+    int32 c = frRead(&fileReader);
     c = tUnicode(c);
-    tAddToken(T_CONST_INT32);
+    tAddToken(T_INT_VALUE);
     tAdd(&c, sizeof(int32));
-    if(fRead() != '\'') {
+    if(frRead(&fileReader) != '\'') {
         tError("expecting unicode end");
     }
 }
 
 static void tAddToken2(Token te, Token t) {
-    if(fReadIf('=')) {
+    if(frReadIf(&fileReader, '=')) {
         tAddToken(te);
     } else {
         tAddToken(t);
@@ -193,7 +217,7 @@ static void tAddToken2(Token te, Token t) {
 }
 
 static void tAddToken3(int c, Token tc, Token te, Token t) {
-    if(fReadIf(c)) {
+    if(frReadIf(&fileReader, c)) {
         tAddToken(tc);
     } else {
         tAddToken2(te, t);
@@ -201,20 +225,16 @@ static void tAddToken3(int c, Token tc, Token te, Token t) {
 }
 
 static void tAddToken4(int c, Token tce, Token tc, Token te, Token t) {
-    if(fReadIf(c)) {
+    if(frReadIf(&fileReader, c)) {
         tAddToken2(tce, tc);
     } else {
         tAddToken2(te, t);
     }
 }
 
-static void tAddTokenMinus() {
-    tAddToken3('-', T_DECREMENT, T_SUB_SET, fReadIf('>') ? T_ARROW : T_SUB);
-}
-
 static void tLineComment() {
     while(true) {
-        int c = fRead();
+        int c = frRead(&fileReader);
         if(c == EOF || c == '\n') {
             line++;
             return;
@@ -224,21 +244,21 @@ static void tLineComment() {
 
 static void tMultipleLineComment() {
     while(true) {
-        int c = fRead();
+        int c = frRead(&fileReader);
         if(c == EOF) {
             tError("unclosed comment at line %d", line);
         } else if(c == '\n') {
             line++;
-        } else if(c == '*' && fReadIf('/')) {
+        } else if(c == '*' && frReadIf(&fileReader, '/')) {
             return;
         }
     }
 }
 
 static void tSlash() {
-    if(fReadIf('/')) {
+    if(frReadIf(&fileReader, '/')) {
         tLineComment();
-    } else if(fReadIf('*')) {
+    } else if(frReadIf(&fileReader, '*')) {
         tMultipleLineComment();
     } else {
         tAddToken2(T_DIV_SET, T_DIV);
@@ -257,7 +277,7 @@ static void tParseToken(int c) {
         case ' ': return;
         case '\n': line++; return;
         case '+': tAddToken3('+', T_INCREMENT, T_ADD_SET, T_ADD); return;
-        case '-': tAddTokenMinus(); return;
+        case '-': tAddToken3('-', T_DECREMENT, T_SUB_SET, T_SUB); return;
         case '*': tAddToken2(T_MUL_SET, T_MUL); return;
         case '/': tSlash(); return;
         case '%': tAddToken2(T_MOD_SET, T_MOD); return;
@@ -294,9 +314,8 @@ static void tParseFile() {
     readIndex = 0;
     writeIndex = 0;
     line = 1;
-    error[0] = '\0';
     while(true) {
-        int c = fRead();
+        int c = frRead(&fileReader);
         if(c == EOF) {
             return;
         }
@@ -304,25 +323,13 @@ static void tParseFile() {
     }
 }
 
-bool tTokenize(const char* path) {
-    if(!setjmp(errorJump)) {
-        fOpen(path, tError);
+void tTokenize(const char* path, Error* e) {
+    error = e;
+    frInit(path, &fileReader, e);
+    if(!eHasError(e) && !setjmp(errorJump)) {
         tParseFile();
     }
-    fClose();
-    return error[0] != '\0';
-}
-
-const char* tGetError() {
-    return error;
-}
-
-int tGetLine() {
-    return line;
-}
-
-void tResetReader() {
-    readIndex = 0;
+    frDelete(&fileReader);
 }
 
 Token tPeekToken() {
@@ -332,25 +339,18 @@ Token tPeekToken() {
     return tokenBuffer[readIndex];
 }
 
-Token tReadToken() {
+bool tReadTokenAndLine(Token* t, int16* line) {
     if(readIndex >= writeIndex) {
-        return T_END;
+        return true;
     }
-    return tokenBuffer[readIndex++];
-}
-
-bool tReadInt16(int16* i) {
-    return tReadTokens(i, sizeof(int16));
+    *t = tokenBuffer[readIndex++];
+    return tReadTokens(line, sizeof(int16));
 }
 
 bool tReadInt32(int32* i) {
     return tReadTokens(i, sizeof(int32));
 }
 
-bool tReadInt64(int64* i) {
-    return tReadTokens(i, sizeof(int64));
-}
-
 bool tReadFloat(float* f) {
     return tReadTokens(f, sizeof(float));
 }

+ 3 - 9
tokenizer/Tokenizer.h

@@ -5,21 +5,15 @@
 extern "C" {
 #endif
 
-#include <stdbool.h>
-
+#include "Error.h"
 #include "Types.h"
 #include "tokenizer/Token.h"
 
-bool tTokenize(const char* path);
-const char* tGetError();
-int tGetLine();
+void tTokenize(const char* path, Error* e);
 
-void tResetReader();
 Token tPeekToken();
-Token tReadToken();
-bool tReadInt16(int16* i);
+bool tReadTokenAndLine(Token* t, int16* line);
 bool tReadInt32(int32* i);
-bool tReadInt64(int64* i);
 bool tReadFloat(float* f);
 const char* tReadString();
 int tGetMarker();

+ 7 - 1
utils/ByteCodePrinter.c

@@ -13,9 +13,14 @@ static int line;
 static char buffer[LINE_LENGTH];
 static int bIndex;
 
+static void btPrintEnd() {
+    puts("+--------+-------+----------------------+------------+------------+");
+}
+
 static void btPrintHeading() {
+    btPrintEnd();
     puts("|  Index |  Line |            Operation | Argument 1 | Argument 2 |");
-    puts("|--------|-------|----------------------|------------|------------|");
+    btPrintEnd();
 }
 
 static void btAdd(const char* format, ...) {
@@ -245,4 +250,5 @@ void btPrint(ByteCode* bt) {
     while(readIndex < code->length) {
         btConsumeOperation();
     }
+    btPrintEnd();
 }