hilbert 0.0.2700000

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