I was looking at the syntax of Pharo Smalltalk, and was wondering how is precedence of binary messages implemented.
How does one go about declaring such a binary message?
How does the system figure out the precedence over unary messages?
Yes, you can look at the number class for example. It has a lot of binary messages there. Or consider this method of Object
:
-> anObject
^ Association basicNew key: self value: anObject
This allows you to evaluate 'five' -> 5
and get an association.
This is done by a parser. So first of all it looks for keyword messages, then binary, then unary, then parents.
So if you have
collection add: 'five' -> 5
The parser will first of all parse add:
with receiver collection
then it parses 'five' -> 5
and puts it a a parameter of add:
. This way the AST is composed in the way that keyword messages are more general and will be executed after their attributes are computed
In the latest versions of Pharo the parsing is done with RBParser
(same parser used previously for refactoring). Keyword messages are parsed with parseKeywordMessage
and binary with parseBinaryMessage
. The easies way to explore would be to put a one time breakpoint on parseBinaryMessage
and execute something like
RBParser parseExpression: 'coll add: #five -> 5'
The debugger will stop on parseBinaryMessage
so you can look at the stack and see how it is working. Pay attention, breaking once is important, otherwise you will get a debugger every time you compile a method or so on.