Understanding how guard clauses are parsed, using that AST

54 views
Skip to first unread message

Brian Cardarella

unread,
Mar 9, 2017, 6:42:29 AM3/9/17
to elixir-lang-core
If I quote the following:


Code.string_to_quoted """
  if foo do
    "true"
  else
    "false"
  end
"""

I get the following AST:

{:if, [line: 1], [{:foo, [line: 1], nil}, [do: "true", else: "false"]]}

Which makes sense to me as the last node is a list. However, `when` seems to follow different rules and I'm not following exactly how Elixir parses it from the AST:

Code.strig_to_quoted """
  def foo(bar) when bar == 1 do
    "baz"
  end
"""

{:def, [line: 1],
 [{:when, [line: 1],
   [{:foo, [line: 1], [{:bar, [line: 1], nil}]},
    {:==, [line: 1], [{:bar, [line: 1], nil}, 1]}]}, [do: "baz"]]}

`when` is not in that last list, but is now the first element in the values for `:def`

Can someone point me to examples of how Elixir is parsing `when` within the source? I dug around in Kernel which brought me to elixir_def but got stuck there.

Use case: I am experimenting with writing some macro functions that could take guard clauses.

Michał Muskała

unread,
Mar 9, 2017, 6:50:45 AM3/9/17
to elixir-lang-core
when is an operator - it behaves very similar to operators like == or in.

iex(1)> quote(do: 1 when 2)
{:when, [], [1, 2]}
iex(2)> quote(do: 1 == 2)
{:==, [context: Elixir, import: Kernel], [1, 2]}

In case of def, the left side (of the operator) is the call and right the guards.

Michał.

Brian Cardarella

unread,
Mar 9, 2017, 6:53:22 AM3/9/17
to elixir-lang-core
Ah, that explains everything! Thank you :)
Reply all
Reply to author
Forward
0 new messages