symath 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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