Module: MilkTea::Parse::Attributes

Included in:
MilkTea::Parser
Defined in:
lib/milk_tea/core/parser/attributes.rb

Instance Method Summary collapse

Instance Method Details

#consume_attribute_name_component(message) ⇒ Object



36
37
38
# File 'lib/milk_tea/core/parser/attributes.rb', line 36

def consume_attribute_name_component(message)
  consume_name_allowing_keywords(message)
end

#parse_attribute_applicationObject



21
22
23
24
25
26
# File 'lib/milk_tea/core/parser/attributes.rb', line 21

def parse_attribute_application
  start_token = peek
  name = parse_attribute_name
  arguments = match(:lparen) ? parse_call_arguments : []
  AST::AttributeApplication.new(name:, arguments:, line: start_token.line, column: start_token.column)
end

#parse_attribute_applicationsObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/milk_tea/core/parser/attributes.rb', line 6

def parse_attribute_applications
  attributes = []

  while match(:at)
    consume(:lbracket, "expected '[' after '@'")
    raise error(peek, "expected attribute in attribute list") if check(:rbracket)

    attributes.concat(parse_comma_separated_until(:rbracket) { parse_attribute_application })
    consume(:rbracket, "expected ']' after attributes")
    skip_newlines
  end

  attributes
end

#parse_attribute_nameObject



28
29
30
31
32
33
34
# File 'lib/milk_tea/core/parser/attributes.rb', line 28

def parse_attribute_name
  parts = [consume_attribute_name_component("expected attribute name").lexeme]
  while match(:dot)
    parts << consume_attribute_name_component("expected attribute name after '.'").lexeme
  end
  AST::QualifiedName.new(parts:)
end

#parse_struct_layout_attributes(attributes) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/milk_tea/core/parser/attributes.rb', line 40

def parse_struct_layout_attributes(attributes)
  packed = false
  alignment = nil

  attributes.each do |attribute|
    next unless attribute.name.parts.length == 1

    case attribute.name.parts.first
    when "packed"
      packed = true
    when "align"
      first_argument = attribute.arguments.first
      next unless first_argument && first_argument.name.nil? && first_argument.value.is_a?(AST::IntegerLiteral)

      alignment = first_argument.value.value
    end
  end

  [packed, alignment]
end

#reject_attributes!(attributes, kind_label = nil) ⇒ Object



61
62
63
64
65
66
# File 'lib/milk_tea/core/parser/attributes.rb', line 61

def reject_attributes!(attributes, kind_label = nil)
  return if attributes.empty?

  message = kind_label ? "attributes are not allowed on #{kind_label} declarations" : "attributes are not allowed on this declaration"
  raise error(peek, message)
end