Kajetan Johannes Hammerle 3 jaren geleden
bovenliggende
commit
ad260bdc31
11 gewijzigde bestanden met toevoegingen van 50 en 11 verwijderingen
  1. 8 3
      Compiler.c
  2. 11 1
      DataType.c
  3. 5 2
      DataType.h
  4. 0 1
      libraries/Time.c
  5. 11 0
      tests/types/null
  6. 3 0
      tests/types/null.out
  7. 2 2
      tokenizer/Token.c
  8. 1 1
      tokenizer/Token.h
  9. 1 0
      utils/ByteCodePrinter.c
  10. 1 0
      vm/Operation.h
  11. 7 1
      vm/Script.c

+ 8 - 3
Compiler.c

@@ -308,8 +308,12 @@ static DataType cCallFunction(const char* name) {
     return found->returnType;
 }
 
+static bool cCompare(DataType left, DataType right) {
+    return dtCompare(left, right) || (dtIsPointer(left) && dtIsNull(right));
+}
+
 static void cStore(DataType left, DataType right, const char* name) {
-    if(!dtCompare(left, right)) {
+    if(!cCompare(left, right)) {
         cInvalidOperation(left, right, name);
     } else if(dtIsPointer(left)) {
         cAddOperation(OP_STORE_POINTER);
@@ -372,6 +376,7 @@ static DataType cPrimary() {
         case T_CONST_FLOAT: cConstantFloat(); return dtFloat();
         case T_TRUE: cAddOperation(OP_PUSH_TRUE); return dtBool();
         case T_FALSE: cAddOperation(OP_PUSH_FALSE); return dtBool();
+        case T_NULLPTR: cAddOperation(OP_PUSH_NULLPTR); return dtNull();
         case T_OPEN_BRACKET: return cBracketPrimary();
         case T_LITERAL: return cLiteral();
         case T_NEW: return cAllocArray();
@@ -731,7 +736,7 @@ static void cReturn() {
         return;
     }
     DataType dt = cUnpackedExpression();
-    if(!dtCompare(dt, returnType)) {
+    if(!cCompare(returnType, dt)) {
         cError("wrong return type, should be %s", cGetName(returnType));
     } else if(dtIsInt(dt)) {
         cAddReturn(OP_RETURN_INT);
@@ -741,7 +746,7 @@ static void cReturn() {
         cAddReturn(OP_RETURN_BOOL);
     } else if(dtIsFloat(dt)) {
         cAddReturn(OP_RETURN_FLOAT);
-    } else if(dtIsPointer(dt)) {
+    } else if(dtIsPointer(dt) || dtIsNull(dt)) {
         cAddReturn(OP_RETURN_POINTER);
     } else {
         cError("cannot return %s", cGetName(dt));

+ 11 - 1
DataType.c

@@ -28,6 +28,7 @@ const char* dtGetName(Structs* sts, DataType dt) {
         case DT_LONG: dtAppend("long"); break;
         case DT_FLOAT: dtAppend("float"); break;
         case DT_BOOL: dtAppend("bool"); break;
+        case DT_NULL: dtAppend("null"); break;
         case DT_STRUCT: dtAppend(sts->data[dt.structId].name); break;
         case DT_VOID: dtAppend("void"); break;
         default: dtAppend("unknown");
@@ -39,7 +40,7 @@ const char* dtGetName(Structs* sts, DataType dt) {
 }
 
 int dtGetSize(DataType dt, Structs* sts) {
-    if(dt.pointers > 0) {
+    if(dt.pointers > 0 || dtIsNull(dt)) {
         return sizeof(Pointer);
     }
     switch(dt.type) {
@@ -80,6 +81,11 @@ DataType dtBool() {
     return dt;
 }
 
+DataType dtNull() {
+    DataType dt = {DT_NULL, 0, 0};
+    return dt;
+}
+
 DataType dtVoid() {
     DataType dt = {DT_VOID, 0, 0};
     return dt;
@@ -124,6 +130,10 @@ bool dtIsBool(DataType dt) {
     return dtCompare(dt, dtBool());
 }
 
+bool dtIsNull(DataType dt) {
+    return dtCompare(dt, dtNull());
+}
+
 bool dtIsVoid(DataType dt) {
     return dtCompare(dt, dtVoid());
 }

+ 5 - 2
DataType.h

@@ -7,8 +7,9 @@
 #define DT_LONG 1
 #define DT_FLOAT 2
 #define DT_BOOL 3
-#define DT_VOID 4
-#define DT_STRUCT 5
+#define DT_NULL 4
+#define DT_VOID 5
+#define DT_STRUCT 6
 
 typedef struct {
     unsigned int type : 4;
@@ -45,6 +46,7 @@ DataType dtInt();
 DataType dtLong();
 DataType dtFloat();
 DataType dtBool();
+DataType dtNull();
 DataType dtVoid();
 DataType dtStruct(Struct* st);
 
@@ -59,6 +61,7 @@ bool dtIsInt(DataType dt);
 bool dtIsLong(DataType dt);
 bool dtIsFloat(DataType dt);
 bool dtIsBool(DataType dt);
+bool dtIsNull(DataType dt);
 bool dtIsVoid(DataType dt);
 bool dtIsPointer(DataType dt);
 bool dtIsVariable(DataType dt);

+ 0 - 1
libraries/Time.c

@@ -1,5 +1,4 @@
 #include <errno.h>
-#include <stdio.h>
 #include <string.h>
 #include <time.h>
 

+ 11 - 0
tests/types/null

@@ -0,0 +1,11 @@
+int** test() {
+    return nullptr;
+}
+
+void main() {
+    int** b = test();
+    int*** c = &b;
+    print b == *c;
+    print length(b);
+    print length(c);
+}

+ 3 - 0
tests/types/null.out

@@ -0,0 +1,3 @@
+true
+0
+1

+ 2 - 2
tokenizer/Token.c

@@ -14,7 +14,7 @@ const char* tGetName(Token token) {
         case T_CONST_LONG: return "const long";
         case T_CONST_FLOAT: return "const float";
         case T_TEXT: return "text";
-        case T_NULL: return "null";
+        case T_NULLPTR: return "nullptr";
         case T_TRUE: return "true";
         case T_FALSE: return "false";
         case T_ADD: return "+";
@@ -85,7 +85,7 @@ const char* tGetName(Token token) {
 
 Token tFromName(const char* name) {
     MATCH_TOKEN("print", T_PRINT);
-    MATCH_TOKEN("null", T_NULL);
+    MATCH_TOKEN("nullptr", T_NULLPTR);
     MATCH_TOKEN("true", T_TRUE);
     MATCH_TOKEN("false", T_FALSE);
     MATCH_TOKEN("return", T_RETURN);

+ 1 - 1
tokenizer/Token.h

@@ -11,7 +11,7 @@ typedef enum {
     T_CONST_LONG,
     T_CONST_FLOAT,
     T_TEXT,
-    T_NULL,
+    T_NULLPTR,
     T_TRUE,
     T_FALSE,
     T_ADD,

+ 1 - 0
utils/ByteCodePrinter.c

@@ -157,6 +157,7 @@ static void btConsumeOperation() {
         PRINT_OP_BASE(OP_PUSH_FLOAT, Float);
         PRINT_OP(OP_PUSH_TRUE);
         PRINT_OP(OP_PUSH_FALSE);
+        PRINT_OP(OP_PUSH_NULLPTR);
         PRINT_NUMBER_OP(ADD);
         PRINT_NUMBER_OP(SUB);
         PRINT_NUMBER_OP(MUL);

+ 1 - 0
vm/Operation.h

@@ -13,6 +13,7 @@ typedef enum Operation {
     OP_NUMBER(PUSH),
     OP_PUSH_TRUE,
     OP_PUSH_FALSE,
+    OP_PUSH_NULLPTR,
     OP_NUMBER(ADD),
     OP_NUMBER(SUB),
     OP_NUMBER(MUL),

+ 7 - 1
vm/Script.c

@@ -164,6 +164,11 @@ static bool sPushPointer(Script* sc, Pointer* value) {
     return sPush(sc, value, sizeof(Pointer));
 }
 
+static void sPushNullPointer(Script* sc) {
+    Pointer p = {-1, -1};
+    sPushPointer(sc, &p);
+}
+
 static void sPrintPointer(Script* sc) {
     Pointer p;
     if(sPopPointer(sc, &p)) {
@@ -352,7 +357,7 @@ static void sLength(Script* sc) {
     Pointer p;
     if(sPopPointer(sc, &p)) {
         if(p.array == -1) {
-            sPushInt(sc, 1);
+            sPushInt(sc, p.offset >= 0);
             return;
         }
         Array* a = asGet(&sc->arrays, p.array);
@@ -512,6 +517,7 @@ static void sConsumeInstruction(Script* sc) {
         case OP_PUSH_FLOAT: PUSH_CONSTANT(float, Float); break;
         case OP_PUSH_TRUE: sPushBool(sc, true); break;
         case OP_PUSH_FALSE: sPushBool(sc, false); break;
+        case OP_PUSH_NULLPTR: sPushNullPointer(sc); break;
         case OP_DIV_INT: DIVISION(int, Int); break;
         case OP_DIV_LONG: DIVISION(long, Long); break;
         case OP_DIV_FLOAT: DIVISION(float, Float); break;