rubic 0.2.0 → 0.3.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.
@@ -21,7 +21,7 @@ rule
21
21
  []
22
22
  }
23
23
  | IDENT
24
- | NUMBER
24
+ | number
25
25
  | STRING
26
26
  | define
27
27
  | cond
@@ -29,6 +29,8 @@ rule
29
29
  | lambda
30
30
  | let
31
31
  | quote
32
+ | set
33
+ | begin
32
34
 
33
35
  seq : expr
34
36
  {
@@ -123,59 +125,147 @@ rule
123
125
  {
124
126
  [:quote, val[1]]
125
127
  }
128
+
129
+ /* set expression */
130
+ set : '(' KW_SET_BANG IDENT expr ')'
131
+ {
132
+ [:set!, val[2], val[3]]
133
+ }
134
+
135
+ /* begin expression */
136
+ begin : '(' KW_BEGIN seq ')'
137
+ {
138
+ [:begin, *val[2]]
139
+ }
140
+
141
+ number : binary NUM_END { val[0] }
142
+ | octal NUM_END { val[0] }
143
+ | decimal NUM_END { val[0] }
144
+ | hexadecimal NUM_END { val[0] }
145
+
146
+ binary : b_prefix b_complex
147
+ { val[0].nil? ? val[1] : (val[0] ? inexact_to_exact(val[1]) : exact_to_inexact(val[1])) }
148
+ b_complex : b_real
149
+ | b_real '@' b_real { normalize_number Complex.polar(val[0], val[2]) }
150
+ | b_real '+' b_ureal 'i' { normalize_number Complex(val[0], val[2]) }
151
+ | b_real '-' b_ureal 'i' { normalize_number Complex(val[0], -val[2]) }
152
+ | b_real '+' 'i' { Complex(val[0], 1) }
153
+ | b_real '-' 'i' { Complex(val[0], -1) }
154
+ | '+' b_ureal 'i' { normalize_number Complex(0, val[1]) }
155
+ | '-' b_ureal 'i' { normalize_number Complex(0, -val[1]) }
156
+ | '+' 'i' { Complex(0, 1) }
157
+ | '-' 'i' { Complex(0, -1) }
158
+ b_real : sign b_ureal { val[0] == '-' ? -val[1] : val[1] }
159
+ b_ureal : b_uint
160
+ | b_uint '/' b_uint { normalize_number Rational(val[0], val[2]) }
161
+ b_uint : b_chars { val[0].to_i(2) }
162
+ b_chars : b_char
163
+ | b_chars b_char { val[0] << val[1] }
164
+ b_char : '0' | '1'
165
+ b_prefix : NUM_PREFIX_B exactness { val[1] }
166
+ | exactness NUM_PREFIX_B { val[0] }
167
+
168
+ octal : o_prefix o_complex
169
+ { val[0].nil? ? val[1] : (val[0] ? inexact_to_exact(val[1]) : exact_to_inexact(val[1])) }
170
+ o_complex : o_real
171
+ | o_real '@' o_real { normalize_number Complex.polar(val[0], val[2]) }
172
+ | o_real '+' o_ureal 'i' { normalize_number Complex(val[0], val[2]) }
173
+ | o_real '-' o_ureal 'i' { normalize_number Complex(val[0], -val[2]) }
174
+ | o_real '+' 'i' { Complex(val[0], 1) }
175
+ | o_real '-' 'i' { Complex(val[0], -1) }
176
+ | '+' o_ureal 'i' { normalize_number Complex(0, val[1]) }
177
+ | '-' o_ureal 'i' { normalize_number Complex(0, -val[1]) }
178
+ | '+' 'i' { Complex(0, 1) }
179
+ | '-' 'i' { Complex(0, -1) }
180
+ o_real : sign o_ureal { val[0] == '-' ? -val[1] : val[1] }
181
+ o_ureal : o_uint
182
+ | o_uint '/' o_uint { normalize_number Rational(val[0], val[2]) }
183
+ o_uint : o_chars { val[0].to_i(8) }
184
+ o_chars : o_char
185
+ | o_chars o_char { val[0] << val[1] }
186
+ o_char : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'
187
+ o_prefix : NUM_PREFIX_O exactness { val[1] }
188
+ | exactness NUM_PREFIX_O { val[0] }
189
+
190
+ decimal : d_prefix d_complex
191
+ { val[0].nil? ? val[1] : (val[0] ? inexact_to_exact(val[1]) : exact_to_inexact(val[1])) }
192
+ d_complex : d_real
193
+ | d_real '@' d_real { normalize_number Complex.polar(val[0], val[2]) }
194
+ | d_real '+' d_ureal 'i' { normalize_number Complex(val[0], val[2]) }
195
+ | d_real '-' d_ureal 'i' { normalize_number Complex(val[0], -val[2]) }
196
+ | d_real '+' 'i' { Complex(val[0], 1) }
197
+ | d_real '-' 'i' { Complex(val[0], -1) }
198
+ | '+' d_ureal 'i' { normalize_number Complex(0, val[1]) }
199
+ | '-' d_ureal 'i' { normalize_number Complex(0, -val[1]) }
200
+ | '+' 'i' { Complex(0, 1) }
201
+ | '-' 'i' { Complex(0, -1) }
202
+ d_real : sign d_ureal { val[0] == '-' ? -val[1] : val[1] }
203
+ d_ureal : d_uint
204
+ | d_uint '/' d_uint { normalize_number Rational(val[0], val[2]) }
205
+ | d_decimal
206
+ d_decimal : d_uint suffix { val[0].to_f * (10 ** val[1]) }
207
+ | '.' d_chars suffix { "0.#{val[1]}".to_f * (10 ** val[2]) }
208
+ | d_chars '.' d_chars suffix
209
+ { "#{val[0]}.#{val[2]}".to_f * (10 ** val[3]) }
210
+ | d_chars '.' suffix { val[0].to_f * (10 ** val[2]) }
211
+ d_uint : d_chars { val[0].to_i(10) }
212
+ d_chars : d_char
213
+ | d_chars d_char { val[0] << val[1] }
214
+ d_char : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
215
+ d_prefix : NUM_PREFIX_D exactness { val[1] }
216
+ | exactness NUM_PREFIX_D { val[0] }
217
+ | exactness
218
+
219
+ hexadecimal : h_prefix h_complex
220
+ { val[0].nil? ? val[1] : (val[0] ? to_exact(val[1]) : exact_to_inexact(val[1])) }
221
+ h_complex : h_real
222
+ | h_real '@' h_real { normalize_number Complex.polar(val[0], val[2]) }
223
+ | h_real '+' h_ureal 'i' { normalize_number Complex(val[0], val[2]) }
224
+ | h_real '-' h_ureal 'i' { normalize_number Complex(val[0], -val[2]) }
225
+ | h_real '+' 'i' { Complex(val[0], 1) }
226
+ | h_real '-' 'i' { Complex(val[0], -1) }
227
+ | '+' h_ureal 'i' { normalize_number Complex(0, val[1]) }
228
+ | '-' h_ureal 'i' { normalize_number Complex(0, -val[1]) }
229
+ | '+' 'i' { Complex(0, 1) }
230
+ | '-' 'i' { Complex(0, -1) }
231
+ h_real : sign h_ureal { val[0] == '-' ? -val[1] : val[1] }
232
+ h_ureal : h_uint
233
+ | h_uint '/' h_uint { normalize_number Rational(val[0], val[2]) }
234
+ h_uint : h_chars { val[0].to_i(16) }
235
+ h_chars : h_char
236
+ | h_chars h_char { val[0] << val[1] }
237
+ h_char : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
238
+ | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
239
+ h_prefix : NUM_PREFIX_X exactness { val[1] }
240
+ | exactness NUM_PREFIX_X { val[0] }
241
+
242
+ suffix : /* empty */
243
+ { 0 }
244
+ | exponent_marker sign d_chars
245
+ { val[1] == '-' ? -val[2].to_i : val[2].to_i }
246
+ exponent_marker : 'e'
247
+ sign : /* empty */ | U_PLUS | U_MINUS
248
+ exactness : /* empty */ | NUM_PREFIX_E | NUM_PREFIX_I
126
249
  end
127
250
 
128
251
  ---- header
129
- require 'strscan'
252
+ require 'rubic/lexer'
253
+ require 'rubic/util'
130
254
 
131
255
  module Rubic
132
256
 
133
257
  ---- inner
134
- EOT = [false, nil] # end of token
135
- SYM_CHARS = Regexp.escape("+-*/<>=?")
258
+ include Rubic::Util
136
259
 
137
260
  def parse(str)
138
- @s = StringScanner.new(str)
261
+ @lexer = Rubic::Lexer.new(str)
139
262
  do_parse
140
263
  end
141
264
 
265
+ private
266
+
142
267
  def next_token
143
- @s.skip(/\s+/)
144
- return EOT if @s.eos?
145
-
146
- case
147
- when @s.scan(/[0-9]+(\.[0-9]+)?/)
148
- [:NUMBER, @s[0].include?('.') ? @s[0].to_f : @s[0].to_i]
149
- when @s.scan(/[()']/)
150
- [@s[0], nil]
151
- when @s.scan(/[A-Za-z_#{SYM_CHARS}][A-Za-z0-9_#{SYM_CHARS}]*/o)
152
- case @s[0] # keyword check
153
- when 'define'
154
- [:KW_DEFINE, nil]
155
- when 'cond'
156
- [:KW_COND, nil]
157
- when 'else'
158
- [:KW_ELSE, nil]
159
- when 'if'
160
- [:KW_IF, nil]
161
- when 'and'
162
- [:KW_AND, nil]
163
- when 'or'
164
- [:KW_OR, nil]
165
- when 'lambda'
166
- [:KW_LAMBDA, nil]
167
- when 'let'
168
- [:KW_LET, nil]
169
- when 'quote'
170
- [:KW_QUOTE, nil]
171
- else
172
- [:IDENT, @s[0].to_sym]
173
- end
174
- when @s.scan(/"([^"]*)"/)
175
- [:STRING, @s[1]]
176
- else
177
- raise Rubic::ParseError, "unknown character #{@s.getch}"
178
- end
268
+ @lexer.next_token
179
269
  end
180
270
 
181
271
  def on_error(t, val, vstack)
@@ -0,0 +1,42 @@
1
+ module Rubic
2
+ module Util
3
+ def inexact_to_exact(num)
4
+ case num
5
+ when Complex
6
+ r = inexact_to_exact(num.real)
7
+ i = inexact_to_exact(num.imag)
8
+ normalize_number Complex(r, i)
9
+ when Float
10
+ normalize_number num.rationalize
11
+ when Rational, Integer
12
+ num
13
+ else
14
+ raise TypeError, "unexpected type of number: #{num.class}"
15
+ end
16
+ end
17
+
18
+ def exact_to_inexact(num)
19
+ case num
20
+ when Complex
21
+ r = exact_to_inexact(num.real)
22
+ i = exact_to_inexact(num.imag)
23
+ normalize_number Complex(r, i)
24
+ when Float, Rational, Integer
25
+ num.to_f
26
+ else
27
+ raise TypeError, "unexpected type of number: #{num.class}"
28
+ end
29
+ end
30
+
31
+ def normalize_number(num)
32
+ case num
33
+ when Complex
34
+ num.imag.zero? ? num.real : num
35
+ when Rational
36
+ num.denominator == 1 ? num.numerator : num
37
+ else
38
+ num
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,3 +1,3 @@
1
1
  module Rubic
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - notozeki
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-20 00:00:00.000000000 Z
11
+ date: 2015-06-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -119,8 +119,10 @@ files:
119
119
  - lib/rubic/environment.rb
120
120
  - lib/rubic/inspector.rb
121
121
  - lib/rubic/interpreter.rb
122
+ - lib/rubic/lexer.rb
122
123
  - lib/rubic/parser.rb
123
124
  - lib/rubic/parser.y
125
+ - lib/rubic/util.rb
124
126
  - lib/rubic/version.rb
125
127
  - rubic.gemspec
126
128
  homepage: https://github.com/notozeki/rubic