Bystroushaak / tinySelf

Self-like language implemented in the RPython language toolkit.
29 stars 3 forks source link

Cascading operator fails under rpython #120

Closed Bystroushaak closed 5 years ago

Bystroushaak commented 5 years ago

It doesn't raise error, but sends the second message to self, instead of the object that should be receiver.

Bystroushaak commented 5 years ago
bystrousak:~/Plocha/Syncthing/c0d3z/self/tinySelf,0$ ./tSelf tests/scripts/unittest.self 
Error: 'Missing slot `addOne` on (line 59):

(| o. |
        o: (| state <- 0.
              addOne = (|| state: state + 1. ). |).

        assert: [ o state == 0 ].

        o addOne.

        assert: [o state == 1 ].

        o addOne;
          addOne.

        assert: [o state == 3 ].

Failed at bytecode number 93
(|
  literals = (| l <- dict clone. |
    l
      at: 0 Put: "ObjBox(Object(slots={state: IntNumber(0), state:: AssignmentPrimitive(), addOne: Object(code=[Send(obj=Self(), msg=KeywordMessage(name=state:, parameters=[Send(obj=Send(obj=Self(), msg=Message(state)), msg=BinaryMessage(name=+, parameter=IntNumber(1)))]))])}))";
      at: 1 Put: "StrBox(state)";
      at: 2 Put: "IntBox(0)";
      at: 3 Put: "StrBox(state:)";
      at: 4 Put: "StrBox(addOne)";
      at: 5 Put: "ObjBox(Object(code=[Send(obj=Self(), msg=KeywordMessage(name=state:, parameters=[Send(obj=Send(obj=Self(), msg=Message(state)), msg=BinaryMessage(name=+, parameter=IntNumber(1)))]))]))";
      at: 6 Put: "StrBox(o:)";
      at: 7 Put: "ObjBox(Block(code=[Send(obj=Send(obj=Send(obj=Self(), msg=Message(o)), msg=Message(state)), msg=BinaryMessage(name===, parameter=IntNumber(0)))]))";
      at: 8 Put: "StrBox(assert:)";
      at: 9 Put: "StrBox(o)";
      at: 10 Put: "ObjBox(Block(code=[Send(obj=Send(obj=Send(obj=Self(), msg=Message(o)), msg=Message(state)), msg=BinaryMessage(name===, parameter=IntNumber(1)))]))";
      at: 11 Put: "ObjBox(Block(code=[Send(obj=Send(obj=Send(obj=Self(), msg=Message(o)), msg=Message(state)), msg=BinaryMessage(name===, parameter=IntNumber(3)))]))".
  ).

  disassembled = (||
    ("0", "PUSH_SELF"), 
    ("1", "PUSH_LITERAL", "type:OBJ", "index:0"), 
    ("4", "PUSH_LITERAL", "type:STR", "index:1"), 
    ("7", "PUSH_LITERAL", "type:INT", "index:2"), 
    ("10", "ADD_SLOT", "type:SLOT_NORMAL"), 
    ("12", "PUSH_LITERAL", "type:STR", "index:3"), 
    ("15", "PUSH_LITERAL", "type:ASSIGNMENT", "index:0"), 
    ("18", "ADD_SLOT", "type:SLOT_NORMAL"), 
    ("20", "PUSH_LITERAL", "type:STR", "index:4"), 
    ("23", "PUSH_LITERAL", "type:OBJ", "index:5"), 
    ("26", "ADD_SLOT", "type:SLOT_NORMAL"), 
    ("28", "PUSH_LITERAL", "type:STR", "index:6"), 
    ("31", "SEND", "type:KEYWORD", "params:1"), 
    ("34", "PUSH_SELF"), 
    ("35", "PUSH_SELF"), 
    ("36", "PUSH_LITERAL", "type:BLOCK", "index:7"), 
    ("39", "PUSH_LITERAL", "type:STR", "index:8"), 
    ("42", "SEND", "type:KEYWORD", "params:1"), 
    ("45", "PUSH_SELF"), 
    ("46", "PUSH_LITERAL", "type:STR", "index:9"), 
    ("49", "SEND", "type:UNARY", "params:0"), 
    ("52", "PUSH_LITERAL", "type:STR", "index:4"), 
    ("55", "SEND", "type:UNARY", "params:0"), 
    ("58", "PUSH_SELF"), 
    ("59", "PUSH_SELF"), 
    ("60", "PUSH_LITERAL", "type:BLOCK", "index:10"), 
    ("63", "PUSH_LITERAL", "type:STR", "index:8"), 
    ("66", "SEND", "type:KEYWORD", "params:1"), 
    ("69", "PUSH_SELF"), 
    ("70", "PUSH_LITERAL", "type:STR", "index:9"), 
    ("73", "SEND", "type:UNARY", "params:0"), 
    ("76", "PUSH_LITERAL", "type:STR", "index:4"), 
    ("79", "SEND", "type:UNARY", "params:0"), 
    ("82", "PUSH_SELF"), 
    ("83", "PUSH_LITERAL", "type:STR", "index:9"), 
    ("86", "SEND", "type:UNARY", "params:0"), 
    ("89", "PUSH_SELF"), 
    ("90", "PUSH_LITERAL", "type:STR", "index:4"), 
    ("93", "SEND", "type:UNARY", "params:0"), 
    ("96", "PUSH_SELF"), 
    ("97", "PUSH_SELF"), 
    ("98", "PUSH_LITERAL", "type:BLOCK", "index:11"), 
    ("101", "PUSH_LITERAL", "type:STR", "index:8"), 
    ("104", "SEND", "type:KEYWORD", "params:1"), 
    ("107", "RETURN_TOP"), 
    ("108", "RETURN_TOP"), 
    ("109", "RETURN_TOP"), 
    ("110", "RETURN_TOP")
  ).

  bytecodes = (||
    2, 3, 3, 0, 3, 2, 1, 3, 1, 2, 4, 0, 3, 2, 3, 3, 6, 0, 4, 0, 3, 2, 4, 3, 3, 5, 4, 0, 3, 2, 6, 0, 2, 1, 2, 2, 3, 5, 7, 3, 2, 8, 0, 2, 1, 2, 3, 2, 9, 0, 0, 0, 3, 2, 4, 0, 0, 0, 2, 2, 3, 5, 10, 3, 2, 8, 0, 2, 1, 2, 3, 2, 9, 0, 0, 0, 3, 2, 4, 0, 0, 0, 2, 3, 2, 9, 0, 0, 0, 2, 3, 2, 4, 0, 0, 0, 2, 2, 3, 5, 11, 3, 2, 8, 0, 2, 1, 5, 5, 5, 5
  ).
|)'
Bystroushaak commented 5 years ago

For some reason this works correctly when running under cpython or pypy.

Bystroushaak commented 5 years ago

Compilation -c of most simple program:

o addOne;
  addOne.

CPython 2.7:

(|
  literals = (| l <- dict clone. |
    l
      at: 0 Put: "StrBox(o)";
      at: 1 Put: "StrBox(addOne)".
  ).

  disassembled = (||
    ("0", "PUSH_SELF"), 
    ("1", "PUSH_LITERAL", "type:STR", "index:0"), 
    ("4", "SEND", "type:UNARY", "params:0"), 
    ("7", "PUSH_LITERAL", "type:STR", "index:1"), 
    ("10", "SEND", "type:UNARY", "params:0"), 
    ("13", "PUSH_SELF"), 
    ("14", "PUSH_LITERAL", "type:STR", "index:0"), 
    ("17", "SEND", "type:UNARY", "params:0"), 
    ("20", "PUSH_LITERAL", "type:STR", "index:1"), 
    ("23", "SEND", "type:UNARY", "params:0"), 
    ("26", "RETURN_TOP"), 
    ("27", "RETURN_TOP"), 
    ("28", "RETURN_TOP"), 
    ("29", "RETURN_TOP")
  ).

  bytecodes = (||
    2, 3, 2, 0, 0, 0, 0, 3, 2, 1, 0, 0, 0, 2, 3, 2, 0, 0, 0, 0, 3, 2, 1, 0, 0, 0, 5, 5, 5, 5
  ).
|)

tSelf compiled by rpython:

(|
  literals = (| l <- dict clone. |
    l
      at: 0 Put: "StrBox(o)";
      at: 1 Put: "StrBox(addOne)".
  ).

  disassembled = (||
    ("0", "PUSH_SELF"), 
    ("1", "PUSH_LITERAL", "type:STR", "index:0"), 
    ("4", "SEND", "type:UNARY", "params:0"), 
    ("7", "PUSH_LITERAL", "type:STR", "index:1"), 
    ("10", "SEND", "type:UNARY", "params:0"), 
    ("13", "PUSH_SELF"), 
    ("14", "PUSH_LITERAL", "type:STR", "index:0"), 
    ("17", "SEND", "type:UNARY", "params:0"), 
    ("20", "PUSH_SELF"), 
    ("21", "PUSH_LITERAL", "type:STR", "index:1"), 
    ("24", "SEND", "type:UNARY", "params:0"), 
    ("27", "RETURN_TOP"), 
    ("28", "RETURN_TOP"), 
    ("29", "RETURN_TOP"), 
    ("30", "RETURN_TOP")
  ).

  bytecodes = (||
    2, 3, 2, 0, 0, 0, 0, 3, 2, 1, 0, 0, 0, 2, 3, 2, 0, 0, 0, 0, 2, 3, 2, 1, 0, 0, 0, 5, 5, 5, 5
  ).
|)

Diff:

--- py.txt  2019-08-18 23:27:40.352722446 +0200
+++ tself.txt   2019-08-18 23:27:36.316869262 +0200
@@ -14,15 +14,16 @@
     ("13", "PUSH_SELF"), 
     ("14", "PUSH_LITERAL", "type:STR", "index:0"), 
     ("17", "SEND", "type:UNARY", "params:0"), 
-    ("20", "PUSH_LITERAL", "type:STR", "index:1"), 
-    ("23", "SEND", "type:UNARY", "params:0"), 
-    ("26", "RETURN_TOP"), 
+    ("20", "PUSH_SELF"), 
+    ("21", "PUSH_LITERAL", "type:STR", "index:1"), 
+    ("24", "SEND", "type:UNARY", "params:0"), 
     ("27", "RETURN_TOP"), 
     ("28", "RETURN_TOP"), 
-    ("29", "RETURN_TOP")
+    ("29", "RETURN_TOP"), 
+    ("30", "RETURN_TOP")
   ).

   bytecodes = (||
-    2, 3, 2, 0, 0, 0, 0, 3, 2, 1, 0, 0, 0, 2, 3, 2, 0, 0, 0, 0, 3, 2, 1, 0, 0, 0, 5, 5, 5, 5
+    2, 3, 2, 0, 0, 0, 0, 3, 2, 1, 0, 0, 0, 2, 3, 2, 0, 0, 0, 0, 2, 3, 2, 1, 0, 0, 0, 5, 5, 5, 5
   ).
 |)
Bystroushaak commented 5 years ago

Problem is caused by the additional push self (instruction 20).

Bystroushaak commented 5 years ago

Ast for cpython:

Cascade(
    obj=Send(
        obj=Self(),
        msg=Message(o)
    ),
    msgs=[
        Message(addOne),
        Message(addOne)
    ]
)

AST for RPython:

Cascade(
    obj=Send(
        obj=Self(),
        msg=Message(o)
    ),
    msgs=[
        Message(addOne),
        Send(
            obj=Self(),
            msg=Message(addOne)
        )
    ]
)

So probably parser bug?

Bystroushaak commented 5 years ago

/pypy/rpython/bin/rpython shebang: #!/usr/bin/env pypy

Bystroushaak commented 5 years ago

pypy src/target.py -a test_cascading_operator.tself results in:

Cascade(
    obj=Send(
        obj=Self(),
        msg=Message(o)
    ),
    msgs=[
        Message(addOne),
        Message(addOne)
    ]
)
Bystroushaak commented 5 years ago

Hypothesis:

Bystroushaak commented 5 years ago
$ pip freeze | grep rply
rply==0.7.7
$ pypy -m pip freeze | grep rply
rply==0.7.7
Bystroushaak commented 5 years ago

Ok, so bug is in the parse_cascade_messages() in parser.py where the AST's Self's .__eq__() is not called. Wtf.