hilbert 0.0.2700000

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 (74) hide show
  1. checksums.yaml +15 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +23 -0
  4. data/.rubocop.yml +25 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +9 -0
  7. data/Guardfile +33 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +159 -0
  10. data/Rakefile +20 -0
  11. data/bin/qlang +29 -0
  12. data/core/Q/Lexer.hs +9 -0
  13. data/core/Q/Parser.hs +9 -0
  14. data/core/Q.hs +19 -0
  15. data/ext/qlang/QMatrix/q_matrix.c +0 -0
  16. data/ext/qlang/extconf.rb +3 -0
  17. data/ext/qlang/qlang.c +65 -0
  18. data/ext/qlang/qlang.h +6 -0
  19. data/legacy_rspec/langs/Haskell/ex1_after.hs +74 -0
  20. data/legacy_rspec/langs/Haskell/ex1_before.hs +74 -0
  21. data/legacy_rspec/langs/Python/ex1_after.py +93 -0
  22. data/legacy_rspec/langs/Python/ex1_before.py +95 -0
  23. data/legacy_rspec/langs/R/ex1_after.R +89 -0
  24. data/legacy_rspec/langs/R/ex1_before.R +89 -0
  25. data/legacy_rspec/objects/list_spec.rb +31 -0
  26. data/legacy_rspec/objects/matrix_spec.rb +55 -0
  27. data/legacy_rspec/objects/vector_spec.rb +47 -0
  28. data/lib/qlang/api/func_api.rb +17 -0
  29. data/lib/qlang/api/integral_api.rb +16 -0
  30. data/lib/qlang/api/limit_api.rb +22 -0
  31. data/lib/qlang/api/list_api.rb +16 -0
  32. data/lib/qlang/api/matrix_api.rb +20 -0
  33. data/lib/qlang/api/sigma_api.rb +16 -0
  34. data/lib/qlang/api/vector_api.rb +19 -0
  35. data/lib/qlang/api.rb +23 -0
  36. data/lib/qlang/exec.rb +64 -0
  37. data/lib/qlang/iq.rb +45 -0
  38. data/lib/qlang/lexer/base.rb +107 -0
  39. data/lib/qlang/lexer/formula_lexer.rb +20 -0
  40. data/lib/qlang/lexer/main_lexer.rb +34 -0
  41. data/lib/qlang/lexer/tokens.rb +94 -0
  42. data/lib/qlang/lexer.rb +11 -0
  43. data/lib/qlang/meta_info.rb +27 -0
  44. data/lib/qlang/parser/base.rb +7 -0
  45. data/lib/qlang/parser/formula_parser.rb +36 -0
  46. data/lib/qlang/parser/func_parser.rb +15 -0
  47. data/lib/qlang/parser/integral_parser.rb +15 -0
  48. data/lib/qlang/parser/limit_parser.rb +16 -0
  49. data/lib/qlang/parser/list_parser.rb +12 -0
  50. data/lib/qlang/parser/matrix_parser.rb +17 -0
  51. data/lib/qlang/parser/sigma_parser.rb +17 -0
  52. data/lib/qlang/parser/vector_parser.rb +13 -0
  53. data/lib/qlang/parser.rb +101 -0
  54. data/lib/qlang/utils/langs.yml +7 -0
  55. data/lib/qlang/utils/ruby_ext.rb +54 -0
  56. data/lib/qlang/version.rb +3 -0
  57. data/lib/qlang.rb +37 -0
  58. data/qlang.gemspec +28 -0
  59. data/test/internal/test_tokens.rb +35 -0
  60. data/test/interpreter/base.rb +17 -0
  61. data/test/interpreter/test_differential.rb +43 -0
  62. data/test/interpreter/test_function.rb +44 -0
  63. data/test/interpreter/test_general.rb +12 -0
  64. data/test/interpreter/test_integral.rb +38 -0
  65. data/test/interpreter/test_limit.rb +37 -0
  66. data/test/interpreter/test_matrix.rb +70 -0
  67. data/test/interpreter/test_sigma.rb +25 -0
  68. data/test/interpreter/test_vector.rb +28 -0
  69. data/test/langs/test_r.rb +32 -0
  70. data/test/langs/test_ruby.rb +9 -0
  71. data/test/minitest_helper.rb +8 -0
  72. data/test/q_matrix/test_q_matrix.rb +13 -0
  73. data/test/test_qlang.rb +24 -0
  74. metadata +203 -0
data/lib/qlang/exec.rb ADDED
@@ -0,0 +1,64 @@
1
+ module Qlang
2
+ module Exec
3
+ class Compiler
4
+ def initialize(args)
5
+ @args = args
6
+ end
7
+
8
+ def output!
9
+ ch_compile_type(@args.first)
10
+ parse_string = parse(@args[1])
11
+ write!(@args[2], parse_string)
12
+
13
+ rescue Exception => e
14
+ raise e if @options[:trace] || e.is_a?(SystemExit)
15
+
16
+ print "#{e.class}: " unless e.class == RuntimeError
17
+ puts "#{e.message}"
18
+ puts ' Use --trace for backtrace.'
19
+ exit 1
20
+ ensure
21
+ exit 0
22
+ end
23
+
24
+ private
25
+
26
+ def ch_compile_type(lang)
27
+ case lang
28
+ when '-rb'
29
+ Qlang.to_ruby
30
+ when '-r'
31
+ Qlang.to_r
32
+ when '-py'
33
+ Qlang.to_python
34
+ else
35
+ print 'Q support only Ruby and R now.'
36
+ end
37
+ end
38
+
39
+ def parse(file_path)
40
+ file = open_file(file_path)
41
+ input_string = read_file(file)
42
+ file.close
43
+ input_string.gsub(/(.*)I love mathematics\.(.*)Q\.E\.D(.*)/m) {
44
+ "#{$1}#{Kconv.tosjis(Qlang.compile($2))}#{$3}"
45
+ }
46
+ end
47
+
48
+ def write!(output_path, string)
49
+ open(output_path, 'w') do |f|
50
+ f.puts string
51
+ end
52
+ end
53
+
54
+ def open_file(filename, flag = 'r')
55
+ return if filename.nil?
56
+ File.open(filename, flag)
57
+ end
58
+
59
+ def read_file(file)
60
+ file.read
61
+ end
62
+ end
63
+ end
64
+ end
data/lib/qlang/iq.rb ADDED
@@ -0,0 +1,45 @@
1
+ require 'dydx'
2
+ include Dydx
3
+
4
+ module Qlang
5
+ module Iq
6
+ class Dydx::Algebra::Formula
7
+ # FIX:
8
+ def to_q
9
+ str = to_s.gsub(/\*\*/, '^').rm(' * ')
10
+ str.equalize!
11
+ end
12
+ end
13
+
14
+ def self.execute(code)
15
+ ruby_code = Q.to_ruby.compile(code.encode('utf-8'))
16
+ ruby_obj = eval(ruby_code)
17
+
18
+ optimize_output(ruby_obj).encode('utf-8')
19
+ rescue SyntaxError
20
+ # TODO: emergency
21
+ case ruby_code
22
+ when /(\d)+(\w)/
23
+ execute("#{$1} * #{$2}")
24
+ end
25
+ end
26
+
27
+ def self.optimize_output(ruby_obj)
28
+
29
+ case ruby_obj
30
+ when Matrix, Vector, Dydx::Algebra::Formula
31
+ ruby_obj.to_q
32
+ when Numeric
33
+ # TODO: I know you wanna way..
34
+ if ruby_obj > 10000.0 then 'oo'
35
+ elsif ruby_obj < -10000.0 then '-oo'
36
+ elsif ruby_obj.abs < Float::EPSILON then '0.0'
37
+ else ruby_obj.to_s.equalize!
38
+ end
39
+ else
40
+ str = ruby_obj.to_s
41
+ str.equalize!
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,107 @@
1
+ require 'strscan'
2
+ require 'qlang/lexer/tokens'
3
+
4
+ module Qlang
5
+ module Lexer
6
+ class Base
7
+ attr_accessor :lexeds
8
+ include Tokens
9
+ class << self
10
+ attr_reader :token_rule_hash
11
+
12
+ def rule(pattern, &token)
13
+ token ||= proc { :NULL }
14
+ @token_rule_hash ||= {}
15
+ @token_rule_hash[pattern] = token.call
16
+ end
17
+ end
18
+
19
+ def initialize(str)
20
+ ss = StringScanner.new(str)
21
+ @lexeds = []
22
+ until ss.eos?
23
+ scan_rslt, ss = scan(ss)
24
+ if scan_rslt
25
+ @lexeds << scan_rslt unless scan_rslt[:token] == :NULL
26
+ else
27
+ fail "I'm so sorry, something wrong. Please feel free to report this."
28
+ end
29
+ end
30
+ end
31
+
32
+ def scan(ss)
33
+ scan_rslt = nil
34
+ token_rule_hash.each do |pattern, token|
35
+ if ss.scan(pattern)
36
+ scan_rslt = {
37
+ token: token,
38
+ value: ss[0],
39
+ els: 4.times.inject([]) { |s,i|s << ss[i+1] }.compact
40
+ }
41
+ break
42
+ end
43
+ end
44
+ [scan_rslt, ss]
45
+ end
46
+
47
+ # Accessor
48
+ ## GET(without side effect)
49
+ def get_value(num)
50
+ num = num.to_i
51
+ @lexeds[num][:value]
52
+ end
53
+
54
+ def get_els(num)
55
+ num = num.to_i
56
+ @lexeds[num][:els]
57
+ end
58
+
59
+ def token_str
60
+ @lexeds.map.with_index { |lexed, i| ":#{lexed[:token]}#{i}" }.join
61
+ end
62
+
63
+ def token_rule_hash
64
+ self.class.token_rule_hash
65
+ end
66
+
67
+ ## POST(with side effect, without idempotence.)
68
+ def parsed!(parsed, target)
69
+ case target
70
+ when Range
71
+ parsed_between!((target.first.to_i)..(target.last.to_i), parsed)
72
+ else
73
+ parsed_at!(target.to_i, parsed)
74
+ end
75
+ end
76
+
77
+ # squash!(range, token: :CONT)
78
+ def squash!(range, opts = { token: :CONT })
79
+ token = opts[:token]
80
+ range = (range.first.to_i)..(range.last.to_i)
81
+ value = values[range].join
82
+ range.count.times { @lexeds.delete_at(range.first) }
83
+ @lexeds.insert(range.first, { token: token, value: value })
84
+ end
85
+
86
+ # Legacy Accessor
87
+ def values
88
+ @lexeds.map { |lexed| lexed[:value] }
89
+ end
90
+
91
+ private
92
+
93
+ def parsed_at!(token_position, parsed)
94
+ @lexeds.delete_at(token_position)
95
+ @lexeds.insert(token_position, { token: :R, value: parsed })
96
+ end
97
+
98
+ def parsed_between!(token_range, parsed)
99
+ start_pos = token_range.first
100
+ token_range.count.times do
101
+ @lexeds.delete_at(start_pos)
102
+ end
103
+ @lexeds.insert(start_pos, { token: :R, value: parsed })
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,20 @@
1
+ module Qlang
2
+ module Lexer
3
+ class FormulaLexer < Base
4
+ rule(/\^/) { :EXP }
5
+ rule(/#{EMBEDDED_FUNC}/) { :BFUNC }
6
+ rule(/(pi|[1-9a-z]){2,}/) { :MUL }
7
+ rule(/(pi|[1-9a-z])/) { :SNGL }
8
+ rule(/([^\^1-9a-z]|^pi)+/) { :OTHER }
9
+
10
+ # rule(/#{OPE}/) { :OPE }
11
+ # rule(/#{FUNCV}/) { :FUNCV }
12
+ # rule(/#{VAR}/) { :VAR }
13
+ # rule(/#{NUM}/) { :NUM }
14
+ # rule(/#{LPRN}/) { :LPRN }
15
+ # rule(/#{RPRN}/) { :RPRN }
16
+
17
+ # rule(/#{ANYSP}/) { }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,34 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ module Qlang
5
+ module Lexer
6
+ class MainLexer < Base
7
+ rule(/(#{FUNCCV})#{ANYSP}#{EQL}#{ANYSP}(#{FORMULA})/) { :def_func }
8
+ rule(/#{ITGRLSYM}#{ANYSP}#{LPRN}(#{ANYSTR})#{RPRN}#{LBRCT}(#{ANYSTR})#{RBRCT}/) { :integral }
9
+ rule(/d\/d(#{VAR}) (#{FORMULA})/) { :differential }
10
+
11
+ rule(/lim#{LBRCT}(#{VAR})#{RSARW}(#{VARNUM})#{RBRCT} (#{FORMULA})/) { :limit }
12
+
13
+ rule(/#{LPRN}(#{NUMS_BY_SP})#{RPRN}/) { :vector }
14
+ rule(/#{LPRN}(#{NUMS_BY_SP_BY_SCLN_OR_NELN})#{RPRN}t/m) { :tmatrix }
15
+ rule(/#{LPRN}(#{NUMS_BY_SP_BY_SCLN_OR_NELN})#{RPRN}/m) { :matrix }
16
+
17
+ rule(/∑#{LBRCT}(#{VAR})=(#{INT}),#{ANYSP}(#{INT})#{RBRCT} (#{FORMULA})/) { :sigma }
18
+ rule(/sigma#{LBRCT}(#{VAR})=(#{INT}),#{ANYSP}(#{INT})#{RBRCT} (#{FORMULA})/) { :sigma }
19
+
20
+ rule(/#{FUNCCN}/) { :FUNCCN }
21
+
22
+ rule(/#{LPRN}/) { :LPRN }
23
+ rule(/#{RPRN}/) { :RPRN }
24
+ rule(/#{LBRCS}/) { :LBRCS }
25
+ rule(/#{RBRCS}/) { :RBRCS }
26
+
27
+ rule(/[ \t\f]/)
28
+
29
+ rule(/(\r|\n)+/) { :NULL }
30
+
31
+ rule(/[^\(\)\{\}(\n\n)]+/) { :CONT }
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,94 @@
1
+ module Qlang
2
+ module Lexer
3
+ module Tokens
4
+ # NUM
5
+ INT = /[0-9]+/
6
+ FLO = /[0-9]+\.[0-9]+/
7
+ E = /e/
8
+ PI = /pi/
9
+ INF = /oo/
10
+ NUM = /(?:#{FLO}|#{INT}|#{E}|#{PI}|#{INF})/
11
+
12
+ # FUNCTION
13
+ LPRN = /\(/
14
+ RPRN = /\)/
15
+ EMBEDDED_FUNC = /(?:sin|cos|tan|log)/
16
+ USER_FUNC = /[a-zA-Z]/
17
+ # h(x + y) != h * (x + y)
18
+ FUNCV = /(?:#{EMBEDDED_FUNC}|#{USER_FUNC})(?=#{LPRN})/
19
+
20
+ # VARIABLE
21
+ VAR = /(?:[a-d]|[f-z])/
22
+ # VAR_MUL2 = /(?!pi)#{VAR}{2}/
23
+ # #VAR_MUL3 = /(?!#{EMBEDDED_FUNC})#{VAR}{3}/
24
+ # # FIX:
25
+ # VAR_MUL = /(?!#{EMBEDDED_FUNC})#{VAR_MUL2}/
26
+
27
+ # # TERM
28
+ # TERM = /(#{NUM}|#{VAR_MUL}|#{VAR_MUL})/
29
+
30
+ # OPE
31
+ PLS = /\+/
32
+ SUB = /-/
33
+ MUL = /\*/
34
+ DIV = /\//
35
+ EXP = /(\*\*|\^)/
36
+ OPE = /(?:#{PLS}|#{SUB}|#{MUL}|#{DIV}|#{EXP})/
37
+
38
+ VARNUM = /(?:#{NUM}|#{VAR})/
39
+ ANYSP = ' *'
40
+ ANYSTR = /.+/
41
+ NONL = /[^\r\n]/
42
+
43
+ PRN = /(?:#{LPRN}|#{RPRN})/
44
+
45
+ LBRCS = /\{/
46
+ RBRCS = /\}/
47
+ BRCS = /(?:#{LBRCS}|#{RBRCS})/
48
+
49
+ LBRCT = /\[/
50
+ RBRCT = /\]/
51
+ BRCT = /(?:#{LBRCT}|#{RBRCT})/
52
+
53
+ CLN = /\:/
54
+ SCLN = /;/
55
+ CMA = /\,/
56
+ EQL = /\=/
57
+
58
+ RSARW = '->'
59
+ LSARW = '<-'
60
+ RDARW = '=>'
61
+ LDARW = '<='
62
+ SP = / /
63
+ NLIN = /(\r|\n)/
64
+
65
+ ITGRLSYM = 'S'
66
+ # FIXIT
67
+ SCLN_OR_NELN = /(?:#{SCLN}|#{NLIN})/
68
+
69
+ # TODO: what is better
70
+ class Util
71
+ def self.string_out(str, partition)
72
+ /#{ANYSP}#{str}(?:#{ANYSP}#{partition}#{ANYSP}#{str})*#{ANYSP}/
73
+ end
74
+
75
+ def self.func_call(args)
76
+ /#{FUNCV}#{LPRN}#{ANYSP}#{args}#{ANYSP}#{RPRN}/
77
+ end
78
+ end
79
+
80
+ NUMS_BY_CMA = Util.string_out(NUM, CMA)
81
+ VARS_BY_CMA = Util.string_out(VAR, CMA)
82
+ VARNUMS_BY_CMA = Util.string_out(VARNUM, CMA)
83
+ NUMS_BY_SP = Util.string_out(NUM, SP)
84
+
85
+ FUNCCN = Util.func_call(NUMS_BY_CMA)
86
+ FUNCCV = Util.func_call(VARS_BY_CMA)
87
+ FUNCCVN = Util.func_call(VARNUMS_BY_CMA)
88
+
89
+ NUMS_BY_SP_BY_SCLN_OR_NELN = Util.string_out(NUMS_BY_SP, SCLN_OR_NELN)
90
+
91
+ FORMULA = /(?:#{OPE}|#{FUNCV}|#{VAR}|#{NUM}|#{PRN}|#{ANYSP})+/
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,11 @@
1
+ require 'qlang/lexer/base'
2
+ require 'qlang/lexer/main_lexer'
3
+
4
+ module Qlang
5
+ module Lexer
6
+ def execute(str)
7
+ MainLexer.new(str)
8
+ end
9
+ module_function :execute
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # $meta_info indicate what and how to do.
2
+
3
+ class MetaInfo
4
+ include Singleton
5
+ attr_accessor :lang, :opts, :mode
6
+
7
+ def _load
8
+ # compiles into R as default.
9
+ lang = :r
10
+ end
11
+
12
+ # TODO: YAML.load_file("./lib/qlang/utils/langs.yml")['langs']
13
+ def langs_hash
14
+ {
15
+ r: 'R',
16
+ ruby: 'Ruby',
17
+ python: 'Pyhton',
18
+ haskell: 'Haskell',
19
+ scala: 'Scala',
20
+ js: 'Javascript'
21
+ }
22
+ end
23
+
24
+ def lang_str
25
+ LANGS_HASH[@lang.to_s]
26
+ end
27
+ end
@@ -0,0 +1,7 @@
1
+ module Qlang
2
+ module Parser
3
+ module Base
4
+ include ::Qlang::Api
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,36 @@
1
+ require 'qlang/lexer/formula_lexer'
2
+
3
+ module Qlang
4
+ module Parser
5
+ module FormulaParser
6
+ include Lexer::Tokens
7
+
8
+ def self.execute(str)
9
+ lexed = Lexer::FormulaLexer.new(str)
10
+ time = Time.now
11
+ loop do
12
+ fail "I'm so sorry, something wrong. Please feel free to report this." if Time.now > time + 10
13
+ case lexed.token_str
14
+ when /:EXP(\d+)/
15
+ new_ope = $meta_info.lang == :ruby ? '**' : '^'
16
+ lexed.parsed!(new_ope, $1)
17
+ when /:MUL(\d+)/
18
+ sss = StringScanner.new(lexed.get_value($1))
19
+ ary = []
20
+ until sss.eos?
21
+ [/pi/, /[1-9a-z]/].each do |rgx2|
22
+ ary << sss[0] if sss.scan(rgx2)
23
+ end
24
+ end
25
+ parsed = ary.join(' * ')
26
+
27
+ lexed.parsed!(parsed, $1)
28
+ else
29
+ break
30
+ end
31
+ end
32
+ lexed.values.join
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ require 'qlang/lexer/tokens'
2
+ module Qlang
3
+ module Parser
4
+ module FuncParser
5
+ include Base
6
+ include Lexer::Tokens
7
+ def execute(els)
8
+ def_func, formula = els[0], els[1]
9
+ def_func =~ /(#{USER_FUNC})#{LPRN}#{ANYSP}(#{VARS_BY_CMA})#{ANYSP}#{RPRN}/
10
+ FuncApi.execute($1, $2.split(' *,'), FormulaParser.execute(formula))
11
+ end
12
+ module_function :execute
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Qlang
2
+ module Parser
3
+ module IntegralParser
4
+ include Base
5
+ def execute(els)
6
+ integrated, range = els[0], els[1]
7
+
8
+ integrated.rm!(' ')
9
+
10
+ IntegralApi.execute(FormulaParser.execute(integrated[0..-3]), integrated[-2..-1], range)
11
+ end
12
+ module_function :execute
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module Qlang
2
+ module Parser
3
+ module LimitParser
4
+ include Base
5
+ def self.execute(els)
6
+ var, close_to, formula = els
7
+
8
+ LimitApi.execute(
9
+ FormulaParser.execute(formula),
10
+ var,
11
+ close_to
12
+ )
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Qlang
2
+ module Parser
3
+ module ListParser
4
+ include Base
5
+ def execute(lexed)
6
+ arys = lexed.split(/ *, */).map { |e| e.split(/ *: */).map { |e2| e2.delete(' ') } }
7
+ ListApi.execute(arys)
8
+ end
9
+ module_function :execute
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module Qlang
2
+ module Parser
3
+ module MatrixParser
4
+ include Base
5
+ def execute(els, opts = { trans: false })
6
+ trans = opts[:trans]
7
+ rows = els.first.split(/ *(?:;|\n) */).map(&:split_by_sp)
8
+ rows.all? { |row| row.count == rows.first.count }
9
+ if trans
10
+ rows = rows.transpose
11
+ end
12
+ MatrixApi.execute(rows)
13
+ end
14
+ module_function :execute
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Qlang
2
+ module Parser
3
+ module SigmaParser
4
+ include Base
5
+ def self.execute(els)
6
+ var, from, to, formula = els
7
+
8
+ SigmaApi.execute(
9
+ FormulaParser.execute(formula),
10
+ var,
11
+ from,
12
+ to
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ module Qlang
2
+ module Parser
3
+ module VectorParser
4
+ include Base
5
+ def execute(els)
6
+ VectorApi.execute(
7
+ els.first.rm(/\A +/).rm(/ +\z/).split_by_sp
8
+ )
9
+ end
10
+ module_function :execute
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,101 @@
1
+ require 'qlang/api'
2
+
3
+ require 'qlang/parser/base'
4
+ require 'qlang/parser/matrix_parser'
5
+ require 'qlang/parser/vector_parser'
6
+ require 'qlang/parser/list_parser'
7
+ require 'qlang/parser/func_parser'
8
+ require 'qlang/parser/integral_parser'
9
+ require 'qlang/parser/limit_parser'
10
+ require 'qlang/parser/sigma_parser'
11
+
12
+ require 'qlang/parser/formula_parser'
13
+
14
+ module Qlang
15
+ module Parser
16
+ include Lexer::Tokens
17
+ SYM = '\w+'
18
+ ONEHASH = "#{ANYSP}#{SYM}#{CLN}#{ANYSP}#{VARNUM}#{ANYSP}" # sdf: 234
19
+ def execute(lexed)
20
+ time = Time.now
21
+ until lexed.token_str =~ /\A:(NLIN|R)\d+\z/
22
+ fail "I'm so sorry, something wrong. Please feel free to report this." if Time.now > time + 10
23
+
24
+ case lexed.token_str
25
+ when /:(vector)(\d+)/, /:(matrix)(\d+)/, /:(tmatrix)(\d+)/, /:(integral)(\d+)/, /:(def_func)(\d+)/, /:(differential)(\d+)/, /:(limit)(\d+)/, /:(sigma)(\d+)/
26
+ token_els = lexed.get_els($2)
27
+
28
+ parsed =
29
+ case $1
30
+ when 'vector'
31
+ VectorParser.execute(token_els)
32
+ when 'matrix'
33
+ MatrixParser.execute(token_els)
34
+ when 'tmatrix'
35
+ MatrixParser.execute(token_els, trans: true)
36
+ when 'limit'
37
+ LimitParser.execute(token_els)
38
+ when 'integral'
39
+ IntegralParser.execute(token_els)
40
+ when 'def_func'
41
+ FuncParser.execute(token_els)
42
+ when 'sigma'
43
+ SigmaParser.execute(token_els)
44
+ when 'differential'
45
+ del_var, formula = token_els
46
+ "d/d#{del_var}(#{FormulaParser.execute(formula)})"
47
+ end
48
+ lexed.parsed!(parsed, $2)
49
+
50
+ when /:LPRN(\d+):CONT(\d+):RPRN(\d+)/
51
+ tokens_range = $1.to_i..$3.to_i
52
+ token_val =
53
+
54
+ lexed.parsed!(
55
+ lexed.get_value($2).parentheses,
56
+ tokens_range
57
+ )
58
+
59
+ when /:LBRCS(\d+):CONT(\d+):RBRCS(\d+)/
60
+ tokens_range = $1.to_i..$3.to_i
61
+ token_val = lexed.get_value($2)
62
+
63
+ cont =
64
+ case token_val
65
+ when /#{ONEHASH}(#{CMA}#{ONEHASH})*/
66
+ ListParser.execute(token_val)
67
+ else
68
+ token_val
69
+ end
70
+
71
+ lexed.parsed!(cont, tokens_range)
72
+
73
+ when /:FUNCCN(\d+)/
74
+ token_val = lexed.get_value($1)
75
+ lexed.parsed!(token_val.parentheses, $1)
76
+
77
+ when /:CONT(\d+)/
78
+ lexed.parsed!(lexed.get_value($1), $1)
79
+ end
80
+ lexed.squash!(($1.to_i)..($1.to_i+1)) if lexed.token_str =~ /:(?:CONT|R)(\d+):(?:CONT|R)(\d+)/
81
+ end
82
+
83
+ LangEqualizer.execute(
84
+ lexed.values.join
85
+ )
86
+ end
87
+ module_function :execute
88
+
89
+ # FIXIT
90
+ class LangEqualizer
91
+ def self.execute(str)
92
+ case $meta_info.lang
93
+ when :ruby
94
+ str.gsub(/\^/, '**')
95
+ else
96
+ str
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,7 @@
1
+ langs:
2
+ :r: R
3
+ :ruby: Ruby
4
+ :python: Pyhton
5
+ :haskell: Haskell
6
+ :scala: Scala
7
+ :js: Javascript