kumi-parser 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e8f52b91ed0f66c7bdc49935483a81a5f329cec5ef5914555a57c6200b48ad7
4
- data.tar.gz: 3b52cc1430c0924cfc4a88f7facb2f022f51ef91ffdc94441b073d2dbde1866e
3
+ metadata.gz: 7dbd29c99827160178d8ebaebc68ada7b754f2ecdbc99d5c204dc6396431e18f
4
+ data.tar.gz: cef86a4ebd6b3398d70255a9111832ad9094626da74936e3d858fcba41999efa
5
5
  SHA512:
6
- metadata.gz: 28dbc7918ed27110f6922286d36151ee00867a2a3d2afb8b20895fe12ddff5c3695b7dfa17058ce6a3638ddb43ca673661c85e586f31a6be4e94a7ea6364a1d7
7
- data.tar.gz: 74e0285aa3c6df1b0a41dd6ace23f60421202835f3d864089bcbc6fa6594dc6f0bc25b4db429cfff2880b633e63836e8b402195ce5db2e9d312cf5c622688fbf
6
+ metadata.gz: af373812dec2bc63ffa5279d5f7adbd2c852f272969dcec65196ddca750d965dbe8b37496f99004975e1a2dbbabac3e7f5cfc5e348bd16b51b2a1261315b97eb
7
+ data.tar.gz: b3faf218a65da205f4f20651e808dcbfc32bd8ace3a63a479aa576909bcb0f0e9ea066fab04d8013a4046faaa0332a8cf5e223f8f785d8652518d7b89134168e
data/README.md CHANGED
@@ -58,7 +58,15 @@ end
58
58
 
59
59
  **Function calls**: `fn(:name, arg1, arg2, ...)`
60
60
  **Operators**: `+` `-` `*` `/` `%` `>` `<` `>=` `<=` `==` `!=` `&` `|`
61
- **References**: `input.field`, `value_name`, `array[index]`
61
+ **References**: `input.field`, `value_name`, `array[index]`
62
+ **Strings**: Both `"double"` and `'single'` quotes supported
63
+ **Element syntax**: `element :type, :name` for array element specifications
64
+
65
+ ## Ruby DSL Differences
66
+
67
+ **String concatenation**: Ruby DSL evaluates `"Hello" + "World"` → `Literal("HelloWorld")`, text parser → `CallExpression(:add, [...])`.
68
+
69
+ **Semantically equivalent** - both should execute identically.
62
70
 
63
71
  ## Architecture
64
72
 
@@ -66,8 +74,6 @@ end
66
74
  - `direct_ast_parser.rb` - Recursive descent parser, direct AST construction
67
75
  - `token_metadata.rb` - Token types, precedence, and semantic hints
68
76
 
69
- See `docs/` for technical details.
70
-
71
77
  ## License
72
78
 
73
79
  MIT
@@ -110,7 +110,17 @@ module Kumi
110
110
  end
111
111
 
112
112
  advance
113
- name_token = expect_token(:symbol)
113
+
114
+ # Handle element syntax: element :type, :name
115
+ if type_token.metadata[:type_name] == :element
116
+ element_type_token = expect_token(:symbol)
117
+ expect_token(:comma)
118
+ name_token = expect_token(:symbol)
119
+ actual_type = element_type_token.value
120
+ else
121
+ name_token = expect_token(:symbol)
122
+ actual_type = type_token.metadata[:type_name]
123
+ end
114
124
 
115
125
  # Handle domain specification: ', domain: [...]'
116
126
  domain = nil
@@ -126,9 +136,9 @@ module Kumi
126
136
  end
127
137
  end
128
138
 
129
- # Handle nested array and hash declarations
139
+ # Handle nested array, hash, and element declarations
130
140
  children = []
131
- if %i[array hash].include?(type_token.metadata[:type_name]) && current_token.type == :do
141
+ if %i[array hash element].include?(actual_type) && current_token.type == :do
132
142
  advance # consume 'do'
133
143
  skip_comments_and_newlines
134
144
 
@@ -147,7 +157,7 @@ module Kumi
147
157
  Kumi::Syntax::InputDeclaration.new(
148
158
  name_token.value,
149
159
  domain,
150
- type_token.metadata[:type_name],
160
+ actual_type,
151
161
  children,
152
162
  loc: type_token.location
153
163
  )
@@ -155,7 +165,7 @@ module Kumi
155
165
  Kumi::Syntax::InputDeclaration.new(
156
166
  name_token.value,
157
167
  domain,
158
- type_token.metadata[:type_name],
168
+ actual_type,
159
169
  children,
160
170
  :field,
161
171
  loc: type_token.location
@@ -273,18 +283,35 @@ module Kumi
273
283
  Kumi::Syntax::CascadeExpression.new(cases, loc: start_token.location)
274
284
  end
275
285
 
276
- # Case expression: 'on condition, result' or 'base result'
286
+ # Case expression: 'on condition1, condition2, ..., result' or 'base result'
277
287
  def parse_case_expression
278
288
  case current_token.type
279
289
  when :on
280
290
  on_token = advance_and_return_token
281
- condition = parse_expression
282
-
283
- # Wrap simple trait references in cascade_and to match Ruby DSL behavior
284
- condition = wrap_condition_in_all(condition) if simple_trait_reference?(condition)
285
-
286
- expect_token(:comma)
287
- result = parse_expression
291
+
292
+ # Parse all comma-separated expressions
293
+ expressions = []
294
+ expressions << parse_expression
295
+
296
+ # Continue parsing comma-separated expressions until end of case
297
+ while current_token.type == :comma
298
+ advance # consume comma
299
+ expressions << parse_expression
300
+ end
301
+
302
+ # Last expression is the result, all others are conditions
303
+ result = expressions.pop
304
+ conditions = expressions
305
+
306
+ # Combine conditions appropriately
307
+ if conditions.length == 1
308
+ condition = conditions[0]
309
+ # Wrap simple trait references in cascade_and to match Ruby DSL behavior
310
+ condition = wrap_condition_in_all(condition) if simple_trait_reference?(condition)
311
+ else
312
+ # Multiple conditions: combine with cascade_and
313
+ condition = Kumi::Syntax::CallExpression.new(:cascade_and, conditions, loc: on_token.location)
314
+ end
288
315
 
289
316
  Kumi::Syntax::CaseExpression.new(condition, result, loc: on_token.location)
290
317
 
@@ -570,6 +597,7 @@ module Kumi
570
597
  condition.is_a?(Kumi::Syntax::DeclarationReference)
571
598
  end
572
599
 
600
+
573
601
  # Helper method to wrap condition in cascade_and function call
574
602
  def wrap_condition_in_all(condition)
575
603
  Kumi::Syntax::CallExpression.new(:cascade_and, [condition], loc: condition.loc)
@@ -26,7 +26,7 @@ module Kumi
26
26
  when nil then break
27
27
  when "\n" then handle_newline
28
28
  when '#' then consume_comment
29
- when '"' then consume_string
29
+ when '"', "'" then consume_string
30
30
  when /\d/ then consume_number
31
31
  when '-'
32
32
  if peek_char && peek_char.match?(/\d/)
@@ -95,10 +95,11 @@ module Kumi
95
95
 
96
96
  def consume_string
97
97
  start_column = @column
98
+ quote_char = current_char # Remember which quote type we're using
98
99
  advance # skip opening quote
99
100
 
100
101
  string_content = ''
101
- while current_char && current_char != '"'
102
+ while current_char && current_char != quote_char
102
103
  if current_char == '\\'
103
104
  advance
104
105
  # Handle escape sequences
@@ -108,6 +109,7 @@ module Kumi
108
109
  when 'r' then string_content += "\r"
109
110
  when '\\' then string_content += '\\'
110
111
  when '"' then string_content += '"'
112
+ when "'" then string_content += "'"
111
113
  else
112
114
  string_content += current_char if current_char
113
115
  end
@@ -117,7 +119,7 @@ module Kumi
117
119
  advance
118
120
  end
119
121
 
120
- raise_tokenizer_error('Unterminated string literal') if current_char != '"'
122
+ raise_tokenizer_error('Unterminated string literal') if current_char != quote_char
121
123
 
122
124
  advance # skip closing quote
123
125
 
@@ -32,6 +32,7 @@ module Kumi
32
32
  BOOLEAN_TYPE = :boolean_type # boolean
33
33
  ANY_TYPE = :any_type # any
34
34
  ARRAY_TYPE = :array_type # array
35
+ ELEMENT_TYPE = :element_type # element
35
36
 
36
37
  # Function keywords
37
38
  FN = :fn
@@ -149,6 +150,11 @@ module Kumi
149
150
  starts_declaration: true,
150
151
  type_name: :hash
151
152
  },
153
+ element_type: {
154
+ category: :type_keyword,
155
+ starts_declaration: true,
156
+ type_name: :element
157
+ },
152
158
 
153
159
  # Function keyword
154
160
  fn: {
@@ -385,7 +391,8 @@ module Kumi
385
391
  'boolean' => :boolean_type,
386
392
  'any' => :any_type,
387
393
  'array' => :array_type,
388
- 'hash' => :hash_type
394
+ 'hash' => :hash_type,
395
+ 'element' => :element_type
389
396
  }.freeze
390
397
 
391
398
  # Opener to closer mappings for error recovery
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Kumi
4
4
  module Parser
5
- VERSION = '0.0.11'
5
+ VERSION = '0.0.13'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kumi-parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kumi Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-08-21 00:00:00.000000000 Z
11
+ date: 2025-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: kumi