Explorar o código

return for functions

Kajetan Johannes Hammerle %!s(int64=4) %!d(string=hai) anos
pai
achega
12a5ca9c04
Modificáronse 5 ficheiros con 32 adicións e 2 borrados
  1. 20 2
      Compiler.c
  2. 3 0
      Tokenizer.c
  3. 1 0
      Tokenizer.h
  4. 7 0
      tests/functions/return
  5. 1 0
      tests/functions/return.out

+ 20 - 2
Compiler.c

@@ -8,9 +8,8 @@
 #include "StringIntMap.h"
 #include "Tokenizer.h"
 
-#define MAX_BYTES (1024 * 1024)
 #define ERROR_LENGTH 256
-#define VARS 256
+#define RETURN_BUFFER 16
 
 static jmp_buf errorJump;
 static char error[ERROR_LENGTH] = {'\0'};
@@ -23,6 +22,9 @@ static int varIndex = 0;
 static StringIntMap vars[2];
 static FunctionMap functions;
 
+static int returns[RETURN_BUFFER];
+static int returnIndex = 0;
+
 static void cError(const char* format, ...) {
     va_list args;
     va_start(args, format);
@@ -241,6 +243,10 @@ static void cFunctionInnerBody(int arguments) {
         cLine(t);
     }
     cAddPop(p, vars[1].entries);
+    for(int i = 0; i < returnIndex; i++) {
+        cSetInt(returns[i], vars[1].entries);
+    }
+    returnIndex = 0;
 }
 
 static void cFunctionBody(const char* name, int arguments) {
@@ -270,6 +276,16 @@ static void cFunction() {
     varIndex = 0;
 }
 
+static void cReturn() {
+    if(returnIndex >= RETURN_BUFFER) {
+        cError("too much returns in function around line %d", line);
+    }
+    cAddOperation(OP_POP);
+    returns[returnIndex++] = cReserveInt(vars);
+    cAddOperation(OP_RETURN);
+    cConsumeToken(T_SEMICOLON);
+}
+
 static void cPrint() {
     cExpression();
     cConsumeToken(T_SEMICOLON);
@@ -283,6 +299,7 @@ static void cLine(Token t) {
         case T_PRINT: cPrint(); break;
         case T_LITERAL: cLiteral(); break;
         case T_FUNCTION: cFunction(); break;
+        case T_RETURN: cReturn(); break;
         default: cUnexpectedToken(t);
     }
 }
@@ -297,6 +314,7 @@ static void cForEachLine() {
 
 static void cAllocAndCompile() {
     varIndex = 0;
+    returnIndex = 0;
     simInit(vars);
     simInit(vars + 1);
     fmInit(&functions);

+ 3 - 0
Tokenizer.c

@@ -80,6 +80,8 @@ static bool tParseLiteral(int c) {
         return tAddToken(T_FALSE);
     } else if(strcmp(buffer, "function") == 0) {
         return tAddToken(T_FUNCTION);
+    } else if(strcmp(buffer, "return") == 0) {
+        return tAddToken(T_RETURN);
     }
     return tAddToken(T_LITERAL) && tAdd(buffer, index + 1);
 }
@@ -236,6 +238,7 @@ const char* tGetTokenName(Token token) {
         case T_LITERAL: return "literal";
         case T_PRINT: return "print";
         case T_FUNCTION: return "function";
+        case T_RETURN: return "return";
         case T_COMMA: return ",";
         case T_SEMICOLON: return ";";
         case T_OPEN_BRACKET: return "(";

+ 1 - 0
Tokenizer.h

@@ -16,6 +16,7 @@ typedef enum Token {
     T_LITERAL,
     T_PRINT,
     T_FUNCTION,
+    T_RETURN,
     T_COMMA,
     T_SEMICOLON,
     T_OPEN_BRACKET,

+ 7 - 0
tests/functions/return

@@ -0,0 +1,7 @@
+function test() {
+    print 5;
+    return;
+    print 6;
+}
+
+test();

+ 1 - 0
tests/functions/return.out

@@ -0,0 +1 @@
+5