Module: Kumi::Parser::Helpers

Included in:
DirectParser
Defined in:
lib/kumi/parser/helpers.rb

Instance Method Summary collapse

Instance Method Details

#advance_and_return_tokenObject



132
133
134
135
136
# File 'lib/kumi/parser/helpers.rb', line 132

def advance_and_return_token
  token = current_token
  advance
  token
end

#convert_literal_value(token) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/kumi/parser/helpers.rb', line 38

def convert_literal_value(token)
  case token.type
  when :integer  then token.value.gsub('_', '').to_i
  when :float    then token.value.gsub('_', '').to_f
  when :string   then token.value
  when :boolean  then token.value == 'true'
  when :symbol   then token.value.to_sym
  when :constant
    case token.value
    when 'Float::INFINITY' then Float::INFINITY
    else
      raise_parse_error("Unknown constant: #{token.value}")
    end
  end
end

#expect_field_name_tokenObject



114
115
116
117
118
119
120
121
122
# File 'lib/kumi/parser/helpers.rb', line 114

def expect_field_name_token
  token = current_token
  if token.identifier? || token.keyword?
    advance
    token.value
  else
    raise_parse_error("Expected field name (identifier or keyword), got #{token.type}")
  end
end

#map_operator_token_to_function_name(token_type) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/kumi/parser/helpers.rb', line 138

def map_operator_token_to_function_name(token_type)
  case token_type
  when :eq  then :==
  when :ne  then :!=
  when :gt  then :>
  when :lt  then :<
  when :gte then :>=
  when :lte then :<=
  when :and then :and
  when :or  then :or
  when :exponent then :power
  else token_type
  end
end

#next_is_kwarg_after_comma?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/kumi/parser/helpers.rb', line 124

def next_is_kwarg_after_comma?
  current_token.type == :comma && peek_token.type == :label
end

#parse_args_and_opts_inside_parensObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/kumi/parser/helpers.rb', line 77

def parse_args_and_opts_inside_parens
  args = []
  opts = {}

  # expect_token(:lparen)

  unless current_token.type == :rparen
    # --- positional args ---
    unless next_is_kwarg_after_comma?
      args << parse_expression
      while current_token.type == :comma && !next_is_kwarg_after_comma?
        advance
        args << parse_expression
      end
    end
    # --- kwargs (labels like `policy:`) ---
    if next_is_kwarg_after_comma?
      # subsequent pairs: `, label value`
      while current_token.type == :comma
        # stop if next token is not a kw key
        advance

        if current_token.type == :label
          key = current_token.value.to_sym
          advance
        end
        opts[key] = parse_kw_literal_value

        break unless next_is_kwarg_after_comma?
      end
    end
  end

  expect_token(:rparen)
  [args, opts]
end

#parse_kw_literal_valueObject



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/kumi/parser/helpers.rb', line 54

def parse_kw_literal_value
  t = current_token
  case t.type
  when :integer  then advance
                      t.value.delete('_').to_i
  when :float    then advance
                      t.value.delete('_').to_f
  when :string, :symbol then advance
                             t.value
  when :boolean  then advance
                      t.value == 'true'
  when :label    then advance
                      t.value.to_sym # :wrap, :clamp, etc.
  when :subtract # allow negatives like -1
    advance
    v = parse_kw_literal_value
    raise_parse_error("numeric after unary '-'") unless v.is_a?(Numeric)
    -v
  else
    raise_parse_error('keyword value must be literal/label')
  end
end

#parse_optional_decl_kwargsObject

Parses optional “, domain: …, index: :sym” (order-agnostic, both optional) Cursor is right after the array/hash/type name.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/kumi/parser/helpers.rb', line 6

def parse_optional_decl_kwargs
  domain = nil
  index  = nil

  # nothing to do
  return [domain, index] unless current_token.type == :comma

  # consume one or more ", key: value" pairs
  while current_token.type == :comma
    advance
    key_tok = current_token

    unless key_tok.type == :label && %w[domain index].include?(key_tok.value)
      # roll back gracefully if it's not a kw pair
      @pos -= 1
      break
    end

    advance

    case key_tok.value
    when 'domain'
      domain = parse_domain_specification
    when 'index'
      sym = expect_token(:symbol)
      index = sym.value.to_sym
    end
  end

  [domain, index]
end

#skip_comments_and_newlinesObject



128
129
130
# File 'lib/kumi/parser/helpers.rb', line 128

def skip_comments_and_newlines
  advance while %i[newline comment].include?(current_token.type)
end