Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5fd66ae0 authored by Jack Palevich's avatar Jack Palevich
Browse files

Improve address operator (unary &).

Until now the address operator only worked with simple variables.
Now it works with arbitrary expressions (that are lvalues or function
names). So for example this now works:

struct S { int a[10]};

int f(struct S* p) {
    return &p->a[3];
}
parent 91acb148
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -4450,10 +4450,8 @@ class Compiler : public ErrorSink {
                unary();
                doPointer();
            } else if (t == '&') {
                VariableInfo* pVI = VI(tok);
                pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType),
                        ET_RVALUE);
                next();
                unary();
                doAddressOf();
            } else if (t == EOF ) {
                error("Unexpected EOF.");
            } else if (t == ';') {
@@ -4656,6 +4654,16 @@ class Compiler : public ErrorSink {
        }
    }

    void doAddressOf() {
        Type* pR0 = pGen->getR0Type();
        bool isFuncPtr = pR0->tag == TY_POINTER && pR0->pHead->tag == TY_FUNC;
        if ((! isFuncPtr) && pGen->getR0ExpressionType() != ET_LVALUE) {
            error("Expected an lvalue");
        }
        Type* pR0Type = pGen->getR0Type();
        pGen->setR0ExpressionType(ET_RVALUE);
    }

    /* Recursive descent parser for binary operations.
     */
    void binaryOp(int level) {
@@ -5293,7 +5301,7 @@ class Compiler : public ErrorSink {

    void checkLVal() {
        if (pGen->getR0ExpressionType() != ET_LVALUE) {
            error("Expected an lval");
            error("Expected an lvalue");
        }
    }

+31 −0
Original line number Diff line number Diff line
void testStruct() {
    struct str {
        float x;
        float y;
    };

    struct str base;
    int index = 0;

    base.x = 10.0;
    struct str *s = &base;

    float *v = &(*s).x;
    float *v2 = &s[index].x;
    printf("testStruct: %g %g %g\n",base.x, *v, *v2);
}

void testArray() {
    int a[2];
    a[0] = 1;
    a[1] = 2;
    int* p = &a[0];
    int* p2 = a;
    printf("testArray: %d %d %d\n", a[0], *p, *p2);
}

int main() {
    testStruct();
    testArray();
    return 0;
}
+7 −0
Original line number Diff line number Diff line
@@ -469,6 +469,13 @@ testCopying: 37 == 37
testUnion: 1 == 0x3f800000
testArgs: (6, 8, 10, 12)
result: 6
""","""""")

    def testAddressOf(self):
        self.compileCheck(["-R", "data/addressOf.c"], """Executing compiled code:
testStruct: 10 10 10
testArray: 1 1 1
result: 0
""","""""")

def main():