فهرست منبع

Make more keywords to special tokens

Kajetan Johannes Hammerle 2 هفته پیش
والد
کامیت
9029e6278e
3فایلهای تغییر یافته به همراه44 افزوده شده و 32 حذف شده
  1. 7 16
      src/Compiler.c
  2. 26 15
      src/Tokenizer.c
  3. 11 1
      src/Tokenizer.h

+ 7 - 16
src/Compiler.c

@@ -48,14 +48,6 @@ static Token consumeNewline(Context* c) {
     return t;
 }
 
-static void consumeLiteral(Context* c, const char* name) {
-    Token token = consumeToken(c, LITERAL);
-    const char* actual = token.stringValue;
-    if(strcmp(actual, name) != 0) {
-        THROW_ERROR("Unexpected literal(%s)", actual);
-    }
-}
-
 static void compileConstant(Context* c) {
     Token token = tokenizerNext(c->tokenizer);
     if(token.type == STRING) {
@@ -89,16 +81,15 @@ static void compileIf(Context* c) {
     CODE(codePushInstruction(c->code, JUMP_ON_0));
     size_t posIndex = codeGetWritePosition(c->code);
     CODE(codePushSize(c->code, 0));
-    consumeLiteral(c, "then");
+    consumeToken(c, THEN);
     consumeNewline(c);
     while(true) {
-        Token token = tokenizerPeek(c->tokenizer);
-        if(token.type == LITERAL && strcmp(token.stringValue, "endif") == 0) {
+        if(tokenizerPeek(c->tokenizer).type == ENDIF) {
             break;
         }
         compileLine(c, tokenizerNext(c->tokenizer));
     }
-    consumeLiteral(c, "endif");
+    consumeToken(c, ENDIF);
     consumeNewline(c);
     size_t endIndex = codeGetWritePosition(c->code);
     codeSetWritePosition(c->code, posIndex);
@@ -110,8 +101,10 @@ static void compileLine(Context* c, Token token) {
     if(token.type == NEWLINE) {
         c->line++;
         return;
-    }
-    if(token.type != LITERAL) {
+    } else if(token.type == IF) {
+        compileIf(c);
+        return;
+    } else if(token.type != LITERAL) {
         unexpectedToken(c, token);
     }
     const char* s = token.stringValue;
@@ -122,8 +115,6 @@ static void compileLine(Context* c, Token token) {
         }
         consumeNewline(c);
         CODE(codePushInstruction(c->code, PRINT_NEWLINE));
-    } else if(strcmp(s, "if") == 0) {
-        compileIf(c);
     } else {
         THROW_ERROR("Unexpected literal(%s)", s);
     }

+ 26 - 15
src/Tokenizer.c

@@ -6,6 +6,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 typedef struct {
     int line;
@@ -56,7 +57,6 @@ static bool isTokenEnd(char c) {
 }
 
 static const char* tokenizerAddLiteral(TState* t, const char* s) {
-    tAddToken(t, LITERAL);
     size_t index = 0;
     char buffer[256] = {};
     buffer[index++] = *s;
@@ -71,8 +71,17 @@ static const char* tokenizerAddLiteral(TState* t, const char* s) {
         }
         buffer[index++] = c;
     }
-    if(bufferWriteString(&t->tokenizer->buffer, buffer)) {
-        tTooMuchTokens(t);
+    if(strcmp(buffer, "if") == 0) {
+        tAddToken(t, IF);
+    } else if(strcmp(buffer, "then") == 0) {
+        tAddToken(t, THEN);
+    } else if(strcmp(buffer, "endif") == 0) {
+        tAddToken(t, ENDIF);
+    } else {
+        tAddToken(t, LITERAL);
+        if(bufferWriteString(&t->tokenizer->buffer, buffer)) {
+            tTooMuchTokens(t);
+        }
     }
     return s;
 }
@@ -227,18 +236,20 @@ void tokenizerDestroy(Tokenizer* t) {
     *t = (Tokenizer){};
 }
 
+#define TOKEN_PRINTER(token, format, ...)                                      \
+    case token: snprintf(buffer, n, format __VA_OPT__(, ) __VA_ARGS__); return
+
 void tokenizerPrintToken(const Token* token, char* buffer, size_t n) {
     switch(token->type) {
-        case LITERAL:
-            snprintf(buffer, n, "Literal(%s)", token->stringValue);
-            break;
-        case INT64: snprintf(buffer, n, "Int64(%ld)", token->intValue); break;
-        case STRING:
-            snprintf(buffer, n, "String(%s)", token->stringValue);
-            break;
-        case PLUS: snprintf(buffer, n, "Plus"); break;
-        case NEWLINE: snprintf(buffer, n, "Newline"); break;
-        case END: snprintf(buffer, n, "End"); break;
-        default: snprintf(buffer, n, "Unknown"); break;
-    }
+        TOKEN_PRINTER(LITERAL, "Literal(%s)", token->stringValue);
+        TOKEN_PRINTER(INT64, "Int64(%ld)", token->intValue);
+        TOKEN_PRINTER(STRING, "String(%s)", token->stringValue);
+        TOKEN_PRINTER(PLUS, "Plus");
+        TOKEN_PRINTER(IF, "If");
+        TOKEN_PRINTER(THEN, "Then");
+        TOKEN_PRINTER(ENDIF, "EndIf");
+        TOKEN_PRINTER(NEWLINE, "Newline");
+        TOKEN_PRINTER(END, "End");
+    }
+    snprintf(buffer, n, "Unknown");
 }

+ 11 - 1
src/Tokenizer.h

@@ -4,7 +4,17 @@
 #include "Buffer.h"
 #include "Error.h"
 
-typedef enum : u8 { LITERAL, INT64, STRING, PLUS, NEWLINE, END } TokenType;
+typedef enum : u8 {
+    LITERAL,
+    INT64,
+    STRING,
+    PLUS,
+    IF,
+    THEN,
+    ENDIF,
+    NEWLINE,
+    END
+} TokenType;
 
 typedef struct {
     TokenType type;