kyleect / locks

A toy language branched from Lox to learn language implementation and tooling. Forked from loxcraft
https://kyleect.github.io/locks/#/docs
MIT License
0 stars 0 forks source link

Passing `instance.method` to a function causes OP_INVOKE #134

Closed kyleect closed 9 months ago

kyleect commented 9 months ago

Code

class Class {
  fn method() {}
}

fn test(value) {
  return value;
}

let instance = Class();
let method = instance.method;

test(method);

test(instance.method);

test(instance.method());

https://kyleect.github.io/locks/#/?code=MYGwhgzhAEDC5WgbwFDWgMwHbQLYFMAXACwHsATACgEpkBfFBlbaQ-CQygNzBAFd8tVOgBORPiJw9++ANyMUKEEWgBLLBzBZg+aAF44CCDXnLCeImXL61Gwlp0A6AiQryUbDpRdXq7z5zqmtr4zpYUfooBlEH2IWGuVNR+QA

Generated bytecode

0000 OP_CLASS            0 == 'Class'
0002 OP_DEFINE_GLOBAL    0 == 'Class'
0004 OP_GET_GLOBAL       0 == 'Class'
0006 OP_CLOSURE          1 == '<fn method arity=0>'
| 0000 OP_NIL
| 0001 OP_RETURN
0008 OP_METHOD           2 == 'method'
0010 OP_POP
0011 OP_CLOSURE          3 == '<fn test arity=1>'
| 0000 OP_GET_LOCAL        1
| 0002 OP_RETURN
0013 OP_DEFINE_GLOBAL    4 == 'test'
0015 OP_GET_GLOBAL       0 == 'Class'
0017 OP_CALL             0
0019 OP_DEFINE_GLOBAL    5 == 'instance'
0021 OP_GET_GLOBAL       5 == 'instance'
0023 OP_GET_PROPERTY     2 == 'method'
0025 OP_DEFINE_GLOBAL    2 == 'method'
0027 OP_GET_GLOBAL       4 == 'test'
0029 OP_GET_GLOBAL       2 == 'method'
0031 OP_CALL             1
0033 OP_POP
0034 OP_GET_GLOBAL       4 == 'test'
0036 OP_GET_GLOBAL       5 == 'instance'
0038 OP_INVOKE        (1 args)    2 'method'
0041 OP_POP
0042 OP_GET_GLOBAL       4 == 'test'
0044 OP_GET_GLOBAL       5 == 'instance'
0046 OP_INVOKE        (0 args)    2 'method'
0049 OP_CALL             1
0051 OP_POP
0052 OP_NIL
0053 OP_RETURN

Parsed AST

Program {
  stmts: [
    (
      StmtClass {
        name: "Class",
        super_: None,
        methods: [
          (
            StmtFn {
              name: "method",
              params: [],
              body: StmtBlock {
                stmts: [],
              },
            },
            204..218,
          ),
        ],
        fields: [],
      },
      188..220,
    ),
    (
      StmtFn {
        name: "test",
        params: [
          "value",
        ],
        body: StmtBlock {
          stmts: [
            (
              StmtReturn {
                value: Some(
                  (
                    ExprIdentifier {
                      identifier: Identifier {
                        name: "value",
                        depth: None,
                      },
                    },
                    248..253,
                  ),
                ),
              },
              241..254,
            ),
          ],
        },
      },
      222..256,
    ),
    (
      StmtAssign {
        identifier: Identifier {
          name: "instance",
          depth: None,
        },
        value: Some(
          (
            ExprCall {
              callee: (
                ExprIdentifier {
                  identifier: Identifier {
                    name: "Class",
                    depth: None,
                  },
                },
                273..278,
              ),
              args: [],
            },
            273..280,
          ),
        ),
      },
      258..281,
    ),
    (
      StmtAssign {
        identifier: Identifier {
          name: "method",
          depth: None,
        },
        value: Some(
          (
            ExprGet {
              object: (
                ExprIdentifier {
                  identifier: Identifier {
                    name: "instance",
                    depth: None,
                  },
                },
                295..303,
              ),
              name: "method",
            },
            295..310,
          ),
        ),
      },
      282..311,
    ),
    (
      StmtExpr {
        value: (
          ExprCall {
            callee: (
              ExprIdentifier {
                identifier: Identifier {
                  name: "test",
                  depth: None,
                },
              },
              313..317,
            ),
            args: [
              (
                ExprIdentifier {
                  identifier: Identifier {
                    name: "method",
                    depth: None,
                  },
                },
                318..324,
              ),
            ],
          },
          313..325,
        ),
      },
      313..326,
    ),
    (
      StmtExpr {
        value: (
          ExprCall {
            callee: (
              ExprIdentifier {
                identifier: Identifier {
                  name: "test",
                  depth: None,
                },
              },
              328..332,
            ),
            args: [
              (
                ExprGet {
                  object: (
                    ExprIdentifier {
                      identifier: Identifier {
                        name: "instance",
                        depth: None,
                      },
                    },
                    333..341,
                  ),
                  name: "method",
                },
                333..348,
              ),
            ],
          },
          328..349,
        ),
      },
      328..350,
    ),
    (
      StmtExpr {
        value: (
          ExprCall {
            callee: (
              ExprIdentifier {
                identifier: Identifier {
                  name: "test",
                  depth: None,
                },
              },
              352..356,
            ),
            args: [
              (
                ExprCall {
                  callee: (
                    ExprGet {
                      object: (
                        ExprIdentifier {
                          identifier: Identifier {
                            name: "instance",
                            depth: None,
                          },
                        },
                        357..365,
                      ),
                      name: "method",
                    },
                    357..372,
                  ),
                  args: [],
                },
                357..374,
              ),
            ],
          },
          352..375,
        ),
      },
      352..376,
    ),
  ],
}
kyleect commented 9 months ago

Fixed! I think this was the cause: https://github.com/kyleect/locks/pull/135/files#diff-23c5734d7de815d5e64ad2291873d96e9f686a8b11d76481f3d02c905c53341dL403