Differences to erl_parse
In erlfmt_parse the following AST nodes have different definitions:
-
The record name is always represented as either a full
atomormacro_callnode instead of a raw atom. This affects the following AST nodes:{record, Anno, Name, Fields}{record, Anno, Expr, Name, Updates}{record_index, Anno, Name, Field}{record_field, Anno, Expr, Name, Field}{attribute, Anno, record, [Name, FieldsTuple]}
-
The value of an attribute node is always a list of abstract term formats instead of concrete terms. The name is always represented as a full
atomnode. -
The
clausenode has a different AST representation:{clause, Anno, Head, Guards, Body}, where theGuardselement is either an atomemptyor aguard_ornode, andHeadelement is one of:- regular
callnode for functions and named funs; - atom
emptyforifexpressions; {args, Anno, Args}node for an list of expressions wrapped in parentheses;{catch, Anno, Args}node for clauses incatchclauses, where 2 to 3 arguments represent the various:separated syntaxes;- other expression for
case,receive, "of" part oftryexpression and simplecatchclauses without:.
- regular
-
New
{spec_clause, Anno, Head, Body, Guards}node for clauses insidespecandcallbackattributes, similar to theclausenode above. It reflects the fact that in specs guards come after body. TheHeadelement is always anargsnode. -
New
{guard_or, Anno, GuardAndList}and{guard_and, Anno, Exprs}nodes are introduced to support annotating guard sequences, instead of a plain nested list of lists structure. -
The
functionnode has a different AST representation:{function, Anno, Clauses}, whereClausesis a list ofclausenodes ormacro_callnodes. Additionally it is less strict - it does not enforce all clauses have the same name and arity. -
The
funnode has a different AST representation:{'fun', Anno, Value}, whereValueis one of:{function, Anno, Name, Arity}, whereNameandArityare anatomandintegernode respectively orvarormacro_callnodes.{function, Anno, Module, Name, Arity}, whereModule,Name, andArityareatom,atom, andintegernodes respectively or avarormacro_callnode.{clauses, Anno, Clauses}, whereClausesis a list ofclausenodes. Additionally it is less strict - the clauses aren't checked for the same name or arity.typefor the anonymous function typefun().{type, Anno, Args, Res}for the anonymous function typefun((...Args) -> Res)whereArgsis aargsnode.
-
The
named_funnode is not used. -
A new node
{macro_call, Anno, Name, Args}is introduced, whereNameis either anatomor avarnode andArgsis a list of expressions, types, or specialopnodes with'when'operaor. -
A new operator node
{op, Anno, 'when', Expr, Guard}is introduced, used only as argument for a macro. It represents "free-standing"Expr when Guardexpressions as used, for example, in theassertMatchmacro. -
A new node
{macro_string, Anno, Name}is introduced, whereNameis either anatomor avarnode. It represents??Namemacro syntax. -
A new node
{concat, Anno, Concatables}, whereConcatablesis a list ofstring,var, andmacro_callnodes. This is used to represent implicit string concatenation, for example"foo" "bar". -
Attributes are not processed to convert the
fun/aritysyntax into tuples, they are left as theopnodes with the/operator. Additionally, theimportandexportattributes are not processed to convert theconsnode chains into lists and containlistnodes. -
Bit type definitions inside binaries are represented as full nodes instead of raw atoms and integers. The unit notation
unit:Intis represented with a{remote, Anno, {atom, Anno, unit}, Int}node. -
The special
matchnode is encoded as regular binary operator node. -
The special
catchnode is encoded as regular unary operator node. -
Lists are represented as a
listnode instead of a chain ofconsandnilnodes, similar to thetuplenode. The last element of the list can be aconsnode representing explicit consing syntax. -
Representation for types is in general the same as for corresponding values. The
typenode is not used at all. This means new binary operators inside types are defined:|,::, and... -
Comprehension nodes (
lc,mc,bc) always represent the expression(s) before||as a list, even for single-value comprehensions. For example,[X || X <- List]produces{lc, Anno, [X], Generators}and[I, -I || I <- List]produces{lc, Anno, [I, {op, _, '-', I}], Generators}. Inerl_parse, single-value comprehensions use a bare expression instead of a list.