Prechádzať zdrojové kódy

int references as function arguments

Kajetan Johannes Hammerle 3 rokov pred
rodič
commit
32a0e67f9f

+ 9 - 0
Compiler.c

@@ -226,6 +226,12 @@ static DataType cLoadVariable(Variable* v) {
 }
 
 static void cStoreVariable(Variable* v, DataType dt, const char* name) {
+    if(dtCompare(v->type, dtToReference(dtInt())) && dtCompare(dt, dtInt())) {
+        cAddOperation(OP_LOAD_INT);
+        cAddInt(v->address);
+        cAddOperation(OP_STORE_INT_REF);
+        return;
+    }
     if(!dtCompare(v->type, dt)) {
         cInvalidOperation(v->type, dt, name);
     }
@@ -878,6 +884,9 @@ static void cFunctionCommaOrEnd(Function* f) {
 }
 
 static void cFunctionAddArgument(Function* f, DataType dt) {
+    if(cConsumeTokenIf(T_BIT_AND)) {
+        dt = dtToReference(dt);
+    }
     cConsumeToken(T_LITERAL);
     const char* name = cReadString();
     Variable* v = vSearchScope(&vars, name);

+ 7 - 0
tests/struct/reference

@@ -1,7 +1,14 @@
+void test(int& t) {
+    t = 9;
+}
+
 void main() {
     int a = 5;
     int& b = &a;
     a = 6;
     print a;
     print b;
+    test(&a);
+    print a;
+    print b;
 }

+ 2 - 0
tests/struct/reference.out

@@ -1,2 +1,4 @@
 6
 6
+9
+9

+ 1 - 0
utils/ByteCodePrinter.c

@@ -120,6 +120,7 @@ static void btConsumeOperation() {
         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);

+ 1 - 0
vm/Operation.h

@@ -42,6 +42,7 @@ typedef enum Operation {
     TYPE_OPERATION(LOAD),
     OP_LOAD_INT_REF,
     TYPE_OPERATION(STORE),
+    OP_STORE_INT_REF,
     OP_VAR_REF,
     OP_INT_ARRAY,
     OP_STORE_ARRAY

+ 8 - 0
vm/Script.c

@@ -198,6 +198,13 @@ static void sStore(Script* sc, int length) {
     }
 }
 
+static void sStoreRef(Script* sc, int length) {
+    int address = -1;
+    if(sPopInt(sc, &address) && sCheckAddress(sc, address, length)) {
+        sPop(sc, sc->stack + address, length);
+    }
+}
+
 static void sNot(Script* sc) {
     bool value = false;
     if(sPopBool(sc, &value)) {
@@ -327,6 +334,7 @@ static void sConsumeInstruction(Script* sc) {
         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;