class Savi::AST::Group

Overview

A Group is a list of Terms with a particular "style" indicated. A parenthesized group in a function call like this will have style == "(":

Settings.read(content, true) ^~~~~~~ ^~~~ (terms) ^~~~~~~~~~~~~~~ (group)

Less commonly, parenthesized Groups can also be used to specify a sequence of statements to execute, separated by commas and/or newlines, with the result value of the Group being the value of the last statement in it:

double_content = (content = half_1 + half_2, content + content) ^~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~ (terms) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (group)

Such Groups can be further delineated into sections separated by a pipe |, which form an AST with a root Group whose style == "|", each Term of which is a sub-Group whose style == "(". This is commonly used in control flow macros prior to their macro result being expanded, such as in the following example of an try macro prior to expansion:

try (settings.get!("dark_mode") | settings.put("dark_mode"), False) ^~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~ (terms of sub-groups) ^~~~~~~~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (sub-groups as terms) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (group)

Array literals are represented as a Group with style == "[", with each term in the Group being an element of the array being constructed:

example Array(U8)'val = ['h', 'e', 'l', 'l', 'o', '/n'] ^ ^ ^ ^ ^ ^~ (terms) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (group)

The same style is also used in [] and []! method call sugar, prior to the Sugar pass in which it is turned into an Identifier and Qualify. The following example shows a style == "[" Group on the left and a style == "[!" Group on the right side of the assignment, prior to Sugar:

settings["dark_mode"] = try (settings["dark_mode"]! | False) ^~~~~~~~~~~~~ ^~~~~~~~~~~~~~ (style == "[") (style == "[!")

Lastly, a Group with style == " " is used for whitespace-separated Terms, such as the type declaration of a local variable or as commonly used in control flow macros prior to their macro expansion:

body_size USize = if (body <: String) (body.size | 0) ^~~~~~~~~ ^~~~~ ^~ ^~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (style == " ") (style == " ")

As you can see, we try to avoid specifying what the meaning of a Group is in the early AST, and only indicate its syntactical "style" since the actual semantics of the node may not be known until a later Pass, where we are able to take into account sugar and macro expansion to resolve them.

Defined in:

savi/ast.cr

Constructors

Instance Method Summary

Instance methods inherited from class Savi::AST::Node

accept(ctx : Compiler::Context, visitor : Visitor)
accept(ctx : Compiler::Context, visitor : CopyOnMutateVisitor)
accept
, annotations : Array(Annotation) | Nil annotations, annotations=(annotations : Array(Annotation) | Nil) annotations=, children_accept(ctx : Compiler::Context, visitor : Visitor)
children_accept(ctx : Compiler::Context, visitor : CopyOnMutateVisitor)
children_accept
, from(other : Node) from, pos pos, pos? : Savi::Source::Pos? pos?, span_pos(source) span_pos, with_pos(pos : Source::Pos) with_pos

Constructor Detail

def self.new(style : String, terms : Array(Savi::AST::Node) = [] of Term) #

[View source]

Instance Method Detail

def children_accept(ctx : Compiler::Context, visitor : Visitor) #

[View source]
def children_accept(ctx : Compiler::Context, visitor : CopyOnMutateVisitor) #

[View source]
def declare_depth : Int32 #

[View source]
def declare_depth=(declare_depth : Int32) #

[View source]
def name #

[View source]
def span_pos(source) #

[View source]
def style : String #

[View source]
def style=(style : String) #

[View source]
def terms : Array(Term) #

[View source]
def terms=(terms : Array(Term)) #

[View source]
def to_a : Array(A) #

[View source]