Kajetan Johannes Hammerle 5 日 前
コミット
b46e30d4e8
5 ファイル変更58 行追加6 行削除
  1. 14 6
      src/Compiler.c
  2. 3 0
      src/Tokenizer.c
  3. 1 0
      src/Tokenizer.h
  4. 34 0
      test/Else.basic
  5. 6 0
      test/Else.basic_result

+ 14 - 6
src/Compiler.c

@@ -224,16 +224,16 @@ static void cleanContext(Context* c) {
     CLEAN_LIST(c, BreakContinue, loopJumps);
 }
 
-[[noreturn]] static void unexpectedToken(Context* c, Token token, int line) {
+[[noreturn]] static void unexpectedToken(Context* c, Token token) {
     char buffer[128];
     tokenizerPrintToken(&token, buffer, sizeof(buffer));
-    THROW_ERROR("Unexpected %s token %d", buffer, line);
+    THROW_ERROR("Unexpected %s token", buffer);
 }
 
 static Token consumeToken(Context* c, TokenType type) {
     Token actual = tokenizerNext(c->tokenizer);
     if(actual.type != type) {
-        unexpectedToken(c, actual, __LINE__);
+        unexpectedToken(c, actual);
     }
     return actual;
 }
@@ -290,7 +290,7 @@ static void compileConstant(Context* c) {
         token = consumeToken(c, TT_LITERAL);
         compileReadVariable(c, token, true);
     } else {
-        unexpectedToken(c, token, __LINE__);
+        unexpectedToken(c, token);
     }
 }
 
@@ -385,9 +385,17 @@ static void compileIf(Context* c) {
     compileExpression(c);
     size_t posIndex = codePushInstructionI32(c, JUMP_ON_0, 0);
     consumeNewline(c);
-    while(!peekToken(c, TT_END)) {
+    while(!peekToken(c, TT_END) && !peekToken(c, TT_ELSE)) {
         compileLine(c, tokenizerNext(c->tokenizer));
     }
+    if(consumeTokenIf(c, TT_ELSE)) {
+        size_t elseEnd = codePushInstructionI32(c, JUMP, 0);
+        codeRewriteI32(c, posIndex, (i32)codeGetWritePosition(c));
+        posIndex = elseEnd;
+        while(!peekToken(c, TT_END)) {
+            compileLine(c, tokenizerNext(c->tokenizer));
+        }
+    }
     consumeToken(c, TT_END);
     consumeNewline(c);
     codeRewriteI32(c, posIndex, (i32)codeGetWritePosition(c));
@@ -620,7 +628,7 @@ static void compileLine(Context* c, Token token) {
         token = consumeToken(c, TT_LITERAL);
         compileSetVariable(c, token.stringValue, true);
     } else if(token.type != TT_LITERAL) {
-        unexpectedToken(c, token, __LINE__);
+        unexpectedToken(c, token);
     } else {
         compileLineLiteral(c, token);
     }

+ 3 - 0
src/Tokenizer.c

@@ -70,6 +70,8 @@ static const char* tokenizerAddLiteral(TState* t, const char* s) {
     }
     if(strcmp(buffer, "if") == 0) {
         tAddToken(t, TT_IF);
+    } else if(strcmp(buffer, "else") == 0) {
+        tAddToken(t, TT_ELSE);
     } else if(strcmp(buffer, "function") == 0) {
         tAddToken(t, TT_FUNCTION);
     } else if(strcmp(buffer, "end") == 0) {
@@ -349,6 +351,7 @@ void tokenizerPrintToken(const Token* token, char* buffer, size_t n) {
         TOKEN_PRINTER(TT_GREATER_OR_EQUAL, ">=");
         TOKEN_PRINTER(TT_SMALLER_OR_EQUAL, "<=");
         TOKEN_PRINTER(TT_IF, "If");
+        TOKEN_PRINTER(TT_ELSE, "Else");
         TOKEN_PRINTER(TT_FUNCTION, "Function");
         TOKEN_PRINTER(TT_END, "End");
         TOKEN_PRINTER(TT_RETURN, "Return");

+ 1 - 0
src/Tokenizer.h

@@ -25,6 +25,7 @@ typedef enum : u8 {
     TT_GREATER_OR_EQUAL,
     TT_SMALLER_OR_EQUAL,
     TT_IF,
+    TT_ELSE,
     TT_FUNCTION,
     TT_END,
     TT_RETURN,

+ 34 - 0
test/Else.basic

@@ -0,0 +1,34 @@
+if 1
+  printLine("wusi")
+  if 0
+    printLine("wusi4")
+  else
+    printLine("baum")
+  end
+  if 1
+    printLine("wusi2")
+  else
+    printLine("baum2")
+  end
+else
+  printLine("gusi")
+end
+
+if 1 + 1
+  printLine("wusi3")
+else
+  printLine("naaah")
+end
+
+if 0
+  printLine("gusi")
+  if 1
+    printLine("gusi2")
+  else
+    printLine("final")
+  end
+else
+  printLine("husi")
+end
+
+printLine("end")

+ 6 - 0
test/Else.basic_result

@@ -0,0 +1,6 @@
+wusi
+baum
+wusi2
+wusi3
+husi
+end