miniruby 0.2.0 → 0.4.0

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: b4b95c75a52ab5a51fdb41c2721323256d4983ac109e223840c0527bdbca01d8
4
- data.tar.gz: 72f0db09bcd1228eaae0c530382c3746d00db27ef489b169032a5431d45f79cd
3
+ metadata.gz: a2511978dbe9723deb32aa63f4ba862348129c51746c349a6d4a98681dfa06d5
4
+ data.tar.gz: 68957f7813f0f83b84b034e14795c7fc29715e353df4e7f6c92709019c483f57
5
5
  SHA512:
6
- metadata.gz: be29ee866331b6e375f7950185c0d1b7d078019a87b07057298f9e600a2c909128285033921a1b70556f291cf6448beed3081e2906541a88fe449d53bb401c7e
7
- data.tar.gz: 07420f654d4cf62143bddd5bc2f3b2062ad43c367c52b596345e9ee579c93bd834310e1f80ada72c327ce766d44c7b65ee07861cdfedcb40cbafddf438115a9f
6
+ metadata.gz: e23490a704a5f4ba7454aeda4f3751253a759205dff92e5e0d05ca7183020125e84d383931d12adc6b3ed0edd4aa1d7c58c1697372a0a3ab017a0b3d779efe78
7
+ data.tar.gz: ab2786fe7c58889a396a4f33166144f335de115eff3fa7cd5dfa2907486db15aa7714f52645214e4cc3a0feca612ce18236db2cc9496655f4ac8f846c2dbe547
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.4.0] - 2026-04-16
4
+ - Add new parser capabilities:
5
+ - Add raw strings `'foo\nbar'`
6
+
7
+ ## [0.3.0] - 2026-04-15
8
+ - Add new parser capabilities:
9
+ - Add `&&`, `||`, `??`
10
+ - Set attributes
11
+
3
12
  ## [0.2.0] - 2026-04-15
4
13
  - Add new parser capabilities:
5
14
  - Add `break`, `next`, `unless`
@@ -190,6 +190,18 @@ module MiniRuby
190
190
  return token(Token::LESS_EQUAL) if match_char('=')
191
191
 
192
192
  return token(Token::LESS)
193
+ when '&'
194
+ return token(Token::AND_AND) if match_char('&')
195
+
196
+ return token(Token::AND)
197
+ when '|'
198
+ return token(Token::OR_OR) if match_char('|')
199
+
200
+ return token(Token::OR)
201
+ when '?'
202
+ return token(Token::QUESTION_QUESTION) if match_char('?')
203
+
204
+ return token(Token::ERROR)
193
205
  when '+'
194
206
  return token(Token::PLUS)
195
207
  when '-'
@@ -200,6 +212,8 @@ module MiniRuby
200
212
  return token(Token::SLASH)
201
213
  when '"'
202
214
  return scan_string
215
+ when "'"
216
+ return scan_raw_string
203
217
  when "\n"
204
218
  return token(Token::NEWLINE)
205
219
  when ' ', "\r", "\t"
@@ -379,5 +393,18 @@ module MiniRuby
379
393
  end
380
394
  end
381
395
  end
396
+
397
+ #: -> Token
398
+ def scan_raw_string
399
+ value_buffer = String.new
400
+ loop do
401
+ char, ok = advance_char
402
+ return token(Token::ERROR, 'unterminated string literal') unless ok
403
+ return token(Token::STRING, value_buffer) if char == "'"
404
+
405
+ value_buffer << char
406
+ end
407
+ end
408
+
382
409
  end
383
410
  end
@@ -113,13 +113,15 @@ module MiniRuby
113
113
  parse_assignment_expression
114
114
  end
115
115
 
116
- # assignment_expression = expression "=" assignment_expression | equality_expression
116
+ # assignment_expression = expression "=" assignment_expression | logical_or_expression
117
117
  #: -> AST::ExpressionNode
118
118
  def parse_assignment_expression
119
- target = parse_equality_expression
119
+ target = parse_logical_or_expression
120
120
  return target unless match(Token::EQUAL)
121
121
 
122
- unless target.is_a?(AST::IdentifierNode)
122
+ case target
123
+ when AST::IdentifierNode, AST::AttributeAccessExpressionNode
124
+ else
123
125
  add_error("unexpected `#{target.class}`, expected an identifier")
124
126
  end
125
127
  swallow_newlines
@@ -129,6 +131,50 @@ module MiniRuby
129
131
  AST::AssignmentExpressionNode.new(span:, target:, value:)
130
132
  end
131
133
 
134
+ # logical_or_expression = logical_and_expression | logical_or_expression ("||" | "??") logical_and_expression
135
+ #: -> AST::ExpressionNode
136
+ def parse_logical_or_expression
137
+ left = parse_logical_and_expression
138
+
139
+ while @lookahead.logical_orlike_operator?
140
+ operator = advance
141
+ swallow_newlines
142
+
143
+ right = parse_logical_and_expression
144
+ span = left.span.join(right.span)
145
+ left = AST::BinaryExpressionNode.new(
146
+ span:,
147
+ operator:,
148
+ left:,
149
+ right:,
150
+ )
151
+ end
152
+
153
+ left
154
+ end
155
+
156
+ # logical_and_expression = equality_expression | logical_and_expression "&&" equality_expression
157
+ #: -> AST::ExpressionNode
158
+ def parse_logical_and_expression
159
+ left = parse_equality_expression
160
+
161
+ while @lookahead.logical_and_operator?
162
+ operator = advance
163
+ swallow_newlines
164
+
165
+ right = parse_equality_expression
166
+ span = left.span.join(right.span)
167
+ left = AST::BinaryExpressionNode.new(
168
+ span:,
169
+ operator:,
170
+ left:,
171
+ right:,
172
+ )
173
+ end
174
+
175
+ left
176
+ end
177
+
132
178
  # equality_expression = equality_expression ("==" | "!=") comparison_expression | comparison_expression
133
179
  #: -> AST::ExpressionNode
134
180
  def parse_equality_expression
@@ -48,6 +48,16 @@ module MiniRuby
48
48
  '<'
49
49
  when LESS_EQUAL
50
50
  '<='
51
+ when AND_AND
52
+ '&&'
53
+ when AND
54
+ '&'
55
+ when OR_OR
56
+ '||'
57
+ when OR
58
+ '|'
59
+ when QUESTION_QUESTION
60
+ '??'
51
61
  when PLUS
52
62
  '+'
53
63
  when MINUS
@@ -143,6 +153,36 @@ module MiniRuby
143
153
  end
144
154
  end
145
155
 
156
+ #: -> bool
157
+ def logical_operator?
158
+ case @type
159
+ when OR_OR, AND_AND, QUESTION_QUESTION
160
+ true
161
+ else
162
+ false
163
+ end
164
+ end
165
+
166
+ #: -> bool
167
+ def logical_orlike_operator?
168
+ case @type
169
+ when OR_OR, QUESTION_QUESTION
170
+ true
171
+ else
172
+ false
173
+ end
174
+ end
175
+
176
+ #: -> bool
177
+ def logical_and_operator?
178
+ case @type
179
+ when AND_AND
180
+ true
181
+ else
182
+ false
183
+ end
184
+ end
185
+
146
186
  #: -> String
147
187
  def type_name
148
188
  self.class.type_to_string(@type)
@@ -186,6 +226,16 @@ module MiniRuby
186
226
  '<'
187
227
  when LESS_EQUAL
188
228
  '<='
229
+ when AND_AND
230
+ '&&'
231
+ when AND
232
+ '&'
233
+ when OR_OR
234
+ '||'
235
+ when OR
236
+ '|'
237
+ when QUESTION_QUESTION
238
+ '??'
189
239
  when PLUS
190
240
  '+'
191
241
  when MINUS
@@ -266,6 +316,16 @@ module MiniRuby
266
316
  LESS = :less
267
317
  # Less equal `<=`
268
318
  LESS_EQUAL = :less_equal
319
+ # Logical and `&&`
320
+ AND_AND = :and_and
321
+ # Bitwise and `&`
322
+ AND = :and
323
+ # Logical or `||`
324
+ OR_OR = :or_or
325
+ # Bitwise or `|`
326
+ OR = :or
327
+ # Nil coalescence `??`
328
+ QUESTION_QUESTION = :question_question
269
329
  # Plus `+`
270
330
  PLUS = :plus
271
331
  # Minus `-`
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniRuby
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miniruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Drewniak