Explorar o código

references for floats and bools

Kajetan Johannes Hammerle %!s(int64=3) %!d(string=hai) anos
pai
achega
d4ccfa76cd

+ 26 - 11
Compiler.c

@@ -208,12 +208,20 @@ static DataType cCallFunction(const char* name) {
     return found->returnType;
 }
 
+static DataType cLoadRef(Variable* v, Operation op, DataType dt) {
+    cAddOperation(OP_LOAD_INT);
+    cAddInt(v->address);
+    cAddOperation(op);
+    return dt;
+}
+
 static DataType cLoadVariable(Variable* v) {
     if(dtCompare(v->type, dtToReference(dtInt()))) {
-        cAddOperation(OP_LOAD_INT);
-        cAddInt(v->address);
-        cAddOperation(OP_LOAD_INT_REF);
-        return dtInt();
+        return cLoadRef(v, OP_REF_LOAD_INT, dtInt());
+    } else if(dtCompare(v->type, dtToReference(dtFloat()))) {
+        return cLoadRef(v, OP_REF_LOAD_FLOAT, dtFloat());
+    } else if(dtCompare(v->type, dtToReference(dtBool()))) {
+        return cLoadRef(v, OP_REF_LOAD_BOOL, dtBool());
     }
     switch(dtAsInt(v->type)) {
         case DT_INT: cAddOperation(OP_LOAD_INT); break;
@@ -225,17 +233,24 @@ static DataType cLoadVariable(Variable* v) {
     return v->type;
 }
 
-static void cStoreVariable(Variable* v, DataType dt, const char* name) {
-    if(dtCompare(v->type, dtToReference(dtInt())) && dtCompare(dt, dtInt())) {
+static bool cStoreRef(Variable* v, DataType should, DataType dt, Operation op) {
+    if(dtCompare(v->type, dtToReference(should)) && dtCompare(dt, should)) {
         cAddOperation(OP_LOAD_INT);
         cAddInt(v->address);
-        cAddOperation(OP_STORE_INT_REF);
-        return;
+        cAddOperation(op);
+        return true;
     }
-    if(!dtCompare(v->type, dt)) {
+    return false;
+}
+
+static void cStoreVariable(Variable* v, DataType dt, const char* name) {
+    if(cStoreRef(v, dtInt(), dt, OP_REF_STORE_INT) ||
+       cStoreRef(v, dtFloat(), dt, OP_REF_STORE_FLOAT) ||
+       cStoreRef(v, dtBool(), dt, OP_REF_STORE_BOOL)) {
+        return;
+    } else if(!dtCompare(v->type, dt)) {
         cInvalidOperation(v->type, dt, name);
-    }
-    if(v->type.reference) {
+    } else if(v->type.reference) {
         cAddOperation(OP_STORE_INT);
         cAddInt(v->address);
         return;

+ 14 - 0
tests/struct/bool_reference

@@ -0,0 +1,14 @@
+void test(bool& t) {
+    t = true;
+}
+
+void main() {
+    bool a = true;
+    bool& b = &a;
+    a = false;
+    print a;
+    print b;
+    test(&a);
+    print a;
+    print b;
+}

+ 4 - 0
tests/struct/bool_reference.out

@@ -0,0 +1,4 @@
+false
+false
+true
+true

+ 15 - 0
tests/struct/float_reference

@@ -0,0 +1,15 @@
+void test(float& t) {
+    t = 8.0;
+    t += 1.0;
+}
+
+void main() {
+    float a = 5.0;
+    float& b = &a;
+    a = 6.0;
+    print a;
+    print b;
+    test(&a);
+    print a;
+    print b;
+}

+ 4 - 0
tests/struct/float_reference.out

@@ -0,0 +1,4 @@
+6.00
+6.00
+9.00
+9.00

+ 0 - 0
tests/struct/reference → tests/struct/int_reference


+ 0 - 0
tests/struct/reference.out → tests/struct/int_reference.out


+ 2 - 2
utils/ByteCodePrinter.c

@@ -110,6 +110,8 @@ static void btPrintFloat(const char* op) {
 #define PRINT_TYPES(TYPE)                                                      \
     PRINT_OP_INT(OP_LOAD_##TYPE);                                              \
     PRINT_OP_INT(OP_STORE_##TYPE);                                             \
+    PRINT_OP_INT(OP_REF_LOAD_##TYPE);                                          \
+    PRINT_OP_INT(OP_REF_STORE_##TYPE);                                         \
     PRINT_OP_INT(OP_RETURN_##TYPE);                                            \
     PRINT_OP(OP_EQUAL_##TYPE);
 
@@ -119,8 +121,6 @@ static void btConsumeOperation() {
         PRINT_TYPES(INT);
         PRINT_TYPES(BOOL);
         PRINT_TYPES(FLOAT);
-        PRINT_OP(OP_LOAD_INT_REF);
-        PRINT_OP(OP_STORE_INT_REF);
         PRINT_OP(OP_NOTHING);
         PRINT_OP_INT(OP_PUSH_INT);
         PRINT_OP_BASE(OP_PUSH_FLOAT, Float);

+ 2 - 2
vm/Operation.h

@@ -40,9 +40,9 @@ typedef enum Operation {
     TYPE_OPERATION(RETURN),
     OP_RESERVE,
     TYPE_OPERATION(LOAD),
-    OP_LOAD_INT_REF,
+    TYPE_OPERATION(REF_LOAD),
     TYPE_OPERATION(STORE),
-    OP_STORE_INT_REF,
+    TYPE_OPERATION(REF_STORE),
     OP_VAR_REF,
     OP_INT_ARRAY,
     OP_STORE_ARRAY

+ 17 - 3
vm/Script.c

@@ -306,6 +306,20 @@ static void sLoadIntRef(Script* sc) {
     }
 }
 
+static void sLoadFloatRef(Script* sc) {
+    int address = 0;
+    if(sPopInt(sc, &address) && sCheckAddress(sc, address, sizeof(float))) {
+        sPush(sc, sc->stack + address, sizeof(float));
+    }
+}
+
+static void sLoadBoolRef(Script* sc) {
+    int address = 0;
+    if(sPopInt(sc, &address) && sCheckAddress(sc, address, sizeof(bool))) {
+        sPush(sc, sc->stack + address, sizeof(bool));
+    }
+}
+
 #define CASE_NUMBER_OP(name, op)                                               \
     case OP_##name##_INT: NUMBER_OP(int, Int, op); break;                      \
     case OP_##name##_FLOAT:                                                    \
@@ -321,7 +335,9 @@ static void sLoadIntRef(Script* sc) {
     case OP_STORE_##TYPE: sStore(sc, sizeof(type)); break;                     \
     case OP_RETURN_##TYPE: RETURN(type, Type); break;                          \
     case OP_PRINT_##TYPE: PRINT(type, Type, type##Printer); break;             \
-    case OP_EQUAL_##TYPE: BOOL_OP(type, Type, ==); break;
+    case OP_EQUAL_##TYPE: BOOL_OP(type, Type, ==); break;                      \
+    case OP_REF_STORE_##TYPE: sStoreRef(sc, sizeof(type)); break;              \
+    case OP_REF_LOAD_##TYPE: sLoad##Type##Ref(sc); break;
 
 static void sConsumeInstruction(Script* sc) {
     switch(sReadOperation(sc)) {
@@ -333,8 +349,6 @@ static void sConsumeInstruction(Script* sc) {
         CASE_TYPE(INT, Int, int);
         CASE_TYPE(BOOL, Bool, bool);
         CASE_TYPE(FLOAT, Float, float);
-        case OP_LOAD_INT_REF: sLoadIntRef(sc); break;
-        case OP_STORE_INT_REF: sStoreRef(sc, sizeof(int)); break;
         case OP_NOTHING: break;
         case OP_PUSH_INT: PUSH_CONSTANT(int, Int); break;
         case OP_PUSH_FLOAT: PUSH_CONSTANT(float, Float); break;