symath 0.1.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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +8 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +616 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/lib/symath/definition/abs.rb +48 -0
  13. data/lib/symath/definition/arccos.rb +25 -0
  14. data/lib/symath/definition/arccot.rb +23 -0
  15. data/lib/symath/definition/arccsc.rb +24 -0
  16. data/lib/symath/definition/arcsec.rb +24 -0
  17. data/lib/symath/definition/arcsin.rb +25 -0
  18. data/lib/symath/definition/arctan.rb +23 -0
  19. data/lib/symath/definition/bounds.rb +39 -0
  20. data/lib/symath/definition/codiff.rb +31 -0
  21. data/lib/symath/definition/constant.rb +111 -0
  22. data/lib/symath/definition/cos.rb +17 -0
  23. data/lib/symath/definition/cot.rb +17 -0
  24. data/lib/symath/definition/csc.rb +17 -0
  25. data/lib/symath/definition/curl.rb +27 -0
  26. data/lib/symath/definition/d.rb +62 -0
  27. data/lib/symath/definition/div.rb +27 -0
  28. data/lib/symath/definition/exp.rb +112 -0
  29. data/lib/symath/definition/fact.rb +55 -0
  30. data/lib/symath/definition/flat.rb +31 -0
  31. data/lib/symath/definition/function.rb +197 -0
  32. data/lib/symath/definition/grad.rb +23 -0
  33. data/lib/symath/definition/hodge.rb +23 -0
  34. data/lib/symath/definition/int.rb +75 -0
  35. data/lib/symath/definition/laplacian.rb +23 -0
  36. data/lib/symath/definition/lmd.rb +97 -0
  37. data/lib/symath/definition/ln.rb +45 -0
  38. data/lib/symath/definition/number.rb +51 -0
  39. data/lib/symath/definition/operator.rb +228 -0
  40. data/lib/symath/definition/sec.rb +17 -0
  41. data/lib/symath/definition/sharp.rb +31 -0
  42. data/lib/symath/definition/sin.rb +17 -0
  43. data/lib/symath/definition/sqrt.rb +62 -0
  44. data/lib/symath/definition/tan.rb +17 -0
  45. data/lib/symath/definition/trig.rb +95 -0
  46. data/lib/symath/definition/variable.rb +284 -0
  47. data/lib/symath/definition/xd.rb +28 -0
  48. data/lib/symath/definition.rb +205 -0
  49. data/lib/symath/equation.rb +67 -0
  50. data/lib/symath/fraction.rb +177 -0
  51. data/lib/symath/matrix.rb +252 -0
  52. data/lib/symath/minus.rb +125 -0
  53. data/lib/symath/operation/differential.rb +167 -0
  54. data/lib/symath/operation/distributivelaw.rb +367 -0
  55. data/lib/symath/operation/exterior.rb +64 -0
  56. data/lib/symath/operation/integration.rb +329 -0
  57. data/lib/symath/operation/match.rb +166 -0
  58. data/lib/symath/operation/normalization.rb +458 -0
  59. data/lib/symath/operation.rb +36 -0
  60. data/lib/symath/operator.rb +163 -0
  61. data/lib/symath/parser.rb +473 -0
  62. data/lib/symath/parser.y +129 -0
  63. data/lib/symath/poly/dup.rb +835 -0
  64. data/lib/symath/poly/galois.rb +621 -0
  65. data/lib/symath/poly.rb +142 -0
  66. data/lib/symath/power.rb +224 -0
  67. data/lib/symath/product.rb +183 -0
  68. data/lib/symath/sum.rb +174 -0
  69. data/lib/symath/type.rb +282 -0
  70. data/lib/symath/value.rb +372 -0
  71. data/lib/symath/version.rb +3 -0
  72. data/lib/symath/wedge.rb +48 -0
  73. data/lib/symath.rb +157 -0
  74. data/symath.gemspec +39 -0
  75. metadata +160 -0
@@ -0,0 +1,473 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.5.0
4
+ # from Racc grammar file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+
9
+ require 'symath'
10
+
11
+ module SyMath
12
+ class Parser < Racc::Parser
13
+
14
+ module_eval(<<'...end parser.y/module_eval...', 'parser.y', 47)
15
+ attr_reader :exp
16
+
17
+ def function(name, subnodes)
18
+ args = subnodes
19
+
20
+ if name.is_a?(String)
21
+ # SyMathntactic sugar for 'flat' function
22
+ name = 'flat' if name.eql?('b')
23
+
24
+ if name.include? "'"
25
+ raise ParseError, "\nparse error on function name '#{name}'"
26
+ end
27
+
28
+ if name == 'lmd'
29
+ return SyMath::Definition::Lmd.new(*args)
30
+ end
31
+ end
32
+
33
+ return SyMath::Operator.create(name, args.map { |a| a.nil? ? a : a })
34
+ end
35
+
36
+ # Create a variable or constant
37
+ def named_node(name)
38
+ if name.length >= 2 and name.match(/^d/)
39
+ return name.to_sym.to_m('dform')
40
+ end
41
+
42
+ if name.match(/\'$/)
43
+ name = name[0..-2]
44
+ return name.to_sym.to_m('vector')
45
+ end
46
+
47
+ return name.to_sym.to_m
48
+ end
49
+
50
+ def parse(str)
51
+ @q = []
52
+
53
+ cmd = [
54
+ 'eval',
55
+ 'normalize',
56
+ 'expand',
57
+ 'factorize',
58
+ 'factorize_simple',
59
+ 'combine_fractions',
60
+ ]
61
+
62
+ until str.empty?
63
+ case str
64
+ when /\A\s+/
65
+ # whitespace, do nothing
66
+ when *cmd
67
+ # command
68
+ @q.push [:CMD, $&]
69
+ when /\A[A-Za-z_]+[A-Za-z_0-9]*\'?/
70
+ # name (char + (char|num))
71
+ @q.push [:NAME, $&]
72
+ when /\A\d+/
73
+ # number (digits)
74
+ @q.push [:NUMBER, $&]
75
+ when /\A\*\*/
76
+ # two character operators
77
+ s = $&
78
+ @q.push [s, s]
79
+ when /\A.|\n/o
80
+ # other signs
81
+ s = $&
82
+ @q.push [s, s]
83
+ end
84
+ str = $'
85
+ end
86
+ @q.push [false, '$end']
87
+ exp = do_parse
88
+ return if exp.nil?
89
+
90
+ return exp
91
+ end
92
+
93
+ def next_token()
94
+ @q.shift
95
+ end
96
+ ...end parser.y/module_eval...
97
+ ##### State transition tables begin ###
98
+
99
+ racc_action_table = [
100
+ 18, 15, 16, 17, 13, 14, 12, 11, 19, 5,
101
+ 45, 28, 29, 3, 4, 42, 46, 7, 8, 9,
102
+ 10, 5, 48, 37, 18, 3, 4, 18, 46, 7,
103
+ 8, 9, 10, 5, 23, 18, 24, 3, 4, 44,
104
+ nil, 7, 8, 9, 10, 5, nil, nil, nil, 3,
105
+ 4, nil, nil, 7, 8, 9, 10, 5, nil, nil,
106
+ nil, 3, 4, nil, nil, 7, 8, 9, 10, 5,
107
+ nil, nil, nil, 3, 4, nil, nil, 7, 8, 9,
108
+ 10, 5, nil, nil, nil, 3, 4, nil, nil, 7,
109
+ 8, 9, 10, 5, nil, nil, nil, 3, 4, nil,
110
+ nil, 7, 8, 9, 10, 5, nil, nil, nil, 3,
111
+ 4, nil, nil, 7, 8, 9, 10, 5, nil, nil,
112
+ nil, 3, 4, nil, nil, 7, 8, 9, 10, 5,
113
+ nil, nil, nil, 3, 4, nil, nil, 7, 8, 9,
114
+ 10, 5, nil, nil, nil, 3, 4, nil, nil, 7,
115
+ 8, 9, 10, 18, 15, 16, 17, 13, 14, 12,
116
+ nil, 19, 5, nil, 38, nil, 3, 4, nil, nil,
117
+ 7, 8, 9, 10, 5, nil, nil, nil, 3, 4,
118
+ nil, nil, 7, 8, 9, 10, 5, nil, nil, nil,
119
+ 3, 4, nil, nil, 7, 8, 9, 10, 18, 15,
120
+ 16, 17, 13, 14, 12, nil, 19, 5, nil, 47,
121
+ nil, 3, 4, nil, nil, 7, 8, 9, 10, 18,
122
+ 15, 16, 17, 13, 14, 12, nil, 19, 18, 15,
123
+ 16, 17, 13, 14, 12, nil, 19, 18, 15, 16,
124
+ 17, 13, 14, 12, 25, 19, nil, 7, 8, 9,
125
+ 10, 18, 15, 16, 17, 13, 14, 18, 15, 16,
126
+ 17, 13, 14, 18, 15, 16, 17, 18, 15, 16,
127
+ 17 ]
128
+
129
+ racc_action_check = [
130
+ 27, 27, 27, 27, 27, 27, 27, 1, 27, 0,
131
+ 40, 10, 11, 0, 0, 27, 40, 0, 0, 0,
132
+ 0, 3, 43, 19, 33, 3, 3, 34, 43, 3,
133
+ 3, 3, 3, 4, 7, 35, 7, 4, 4, 38,
134
+ nil, 4, 4, 4, 4, 5, nil, nil, nil, 5,
135
+ 5, nil, nil, 5, 5, 5, 5, 9, nil, nil,
136
+ nil, 9, 9, nil, nil, 9, 9, 9, 9, 12,
137
+ nil, nil, nil, 12, 12, nil, nil, 12, 12, 12,
138
+ 12, 13, nil, nil, nil, 13, 13, nil, nil, 13,
139
+ 13, 13, 13, 14, nil, nil, nil, 14, 14, nil,
140
+ nil, 14, 14, 14, 14, 15, nil, nil, nil, 15,
141
+ 15, nil, nil, 15, 15, 15, 15, 16, nil, nil,
142
+ nil, 16, 16, nil, nil, 16, 16, 16, 16, 17,
143
+ nil, nil, nil, 17, 17, nil, nil, 17, 17, 17,
144
+ 17, 18, nil, nil, nil, 18, 18, nil, nil, 18,
145
+ 18, 18, 18, 21, 21, 21, 21, 21, 21, 21,
146
+ nil, 21, 23, nil, 21, nil, 23, 23, nil, nil,
147
+ 23, 23, 23, 23, 25, nil, nil, nil, 25, 25,
148
+ nil, nil, 25, 25, 25, 25, 37, nil, nil, nil,
149
+ 37, 37, nil, nil, 37, 37, 37, 37, 41, 41,
150
+ 41, 41, 41, 41, 41, nil, 41, 46, nil, 41,
151
+ nil, 46, 46, nil, nil, 46, 46, 46, 46, 2,
152
+ 2, 2, 2, 2, 2, 2, nil, 2, 39, 39,
153
+ 39, 39, 39, 39, 39, nil, 39, 49, 49, 49,
154
+ 49, 49, 49, 49, 8, 49, nil, 8, 8, 8,
155
+ 8, 20, 20, 20, 20, 20, 20, 30, 30, 30,
156
+ 30, 30, 30, 31, 31, 31, 31, 32, 32, 32,
157
+ 32 ]
158
+
159
+ racc_action_pointer = [
160
+ 1, 7, 216, 13, 25, 37, nil, 21, 231, 49,
161
+ -4, 12, 61, 73, 85, 97, 109, 121, 133, 10,
162
+ 248, 150, nil, 154, nil, 166, nil, -3, nil, nil,
163
+ 254, 260, 264, 21, 24, 32, nil, 178, 24, 225,
164
+ -4, 195, nil, 8, nil, nil, 199, nil, nil, 234 ]
165
+
166
+ racc_action_default = [
167
+ -2, -26, -1, -26, -26, -26, -15, -22, -26, -26,
168
+ -20, -26, -26, -26, -26, -26, -26, -26, -26, -26,
169
+ -3, -26, -13, -26, -23, -26, -18, -26, -21, 50,
170
+ -4, -5, -6, -7, -8, -9, -10, -26, -12, -25,
171
+ -26, -26, -19, -26, -11, -16, -26, -17, -14, -24 ]
172
+
173
+ racc_goto_table = [
174
+ 2, 1, 26, 20, 21, 22, 40, nil, nil, 27,
175
+ nil, nil, 30, 31, 32, 33, 34, 35, 36, nil,
176
+ 43, nil, nil, nil, nil, 41, nil, nil, nil, nil,
177
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
178
+ nil, nil, nil, nil, nil, nil, 49 ]
179
+
180
+ racc_goto_check = [
181
+ 2, 1, 4, 2, 2, 2, 3, nil, nil, 2,
182
+ nil, nil, 2, 2, 2, 2, 2, 2, 2, nil,
183
+ 3, nil, nil, nil, nil, 2, nil, nil, nil, nil,
184
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
185
+ nil, nil, nil, nil, nil, nil, 2 ]
186
+
187
+ racc_goto_pointer = [
188
+ nil, 1, 0, -17, -6 ]
189
+
190
+ racc_goto_default = [
191
+ nil, nil, 39, nil, 6 ]
192
+
193
+ racc_reduce_table = [
194
+ 0, 0, :racc_error,
195
+ 1, 22, :_reduce_none,
196
+ 0, 22, :_reduce_2,
197
+ 2, 23, :_reduce_3,
198
+ 3, 23, :_reduce_4,
199
+ 3, 23, :_reduce_5,
200
+ 3, 23, :_reduce_6,
201
+ 3, 23, :_reduce_7,
202
+ 3, 23, :_reduce_8,
203
+ 3, 23, :_reduce_9,
204
+ 3, 23, :_reduce_10,
205
+ 4, 23, :_reduce_11,
206
+ 3, 23, :_reduce_12,
207
+ 2, 23, :_reduce_13,
208
+ 5, 23, :_reduce_14,
209
+ 1, 23, :_reduce_none,
210
+ 4, 25, :_reduce_16,
211
+ 4, 25, :_reduce_17,
212
+ 2, 25, :_reduce_18,
213
+ 3, 25, :_reduce_19,
214
+ 1, 25, :_reduce_20,
215
+ 2, 25, :_reduce_21,
216
+ 1, 25, :_reduce_22,
217
+ 2, 25, :_reduce_23,
218
+ 3, 24, :_reduce_24,
219
+ 1, 24, :_reduce_25 ]
220
+
221
+ racc_reduce_n = 26
222
+
223
+ racc_shift_n = 50
224
+
225
+ racc_token_table = {
226
+ false => 0,
227
+ :error => 1,
228
+ :UMINUS => 2,
229
+ "**" => 3,
230
+ "*" => 4,
231
+ "/" => 5,
232
+ "^" => 6,
233
+ "+" => 7,
234
+ "-" => 8,
235
+ "=" => 9,
236
+ :unassoc => 10,
237
+ "." => 11,
238
+ :CMD => 12,
239
+ "(" => 13,
240
+ ")" => 14,
241
+ "!" => 15,
242
+ :NAME => 16,
243
+ "#" => 17,
244
+ "|" => 18,
245
+ :NUMBER => 19,
246
+ "," => 20 }
247
+
248
+ racc_nt_base = 21
249
+
250
+ racc_use_result_var = true
251
+
252
+ Racc_arg = [
253
+ racc_action_table,
254
+ racc_action_check,
255
+ racc_action_default,
256
+ racc_action_pointer,
257
+ racc_goto_table,
258
+ racc_goto_check,
259
+ racc_goto_default,
260
+ racc_goto_pointer,
261
+ racc_nt_base,
262
+ racc_reduce_table,
263
+ racc_token_table,
264
+ racc_shift_n,
265
+ racc_reduce_n,
266
+ racc_use_result_var ]
267
+
268
+ Racc_token_to_s_table = [
269
+ "$end",
270
+ "error",
271
+ "UMINUS",
272
+ "\"**\"",
273
+ "\"*\"",
274
+ "\"/\"",
275
+ "\"^\"",
276
+ "\"+\"",
277
+ "\"-\"",
278
+ "\"=\"",
279
+ "unassoc",
280
+ "\".\"",
281
+ "CMD",
282
+ "\"(\"",
283
+ "\")\"",
284
+ "\"!\"",
285
+ "NAME",
286
+ "\"#\"",
287
+ "\"|\"",
288
+ "NUMBER",
289
+ "\",\"",
290
+ "$start",
291
+ "target",
292
+ "exp",
293
+ "args",
294
+ "func" ]
295
+
296
+ Racc_debug_parser = false
297
+
298
+ ##### State transition tables end #####
299
+
300
+ # reduce 0 omitted
301
+
302
+ # reduce 1 omitted
303
+
304
+ module_eval(<<'.,.,', 'parser.y', 14)
305
+ def _reduce_2(val, _values, result)
306
+ result = nil
307
+ result
308
+ end
309
+ .,.,
310
+
311
+ module_eval(<<'.,.,', 'parser.y', 15)
312
+ def _reduce_3(val, _values, result)
313
+ result = val[1].send(val[0])
314
+ result
315
+ end
316
+ .,.,
317
+
318
+ module_eval(<<'.,.,', 'parser.y', 16)
319
+ def _reduce_4(val, _values, result)
320
+ result = eq(val[0], val[2])
321
+ result
322
+ end
323
+ .,.,
324
+
325
+ module_eval(<<'.,.,', 'parser.y', 17)
326
+ def _reduce_5(val, _values, result)
327
+ result = val[0].add(val[2])
328
+ result
329
+ end
330
+ .,.,
331
+
332
+ module_eval(<<'.,.,', 'parser.y', 18)
333
+ def _reduce_6(val, _values, result)
334
+ result = val[0].sub(val[2])
335
+ result
336
+ end
337
+ .,.,
338
+
339
+ module_eval(<<'.,.,', 'parser.y', 19)
340
+ def _reduce_7(val, _values, result)
341
+ result = val[0].mul(val[2])
342
+ result
343
+ end
344
+ .,.,
345
+
346
+ module_eval(<<'.,.,', 'parser.y', 20)
347
+ def _reduce_8(val, _values, result)
348
+ result = val[0].div(val[2])
349
+ result
350
+ end
351
+ .,.,
352
+
353
+ module_eval(<<'.,.,', 'parser.y', 21)
354
+ def _reduce_9(val, _values, result)
355
+ result = val[0].wedge(val[2])
356
+ result
357
+ end
358
+ .,.,
359
+
360
+ module_eval(<<'.,.,', 'parser.y', 22)
361
+ def _reduce_10(val, _values, result)
362
+ result = val[0].power(val[2])
363
+ result
364
+ end
365
+ .,.,
366
+
367
+ module_eval(<<'.,.,', 'parser.y', 23)
368
+ def _reduce_11(val, _values, result)
369
+ result = function('fact', [val[1]])
370
+ result
371
+ end
372
+ .,.,
373
+
374
+ module_eval(<<'.,.,', 'parser.y', 24)
375
+ def _reduce_12(val, _values, result)
376
+ result = val[1]
377
+ result
378
+ end
379
+ .,.,
380
+
381
+ module_eval(<<'.,.,', 'parser.y', 25)
382
+ def _reduce_13(val, _values, result)
383
+ result = val[1].neg
384
+ result
385
+ end
386
+ .,.,
387
+
388
+ module_eval(<<'.,.,', 'parser.y', 26)
389
+ def _reduce_14(val, _values, result)
390
+ result = function(val[0], val[3])
391
+ result
392
+ end
393
+ .,.,
394
+
395
+ # reduce 15 omitted
396
+
397
+ module_eval(<<'.,.,', 'parser.y', 29)
398
+ def _reduce_16(val, _values, result)
399
+ result = function(val[0], val[2])
400
+ result
401
+ end
402
+ .,.,
403
+
404
+ module_eval(<<'.,.,', 'parser.y', 30)
405
+ def _reduce_17(val, _values, result)
406
+ result = function('sharp', [val[2]])
407
+ result
408
+ end
409
+ .,.,
410
+
411
+ module_eval(<<'.,.,', 'parser.y', 31)
412
+ def _reduce_18(val, _values, result)
413
+ result = function('sharp', [val[1]])
414
+ result
415
+ end
416
+ .,.,
417
+
418
+ module_eval(<<'.,.,', 'parser.y', 32)
419
+ def _reduce_19(val, _values, result)
420
+ result = function('abs', [val[1]])
421
+ result
422
+ end
423
+ .,.,
424
+
425
+ module_eval(<<'.,.,', 'parser.y', 33)
426
+ def _reduce_20(val, _values, result)
427
+ result = val[0].to_i.to_m
428
+ result
429
+ end
430
+ .,.,
431
+
432
+ module_eval(<<'.,.,', 'parser.y', 34)
433
+ def _reduce_21(val, _values, result)
434
+ result = function('fact', [val[0].to_i.to_m])
435
+ result
436
+ end
437
+ .,.,
438
+
439
+ module_eval(<<'.,.,', 'parser.y', 35)
440
+ def _reduce_22(val, _values, result)
441
+ result = named_node(val[0])
442
+ result
443
+ end
444
+ .,.,
445
+
446
+ module_eval(<<'.,.,', 'parser.y', 36)
447
+ def _reduce_23(val, _values, result)
448
+ result = function('fact', [named_node(val[0])])
449
+ result
450
+ end
451
+ .,.,
452
+
453
+ module_eval(<<'.,.,', 'parser.y', 38)
454
+ def _reduce_24(val, _values, result)
455
+ result = val[0].push(val[2])
456
+ result
457
+ end
458
+ .,.,
459
+
460
+ module_eval(<<'.,.,', 'parser.y', 39)
461
+ def _reduce_25(val, _values, result)
462
+ result = [val[0]]
463
+ result
464
+ end
465
+ .,.,
466
+
467
+ def _reduce_none(val, _values, result)
468
+ val[0]
469
+ end
470
+
471
+ end # class Parser
472
+
473
+ end
@@ -0,0 +1,129 @@
1
+ # Sy expression parser
2
+
3
+ class Parser
4
+ prechigh
5
+ nonassoc UMINUS
6
+ left '**'
7
+ left '*' '/' '^'
8
+ left '+' '-'
9
+ left '='
10
+ unassoc '.'
11
+ CMD
12
+ preclow
13
+ rule
14
+ target: exp
15
+ | /* none */ { result = nil }
16
+ exp: CMD exp { result = val[1].send(val[0]) }
17
+ | exp '=' exp { result = eq(val[0], val[2]) }
18
+ | exp '+' exp { result = val[0].add(val[2]) }
19
+ | exp '-' exp { result = val[0].sub(val[2]) }
20
+ | exp '*' exp { result = val[0].mul(val[2]) }
21
+ | exp '/' exp { result = val[0].div(val[2]) }
22
+ | exp '^' exp { result = val[0].wedge(val[2]) }
23
+ | exp '**' exp { result = val[0].power(val[2]) }
24
+ | '(' exp ')' '!' { result = function('fact', [val[1]]) }
25
+ | '(' exp ')' { result = val[1] }
26
+ | '-' exp =UMINUS { result = val[1].neg }
27
+ | exp '.' '(' args ')' { result = function(val[0], val[3]) }
28
+ | func
29
+
30
+ func: NAME '(' args ')' { result = function(val[0], val[2]) }
31
+ | '#' '(' exp ')' { result = function('sharp', [val[2]]) }
32
+ | '#' func { result = function('sharp', [val[1]]) }
33
+ | '|' exp '|' { result = function('abs', [val[1]]) }
34
+ | NUMBER { result = val[0].to_i.to_m }
35
+ | NUMBER '!' { result = function('fact', [val[0].to_i.to_m]) }
36
+ | NAME { result = named_node(val[0]) }
37
+ | NAME '!' { result = function('fact', [named_node(val[0])]) }
38
+
39
+ args: args ',' exp { result = val[0].push(val[2]) }
40
+ | exp { result = [val[0]] }
41
+ end
42
+ ---- header
43
+ require 'sy'
44
+
45
+ module Sy
46
+ ---- inner
47
+ attr_reader :exp
48
+
49
+ def function(name, subnodes)
50
+ args = subnodes
51
+
52
+ if name.is_a?(String)
53
+ # Syntactic sugar for 'flat' function
54
+ name = 'flat' if name.eql?('b')
55
+
56
+ if name.include? "'"
57
+ raise ParseError, "\nparse error on function name '#{name}'"
58
+ end
59
+
60
+ if name == 'lmd'
61
+ return Sy::Definition::Lmd.new(*args)
62
+ end
63
+ end
64
+
65
+ return Sy::Operator.create(name, args.map { |a| a.nil? ? a : a })
66
+ end
67
+
68
+ # Create a variable or constant
69
+ def named_node(name)
70
+ if name.length >= 2 and name.match(/^d/)
71
+ return name.to_sym.to_m('dform')
72
+ end
73
+
74
+ if name.match(/\'$/)
75
+ name = name[0..-2]
76
+ return name.to_sym.to_m('vector')
77
+ end
78
+
79
+ return name.to_sym.to_m
80
+ end
81
+
82
+ def parse(str)
83
+ @q = []
84
+
85
+ cmd = [
86
+ 'eval',
87
+ 'normalize',
88
+ 'expand',
89
+ 'factorize',
90
+ 'factorize_simple',
91
+ 'combine_fractions',
92
+ ]
93
+
94
+ until str.empty?
95
+ case str
96
+ when /\A\s+/
97
+ # whitespace, do nothing
98
+ when *cmd
99
+ # command
100
+ @q.push [:CMD, $&]
101
+ when /\A[A-Za-z_]+[A-Za-z_0-9]*\'?/
102
+ # name (char + (char|num))
103
+ @q.push [:NAME, $&]
104
+ when /\A\d+/
105
+ # number (digits)
106
+ @q.push [:NUMBER, $&]
107
+ when /\A\*\*/
108
+ # two character operators
109
+ s = $&
110
+ @q.push [s, s]
111
+ when /\A.|\n/o
112
+ # other signs
113
+ s = $&
114
+ @q.push [s, s]
115
+ end
116
+ str = $'
117
+ end
118
+ @q.push [false, '$end']
119
+ exp = do_parse
120
+ return if exp.nil?
121
+
122
+ return exp
123
+ end
124
+
125
+ def next_token()
126
+ @q.shift
127
+ end
128
+ ---- footer
129
+ end