qlang 0.0.27 → 0.0.141
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/README.md +20 -38
- data/lib/qlang/api.rb +2 -22
- data/lib/qlang/api/list_api.rb +2 -8
- data/lib/qlang/exec.rb +24 -26
- data/lib/qlang/iq.rb +5 -26
- data/lib/qlang/lexer/base.rb +3 -15
- data/lib/qlang/lexer/func_lexer.rb +2 -2
- data/lib/qlang/lexer/wrap_lexer.rb +2 -10
- data/lib/qlang/parser.rb +22 -32
- data/lib/qlang/parser/func_parser.rb +7 -6
- data/lib/qlang/parser/integral_parser.rb +2 -2
- data/lib/qlang/parser/matrix_parser.rb +2 -6
- data/lib/qlang/parser/vector_parser.rb +2 -4
- data/lib/qlang/version.rb +1 -1
- data/q_lang.gemspec +1 -2
- data/spec/function_spec.rb +31 -0
- data/spec/{objects/integral_spec.rb → integral_spec.rb} +0 -1
- data/spec/iq_spec.rb +19 -105
- data/spec/list_spec.rb +31 -0
- data/spec/{objects/matrix_spec.rb → matrix_spec.rb} +0 -0
- data/spec/q_lang_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -4
- data/spec/{objects/vector_spec.rb → vector_spec.rb} +0 -0
- data/tanaka.rb +4 -0
- metadata +27 -31
- data/.coveralls.yml +0 -2
- data/lib/qlang/lexer/tokens.rb +0 -45
- data/lib/qlang/parser/formula_parser.rb +0 -36
- data/spec/lexer/regular_expressions_spec.rb +0 -18
- data/spec/objects/function_spec.rb +0 -33
- data/spec/objects/list_spec.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 717677209dfcc71bdf36cce50db8ec22692dd7f8
|
4
|
+
data.tar.gz: 46f9c75f916b1975e03075db0410b64769078ff3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22d87e8c71f5e87481488d58fe6fcda5269e983437fb4cdb830b954f4b25942eee41e1be4efdcdbd50d2668f84d0e9c6d49648fb75a4707c946a2e7888949017
|
7
|
+
data.tar.gz: 675be6320a08b8c72a0950aead7c353cfdebe92b37b08111957e7dee88ecc4c2b22f160bef7bd44b29a1d03547faa191433d19cafc9f5594abc78e2b1cfc4425
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,60 +1,42 @@
|
|
1
1
|
# Qlang
|
2
2
|
|
3
|
-
[![Gem Version](https://badge.fury.io/rb/qlang.svg)](http://badge.fury.io/rb/qlang) [![Build Status](https://travis-ci.org/gogotanaka/Q.svg?branch=master)](https://travis-ci.org/gogotanaka/Q) [![Coverage Status](https://coveralls.io/repos/gogotanaka/Q/badge.png?branch=master)](https://coveralls.io/r/gogotanaka/Q?branch=master) [![Code Climate](https://codeclimate.com/github/gogotanaka/Q/badges/gpa.svg)](https://codeclimate.com/github/gogotanaka/Q) [![Dependency Status](https://gemnasium.com/gogotanaka/Q.svg)](https://gemnasium.com/gogotanaka/Q)
|
4
|
-
|
5
3
|
Enjoy MATH with Keyboard.
|
6
4
|
|
7
|
-
### Differentiate
|
8
5
|
|
9
6
|
```
|
10
|
-
|
11
|
-
=> ( - sin( x ) )
|
12
|
-
|
13
|
-
d/dx(log(x))
|
14
|
-
=> ( 1 / x )
|
7
|
+
# Differentiate
|
15
8
|
|
16
|
-
|
9
|
+
Q:-> d/dx(cos(x))
|
10
|
+
( - sin( x ) )
|
17
11
|
|
18
|
-
d/
|
19
|
-
|
12
|
+
Q:-> d/dx(log(x))
|
13
|
+
( 1 / x )
|
20
14
|
|
21
|
-
d/dy
|
22
|
-
|
23
|
-
```
|
15
|
+
Q:-> d/dy(y ** 2)
|
16
|
+
( 2 * y )
|
24
17
|
|
25
18
|
|
26
|
-
|
27
|
-
|
28
|
-
```
|
29
|
-
S(log(x)dx)[0..1]
|
30
|
-
=> - oo
|
19
|
+
# Integrate
|
31
20
|
|
32
|
-
S(
|
33
|
-
|
21
|
+
Q:-> S(log(x)dx)[0..1]
|
22
|
+
( - sin( x ) )
|
34
23
|
|
35
|
-
|
36
|
-
|
37
|
-
```
|
24
|
+
Q:-> d/dx(log(x))
|
25
|
+
( 1 / x )
|
38
26
|
|
27
|
+
Q:-> d/dy(y ** 2)
|
28
|
+
( 2 * y )
|
39
29
|
|
40
30
|
### Matrix
|
41
|
-
|
42
|
-
```
|
31
|
+
Q:->(1 2 3; 4 5 6)
|
43
32
|
(1 2 3; 4 5 6)
|
44
|
-
=> (1 2 3; 4 5 6)
|
45
33
|
|
46
|
-
(1 2 3; 4 5 6) + (1 2 3; 4 5 6)
|
47
|
-
|
34
|
+
Q:-> (1 2 3; 4 5 6) + (1 2 3; 4 5 6)
|
35
|
+
(2 4 6; 8 10 12)
|
48
36
|
|
49
|
-
(1 2 3; 4 5 6) * (1 2 3)
|
50
|
-
|
51
|
-
```
|
37
|
+
Q:-> (1 2 3; 4 5 6) * (1 2 3)
|
38
|
+
(14 32)
|
52
39
|
|
53
|
-
### Function
|
54
|
-
```
|
55
|
-
f(x, y) = xy
|
56
|
-
f(1, 2)
|
57
|
-
=> 2
|
58
40
|
```
|
59
41
|
|
60
42
|
|
@@ -79,7 +61,7 @@ Install it yourself as:
|
|
79
61
|
|
80
62
|
## Contributing
|
81
63
|
|
82
|
-
1. Fork it ( https://github.com/
|
64
|
+
1. Fork it ( https://github.com/[my-github-username]/qlang/fork )
|
83
65
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
66
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
67
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/qlang/api.rb
CHANGED
@@ -9,35 +9,15 @@ module Qlang
|
|
9
9
|
# TODO:
|
10
10
|
class ::String
|
11
11
|
def rm(str_or_rgx)
|
12
|
-
gsub(str_or_rgx, '')
|
13
|
-
end
|
14
|
-
|
15
|
-
def rm!(str_or_rgx)
|
16
12
|
gsub!(str_or_rgx, '')
|
17
|
-
self
|
18
13
|
end
|
19
14
|
|
20
|
-
def rms
|
15
|
+
def rms(*str_or_rgxs)
|
21
16
|
str_or_rgxs.each do |str_or_rgx|
|
22
|
-
rm
|
17
|
+
rm(str_or_rgx)
|
23
18
|
end
|
24
19
|
self
|
25
20
|
end
|
26
|
-
|
27
|
-
def split_by_sp
|
28
|
-
split(/ +/)
|
29
|
-
end
|
30
|
-
|
31
|
-
# FIX:
|
32
|
-
def equalize!
|
33
|
-
rms!(/\A +/, / +\z/)
|
34
|
-
if self =~ /\A\(/ && self =~ /\)\z/
|
35
|
-
rms!(/\A\(/, /\)\z/)
|
36
|
-
rms!(/\A +/, / +\z/)
|
37
|
-
else
|
38
|
-
self
|
39
|
-
end
|
40
|
-
end
|
41
21
|
end
|
42
22
|
|
43
23
|
class ::Matrix
|
data/lib/qlang/api/list_api.rb
CHANGED
@@ -2,14 +2,8 @@ module Qlang
|
|
2
2
|
module Api
|
3
3
|
module ListApi
|
4
4
|
def execute(arys)
|
5
|
-
|
6
|
-
|
7
|
-
combineds_by_equal = arys.map { |ary| "#{ary[0]}=#{ary[1]}" }.join(', ')
|
8
|
-
"list(#{combineds_by_equal})"
|
9
|
-
when :Ruby
|
10
|
-
fail 'List is not implemented for Ruby'
|
11
|
-
end
|
12
|
-
|
5
|
+
combineds_by_equal = arys.map { |ary| "#{ary[0]}=#{ary[1]}" }.join(', ')
|
6
|
+
"list(#{combineds_by_equal})"
|
13
7
|
end
|
14
8
|
module_function :execute
|
15
9
|
end
|
data/lib/qlang/exec.rb
CHANGED
@@ -19,36 +19,34 @@ module Qlang
|
|
19
19
|
exit 0
|
20
20
|
end
|
21
21
|
|
22
|
-
private
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
else
|
31
|
-
print 'Q support Ruby and R now.'
|
32
|
-
end
|
22
|
+
private def ch_compile_type(lang)
|
23
|
+
case lang
|
24
|
+
when '-Ruby'
|
25
|
+
Qlang.to_ruby
|
26
|
+
when '-R'
|
27
|
+
Qlang.to_r
|
28
|
+
else
|
29
|
+
print 'Q support Ruby and R now.'
|
33
30
|
end
|
31
|
+
end
|
34
32
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
33
|
+
private def parse
|
34
|
+
raise '#{@args[0]} is unsupported option' unless @args[0] == '-q'
|
35
|
+
filename = @args[1]
|
36
|
+
file = open_file(filename)
|
37
|
+
string = read_file(file)
|
38
|
+
print(Kconv.tosjis(Qlang.compile(string)), '\n')
|
39
|
+
file.close
|
40
|
+
end
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
private def open_file(filename, flag = 'r')
|
43
|
+
return if filename.nil?
|
44
|
+
File.open(filename, flag)
|
45
|
+
end
|
48
46
|
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
private def read_file(file)
|
48
|
+
file.read
|
49
|
+
end
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
data/lib/qlang/iq.rb
CHANGED
@@ -1,39 +1,18 @@
|
|
1
1
|
module Qlang
|
2
2
|
module Iq
|
3
|
-
|
4
|
-
|
5
|
-
def to_q
|
6
|
-
str = to_s.gsub(/\*\*/, '^').rm(' * ')
|
7
|
-
str.equalize!
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.execute(code)
|
12
|
-
ruby_code = Q.to_ruby.compile(code)
|
13
|
-
ruby_obj = eval(ruby_code)
|
14
|
-
|
15
|
-
optimize_output(ruby_obj)
|
16
|
-
rescue SyntaxError
|
17
|
-
# TODO: emergency
|
18
|
-
case ruby_code
|
19
|
-
when /(\d)+(\w)/
|
20
|
-
execute("#{$1} * #{$2}")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.optimize_output(ruby_obj)
|
3
|
+
def execute(code)
|
4
|
+
ruby_obj = eval Q.to_ruby.compile(code)
|
25
5
|
case ruby_obj
|
26
|
-
when Matrix, Vector
|
6
|
+
when Matrix, Vector
|
27
7
|
ruby_obj.to_q
|
28
8
|
when Float::INFINITY
|
29
9
|
'oo'
|
30
10
|
when - Float::INFINITY
|
31
11
|
'-oo'
|
32
12
|
else
|
33
|
-
|
34
|
-
str.equalize!
|
13
|
+
ruby_obj
|
35
14
|
end
|
36
15
|
end
|
37
|
-
|
16
|
+
module_function :execute
|
38
17
|
end
|
39
18
|
end
|
data/lib/qlang/lexer/base.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
require 'strscan'
|
2
|
-
require 'qlang/lexer/tokens'
|
3
|
-
|
4
2
|
|
5
3
|
module Qlang
|
6
4
|
module Lexer
|
7
5
|
class Base
|
8
|
-
attr_accessor :lexeds
|
9
|
-
include Tokens
|
10
6
|
class << self
|
11
7
|
attr_reader :token_hash
|
12
8
|
|
@@ -100,18 +96,10 @@ module Qlang
|
|
100
96
|
end
|
101
97
|
end
|
102
98
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
@lexeds.insert(token_position, { R: parsed })
|
99
|
+
private def to_num(token_with_num)
|
100
|
+
token_with_num =~ /\d+/
|
101
|
+
$&.to_i
|
107
102
|
end
|
108
|
-
|
109
|
-
private
|
110
|
-
|
111
|
-
def to_num(token_with_num)
|
112
|
-
token_with_num =~ /\d+/
|
113
|
-
$&.to_i
|
114
|
-
end
|
115
103
|
end
|
116
104
|
end
|
117
105
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
module Qlang
|
2
2
|
module Lexer
|
3
3
|
class FuncLexer < Base
|
4
|
-
rule(
|
4
|
+
rule(/\w\(\w( ?, ?\w)*\)/) { :FDEF }
|
5
5
|
rule(/\=/) { :EQL }
|
6
6
|
|
7
7
|
rule(/[ \t\f]/)
|
8
8
|
|
9
9
|
rule(/\r\n/) { :NLIN }
|
10
|
-
rule(
|
10
|
+
rule(/\w.*/) { :OTHER }
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -1,16 +1,8 @@
|
|
1
|
-
require 'pry'
|
2
1
|
module Qlang
|
3
2
|
module Lexer
|
4
3
|
class WrapLexer < Base
|
5
|
-
rule(
|
6
|
-
rule(
|
7
|
-
rule(/S#{ANYSP}#{LPRN}#{ANYSTR}#{RPRN}\[#{ANYSTR}\]/) { :integral }
|
8
|
-
rule(/d\/d#{VAR} .*/) { :differential }
|
9
|
-
rule(%r@#{LPRN}#{NUMS_BY_SP}#{RPRN}@) { :vector }
|
10
|
-
rule(%r@#{LPRN}#{NUMS_BY_SP_BY_SCLN}#{RPRN}t@) { :tmatrix }
|
11
|
-
rule(%r@#{LPRN}#{NUMS_BY_SP_BY_SCLN}#{RPRN}@) { :matrix }
|
12
|
-
|
13
|
-
|
4
|
+
rule(/\w\(\w( ?, ?\w)*\) ?= ?[^\r\n]+/) { :FUNC }
|
5
|
+
rule(/S *\(.+\)\[.+\]/) { :ITGL }
|
14
6
|
rule(/\(/) { :LPRN }
|
15
7
|
rule(/\)/) { :RPRN }
|
16
8
|
rule(/\{/) { :LBRC }
|
data/lib/qlang/parser.rb
CHANGED
@@ -9,7 +9,6 @@ require 'qlang/parser/vector_parser'
|
|
9
9
|
require 'qlang/parser/list_parser'
|
10
10
|
require 'qlang/parser/func_parser'
|
11
11
|
require 'qlang/parser/integral_parser'
|
12
|
-
require 'qlang/parser/formula_parser'
|
13
12
|
|
14
13
|
module Qlang
|
15
14
|
module Parser
|
@@ -19,30 +18,18 @@ module Qlang
|
|
19
18
|
fail "I'm so sorry, something wrong. Please feel free to report this." if Time.now > time + 10
|
20
19
|
|
21
20
|
case lexed.token_str
|
22
|
-
when /(:vector)(\d)/, /(:matrix)(\d)/, /(:tmatrix)(\d)/, /(:integral)(\d)/, /(:def_func)(\d)/
|
23
|
-
token_sym = $1.delete(':').to_sym
|
24
|
-
token_position = $2.to_i
|
25
|
-
token_val = lexed.lexeds[token_position][token_sym]
|
26
|
-
|
27
|
-
parsed = case token_sym
|
28
|
-
when :vector
|
29
|
-
VectorParser.execute(token_val)
|
30
|
-
when :matrix
|
31
|
-
MatrixParser.execute(token_val)
|
32
|
-
when :tmatrix
|
33
|
-
MatrixParser.execute(token_val, trans: true)
|
34
|
-
when :integral
|
35
|
-
IntegralParser.execute(token_val)
|
36
|
-
when :def_func
|
37
|
-
FuncParser.execute(token_val)
|
38
|
-
end
|
39
|
-
lexed.parsed!(token_position, parsed)
|
40
|
-
|
41
21
|
when /:LPRN\d(:CONT\d):RPRN\d/
|
42
22
|
cont_token_with_num = $1
|
43
23
|
cont_lexed = Lexer::ContLexer.new(lexed.get_value(cont_token_with_num))
|
44
24
|
|
45
|
-
|
25
|
+
case cont_lexed.token_str
|
26
|
+
when /(:NUM\d)+(:SCLN\d|:NLIN\d)(:NUM\d)/
|
27
|
+
cont = MatrixParser.execute(cont_lexed)
|
28
|
+
when /(:NUM\d)+/
|
29
|
+
cont = VectorParser.execute(cont_lexed)
|
30
|
+
else
|
31
|
+
cont = "(#{cont_lexed.values.join(' ')})"
|
32
|
+
end
|
46
33
|
lexed.squash_with_prn(cont_token_with_num, cont)
|
47
34
|
|
48
35
|
when /:LBRC\d(:CONT\d):RBRC\d/
|
@@ -57,26 +44,29 @@ module Qlang
|
|
57
44
|
end
|
58
45
|
lexed.squash_with_prn(cont_token_with_num, cont)
|
59
46
|
|
60
|
-
when /:
|
47
|
+
when /:FUNC\d/
|
61
48
|
cont_token_with_num = $&
|
62
|
-
|
63
|
-
lexed.squash_with_prn(cont_token_with_num, cont)
|
49
|
+
cont_lexed = Lexer::FuncLexer.new(lexed.get_value(cont_token_with_num))
|
64
50
|
|
65
|
-
|
51
|
+
case cont_lexed.token_str
|
52
|
+
when /:FDEF\d:EQL\d:OTHER\d/
|
53
|
+
cont = FuncParser.execute(cont_lexed)
|
54
|
+
lexed.ch_value(cont_token_with_num, cont)
|
55
|
+
lexed.ch_token(cont_token_with_num, :R)
|
56
|
+
end
|
57
|
+
|
58
|
+
when /:ITGL\d/
|
66
59
|
cont_token_with_num = $&
|
67
|
-
cont = lexed.get_value(cont_token_with_num)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
#cont.gsub!(/(d\/d[a-zA-Z]) (.*)/, "\1(\2)")
|
72
|
-
lexed.squash_with_prn(cont_token_with_num, cont)
|
60
|
+
cont = IntegralParser.execute(lexed.get_value(cont_token_with_num))
|
61
|
+
lexed.ch_value(cont_token_with_num, cont)
|
62
|
+
lexed.ch_token(cont_token_with_num, :R)
|
63
|
+
|
73
64
|
when /:CONT\d/
|
74
65
|
lexed.ch_token($&, :R)
|
75
66
|
end
|
76
67
|
|
77
68
|
lexed.squash_to_cont($1, 2) if lexed.token_str =~ /(:CONT\d|:R\d)(:CONT\d|:R\d)/
|
78
69
|
end
|
79
|
-
|
80
70
|
lexed.fix_r_txt!
|
81
71
|
lexed.values.join
|
82
72
|
end
|
@@ -1,13 +1,14 @@
|
|
1
|
-
require 'qlang/lexer/tokens'
|
2
1
|
module Qlang
|
3
2
|
module Parser
|
4
3
|
module FuncParser
|
5
4
|
include Base
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
def execute(lexed)
|
6
|
+
lexed.fix_r_txt!
|
7
|
+
fdef_ary = lexed[0][:FDEF].split('')
|
8
|
+
func_name = fdef_ary.shift
|
9
|
+
args = fdef_ary.join.rms('(', ')', ',', ' ').split('')
|
10
|
+
|
11
|
+
FuncApi.execute(func_name, args, lexed[-1][:OTHER])
|
11
12
|
end
|
12
13
|
module_function :execute
|
13
14
|
end
|
@@ -5,9 +5,9 @@ module Qlang
|
|
5
5
|
def execute(string)
|
6
6
|
integrated, range = string.scan(/S *\((.+)\)\[(.+)\]/).first
|
7
7
|
|
8
|
-
integrated.rm
|
8
|
+
integrated.rm(' ')
|
9
9
|
|
10
|
-
IntegralApi.execute(
|
10
|
+
IntegralApi.execute(integrated[0..-3], integrated[-2..-1], range)
|
11
11
|
end
|
12
12
|
module_function :execute
|
13
13
|
end
|
@@ -2,13 +2,9 @@ module Qlang
|
|
2
2
|
module Parser
|
3
3
|
module MatrixParser
|
4
4
|
include Base
|
5
|
-
def execute(
|
6
|
-
|
7
|
-
rows = lexed_string.split(/ *; */).map(&:split_by_sp)
|
5
|
+
def execute(lexed)
|
6
|
+
rows = lexed.split(';')
|
8
7
|
rows.all? { |row| row.count == rows.first.count }
|
9
|
-
if trans
|
10
|
-
rows = rows.transpose
|
11
|
-
end
|
12
8
|
MatrixApi.execute(rows)
|
13
9
|
end
|
14
10
|
module_function :execute
|
@@ -2,10 +2,8 @@ module Qlang
|
|
2
2
|
module Parser
|
3
3
|
module VectorParser
|
4
4
|
include Base
|
5
|
-
def execute(
|
6
|
-
|
7
|
-
elements = lexed_string.split_by_sp
|
8
|
-
VectorApi.execute(elements)
|
5
|
+
def execute(lexed)
|
6
|
+
VectorApi.execute(lexed.values)
|
9
7
|
end
|
10
8
|
module_function :execute
|
11
9
|
end
|
data/lib/qlang/version.rb
CHANGED
data/q_lang.gemspec
CHANGED
@@ -18,9 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency "dydx", '~> 0.1.41421'
|
22
|
-
|
23
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
24
22
|
spec.add_development_dependency "rake"
|
25
23
|
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "dydx", '0.1.412'
|
26
25
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Qlang do
|
4
|
+
describe 'Function' do
|
5
|
+
it do
|
6
|
+
expect(
|
7
|
+
Q.compile('f(x, y) = x + y')
|
8
|
+
).to eq(
|
9
|
+
"f <- function(x ,y) x + y"
|
10
|
+
)
|
11
|
+
|
12
|
+
expect(
|
13
|
+
Q.compile('g(x) = x ** 2')
|
14
|
+
).to eq(
|
15
|
+
"g <- function(x) x ** 2"
|
16
|
+
)
|
17
|
+
|
18
|
+
expect(
|
19
|
+
Q.compile('g(x) = x ** (2 + 2)')
|
20
|
+
).to eq(
|
21
|
+
"g <- function(x) x ** (2 + 2)"
|
22
|
+
)
|
23
|
+
|
24
|
+
expect(
|
25
|
+
Q.compile('h(a, b, c) = a ** 2 + b ** 2 + c ** 2')
|
26
|
+
).to eq(
|
27
|
+
"h <- function(a ,b ,c) a ** 2 + b ** 2 + c ** 2"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/spec/iq_spec.rb
CHANGED
@@ -2,65 +2,15 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Qlang do
|
4
4
|
describe Iq do
|
5
|
-
def self.def_test(name, input, output)
|
6
|
-
it name + '_def' do
|
7
|
-
expect(Iq.execute(input)).to eq(output)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.cal_test(name, input, output)
|
12
|
-
it name + '_cal' do
|
13
|
-
expect(Iq.execute(input)).to eq(output)
|
14
|
-
reset
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
describe 'General' do
|
19
|
-
cal_test('ex1', '2x', '2x')
|
20
|
-
cal_test('ex2', 'x + x', '2x')
|
21
|
-
cal_test('ex3', 'x * y', 'xy')
|
22
|
-
end
|
23
|
-
|
24
5
|
describe 'Matrix' do
|
25
|
-
|
26
|
-
'(1 2 3; 4 5 6)'
|
27
|
-
'(1 2 3; 4 5 6)'
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
'(1 2 3
|
32
|
-
|
33
|
-
)
|
34
|
-
|
35
|
-
cal_test('ex3',
|
36
|
-
'(1 2 3; 4 5 6) - (2 4 1; 8 3 9)',
|
37
|
-
'(-1 -2 2; -4 2 -3)'
|
38
|
-
)
|
39
|
-
|
40
|
-
cal_test('ex4',
|
41
|
-
'(1 2; 3 4) * (1 2; 3 4)',
|
42
|
-
'(7 10; 15 22)'
|
43
|
-
)
|
44
|
-
|
45
|
-
cal_test('ex5',
|
46
|
-
'(1 2; 3 4) ** 2',
|
47
|
-
'(7 10; 15 22)'
|
48
|
-
)
|
49
|
-
|
50
|
-
cal_test('ex6',
|
51
|
-
'(1 2; 3 4) ** 2',
|
52
|
-
'(7 10; 15 22)'
|
53
|
-
)
|
54
|
-
|
55
|
-
cal_test('ex7',
|
56
|
-
'(1 2; 3 4) * (1 2)',
|
57
|
-
'(5 11)'
|
58
|
-
)
|
59
|
-
|
60
|
-
cal_test('ex8',
|
61
|
-
'(1 2 3; 4 5 6)t',
|
62
|
-
'(1 4; 2 5; 3 6)'
|
63
|
-
)
|
6
|
+
it do
|
7
|
+
expect(Iq.execute('(1 2 3; 4 5 6)')).to eq('(1 2 3; 4 5 6)')
|
8
|
+
expect(Iq.execute('(1 2 3; 4 5 6) + (1 2 3; 4 5 6)')).to eq('(2 4 6; 8 10 12)')
|
9
|
+
expect(Iq.execute('(1 2 3; 4 5 6) - (2 4 1; 8 3 9)')).to eq('(-1 -2 2; -4 2 -3)')
|
10
|
+
expect(Iq.execute('(1 2; 3 4) * (1 2; 3 4)')).to eq('(7 10; 15 22)')
|
11
|
+
expect(Iq.execute('(1 2; 3 4) ** 2')).to eq('(7 10; 15 22)')
|
12
|
+
expect(Iq.execute('(1 2; 3 4) * (1 2)')).to eq('(5 11)')
|
13
|
+
end
|
64
14
|
end
|
65
15
|
|
66
16
|
describe 'Vector' do
|
@@ -79,63 +29,27 @@ describe Qlang do
|
|
79
29
|
|
80
30
|
describe 'Diff' do
|
81
31
|
it do
|
82
|
-
expect(Iq.execute('d/dx(e ** x)')).to eq(
|
83
|
-
expect(Iq.execute('d/dx(x ** 2)')).to eq(
|
84
|
-
expect(Iq.execute('d/dx(x * 2)')).to eq(
|
85
|
-
expect(Iq.execute('d/dx( sin(x) )')).to eq(
|
86
|
-
expect(Iq.execute('d/dx(log( x ))')).to eq(
|
32
|
+
expect(Iq.execute('d/dx(e ** x)')).to eq(e ** x)
|
33
|
+
expect(Iq.execute('d/dx(x ** 2)')).to eq(2 * x)
|
34
|
+
expect(Iq.execute('d/dx(x * 2)')).to eq(2)
|
35
|
+
expect(Iq.execute('d/dx( sin(x) )')).to eq(cos(x))
|
36
|
+
expect(Iq.execute('d/dx(log( x ))')).to eq(1/x)
|
87
37
|
end
|
88
|
-
cal_test('ex1', 'd/dx cos(x)', '- sin( x )')
|
89
|
-
cal_test('ex2', 'd/dx xx', '2x')
|
90
38
|
end
|
91
39
|
|
92
40
|
describe 'Integral' do
|
93
41
|
it do
|
94
42
|
expect(Iq.execute('S( log(x)dx )[0..1]')).to eq('-oo')
|
95
|
-
expect(Iq.execute('S( sin(x)dx )[0..pi]')).to eq(
|
96
|
-
expect(Iq.execute('S( cos(x)dx )[0..pi]')).to eq(
|
97
|
-
expect(Iq.execute('S( cos(x)dx )[0..pi]')).to eq('0.0')
|
43
|
+
expect(Iq.execute('S( sin(x)dx )[0..pi]')).to eq(2.0)
|
44
|
+
expect(Iq.execute('S( cos(x)dx )[0..pi]')).to eq(0.0)
|
98
45
|
end
|
99
|
-
cal_test('ex1', 'S(xx dx)[0..1]', '0.33333333')
|
100
|
-
cal_test('ex2', 'S(2pi dx)[0..1]', '6.28318531')
|
101
46
|
end
|
102
47
|
|
103
48
|
describe 'Function' do
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
cal_test('ex2', 'f( 3, 9 )', '27.0')
|
109
|
-
|
110
|
-
def_test('ex3', 'f(x, y) = xy^2', 'x * ( y ** 2 )')
|
111
|
-
cal_test('ex3', 'f( 3, 2 )', '12.0')
|
112
|
-
|
113
|
-
def_test('ex4', 'f(x, y) = xy^2', 'x * ( y ** 2 )')
|
114
|
-
cal_test('ex4', 'df/dx', 'y ^ 2')
|
115
|
-
|
116
|
-
def_test('ex5', 'g(x) = x ^ 2', 'x ** 2')
|
117
|
-
cal_test('ex5', 'g(2)', '4.0')
|
118
|
-
|
119
|
-
def_test('ex6', 'h(x) = e ^ 2', 'e ** 2')
|
120
|
-
cal_test('ex6', 'h(2)', '7.3890560989306495')
|
121
|
-
|
122
|
-
def_test('ex7', 'h(x) = pix', 'pi * x')
|
123
|
-
cal_test('ex7', 'h(3)', '9.42477796076938')
|
124
|
-
|
125
|
-
def_test('ex8', 'h(x) = pie', 'pi * e')
|
126
|
-
cal_test('ex8', 'h(2)', '8.539734222673566')
|
127
|
-
|
128
|
-
def_test('ex9', 'h(x) = ( 1 / ( 2pi ) ^ ( 1 / 2.0 ) ) * e ^ ( - x ^ 2 / 2 )', '( ( 4503599627370496 / 6369051672525773 ) / ( pi ** 0.5 ) ) * ( e ** ( ( - ( x ** 2 ) ) / 2 ) )')
|
129
|
-
cal_test('ex9', 'S( h(x)dx )[-oo..oo]', '1.0')
|
130
|
-
|
131
|
-
def_test('ex10', 'f(x) = sin(x)', 'sin( x )')
|
132
|
-
cal_test('ex10', 'f(pi)', '0.0')
|
133
|
-
|
134
|
-
def_test('ex11', 'f(x) = cos(x)', 'cos( x )')
|
135
|
-
cal_test('ex11', 'f(pi)', '-1.0')
|
136
|
-
|
137
|
-
def_test('ex11', 'f(x) = log(x)', 'log( x )')
|
138
|
-
cal_test('ex11', 'f(e)', '1.0')
|
49
|
+
it do
|
50
|
+
expect(Iq.execute('f(x, y) = x + y')).to eq(f(x, y) <= x + y)
|
51
|
+
expect(Iq.execute('g(x) = x ** 2')).to eq(g(x) <= x ** 2)
|
52
|
+
end
|
139
53
|
end
|
140
54
|
end
|
141
55
|
end
|
data/spec/list_spec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Qlang do
|
4
|
+
describe 'List' do
|
5
|
+
it do
|
6
|
+
expect(
|
7
|
+
Q.to_r.compile('{name: "Gogotanaka", age: 21, birth: (1992 8 10) }')
|
8
|
+
).to eq(
|
9
|
+
"list(name=\"Gogotanaka\", age=21, birth=c(1992, 8, 10))"
|
10
|
+
)
|
11
|
+
|
12
|
+
expect(
|
13
|
+
Q.to_r.compile('{key1: 234234, key2: 387342 }')
|
14
|
+
).to eq(
|
15
|
+
"list(key1=234234, key2=387342)"
|
16
|
+
)
|
17
|
+
|
18
|
+
expect(
|
19
|
+
Q.to_r.compile('{key1:234234,key2:387342,key3:38733242}')
|
20
|
+
).to eq(
|
21
|
+
"list(key1=234234, key2=387342, key3=38733242)"
|
22
|
+
)
|
23
|
+
|
24
|
+
expect(
|
25
|
+
Q.to_r.compile('{key1:(1 3 2; 8 2 3),key2:387342,key3:38733242}')
|
26
|
+
).to eq(
|
27
|
+
"list(key1=matrix(c(1, 3, 2, 8, 2, 3), 2, 3, byrow = TRUE), key2=387342, key3=38733242)"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
File without changes
|
data/spec/q_lang_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
File without changes
|
data/tanaka.rb
ADDED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qlang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.141
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gogotanaka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: dydx
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 0.1.41421
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.41421
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +52,20 @@ dependencies:
|
|
66
52
|
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dydx
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.1.412
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.1.412
|
69
69
|
description: Enjoy MATH!
|
70
70
|
email:
|
71
71
|
- mail@tanakakazuki.com
|
@@ -74,7 +74,6 @@ executables:
|
|
74
74
|
extensions: []
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
|
-
- ".coveralls.yml"
|
78
77
|
- ".gitignore"
|
79
78
|
- ".rspec"
|
80
79
|
- ".rubocop.yml"
|
@@ -97,11 +96,9 @@ files:
|
|
97
96
|
- lib/qlang/lexer/base.rb
|
98
97
|
- lib/qlang/lexer/cont_lexer.rb
|
99
98
|
- lib/qlang/lexer/func_lexer.rb
|
100
|
-
- lib/qlang/lexer/tokens.rb
|
101
99
|
- lib/qlang/lexer/wrap_lexer.rb
|
102
100
|
- lib/qlang/parser.rb
|
103
101
|
- lib/qlang/parser/base.rb
|
104
|
-
- lib/qlang/parser/formula_parser.rb
|
105
102
|
- lib/qlang/parser/func_parser.rb
|
106
103
|
- lib/qlang/parser/integral_parser.rb
|
107
104
|
- lib/qlang/parser/list_parser.rb
|
@@ -109,15 +106,15 @@ files:
|
|
109
106
|
- lib/qlang/parser/vector_parser.rb
|
110
107
|
- lib/qlang/version.rb
|
111
108
|
- q_lang.gemspec
|
109
|
+
- spec/function_spec.rb
|
110
|
+
- spec/integral_spec.rb
|
112
111
|
- spec/iq_spec.rb
|
113
|
-
- spec/
|
114
|
-
- spec/
|
115
|
-
- spec/objects/integral_spec.rb
|
116
|
-
- spec/objects/list_spec.rb
|
117
|
-
- spec/objects/matrix_spec.rb
|
118
|
-
- spec/objects/vector_spec.rb
|
112
|
+
- spec/list_spec.rb
|
113
|
+
- spec/matrix_spec.rb
|
119
114
|
- spec/q_lang_spec.rb
|
120
115
|
- spec/spec_helper.rb
|
116
|
+
- spec/vector_spec.rb
|
117
|
+
- tanaka.rb
|
121
118
|
homepage: http://q-language.org/
|
122
119
|
licenses:
|
123
120
|
- MIT
|
@@ -143,12 +140,11 @@ signing_key:
|
|
143
140
|
specification_version: 4
|
144
141
|
summary: Enjoy MATH!
|
145
142
|
test_files:
|
143
|
+
- spec/function_spec.rb
|
144
|
+
- spec/integral_spec.rb
|
146
145
|
- spec/iq_spec.rb
|
147
|
-
- spec/
|
148
|
-
- spec/
|
149
|
-
- spec/objects/integral_spec.rb
|
150
|
-
- spec/objects/list_spec.rb
|
151
|
-
- spec/objects/matrix_spec.rb
|
152
|
-
- spec/objects/vector_spec.rb
|
146
|
+
- spec/list_spec.rb
|
147
|
+
- spec/matrix_spec.rb
|
153
148
|
- spec/q_lang_spec.rb
|
154
149
|
- spec/spec_helper.rb
|
150
|
+
- spec/vector_spec.rb
|
data/.coveralls.yml
DELETED
data/lib/qlang/lexer/tokens.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
module Qlang
|
2
|
-
module Lexer
|
3
|
-
module Tokens
|
4
|
-
# FIRST TOKEN
|
5
|
-
NUM = '[0-9]+'
|
6
|
-
VAR = '[a-z]'
|
7
|
-
FUNCV = '[a-zA-Z]'
|
8
|
-
VARNUM = '[0-9a-z]'
|
9
|
-
ANYSP = ' *'
|
10
|
-
ANYSTR = '.+'
|
11
|
-
NONL = '[^\r\n]'
|
12
|
-
LPRN = '\('
|
13
|
-
RPRN = '\)'
|
14
|
-
LBRC = '\{'
|
15
|
-
RBRC = '\}'
|
16
|
-
CLN = '\:'
|
17
|
-
SCLN = ';'
|
18
|
-
CMA = '\,'
|
19
|
-
SP = ' '
|
20
|
-
|
21
|
-
# SECOND TOKEN
|
22
|
-
class ::String
|
23
|
-
def line_by(char)
|
24
|
-
"#{ANYSP}#{self}(#{ANYSP}#{char}#{ANYSP}#{self})*#{ANYSP}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
NUMS_BY_CMA = NUM.line_by(CMA)
|
28
|
-
VARS_BY_CMA = VAR.line_by(CMA)
|
29
|
-
VARNUMS_BY_CMA = VARNUM.line_by(CMA)
|
30
|
-
NUMS_BY_SP = NUM.line_by(SP)
|
31
|
-
|
32
|
-
# THIRD TOKEN
|
33
|
-
class ::String
|
34
|
-
def func_call
|
35
|
-
"#{FUNCV}#{LPRN}#{ANYSP}#{self}*#{ANYSP}#{RPRN}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
FUNCCN = NUMS_BY_CMA.func_call
|
39
|
-
FUNCCV = VARS_BY_CMA.func_call
|
40
|
-
FUNCCVN = VARNUMS_BY_CMA.func_call
|
41
|
-
|
42
|
-
NUMS_BY_SP_BY_SCLN = NUMS_BY_SP.line_by(SCLN)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Qlang
|
2
|
-
module Parser
|
3
|
-
# FIX:
|
4
|
-
module FormulaParser
|
5
|
-
def execute(lexed)
|
6
|
-
ss = StringScanner.new(lexed)
|
7
|
-
result = ''
|
8
|
-
until ss.eos?
|
9
|
-
{ EXP: /\^/, BFUNC: /sin|cos|tan|log/, MUL: /(pi|[1-9a-z]){2,}/, SNGL: /(pi|[1-9a-z])/, OTHER: /([^\^1-9a-z]|^pi)+/ }.each do |token , rgx|
|
10
|
-
if ss.scan(rgx)
|
11
|
-
item = case token
|
12
|
-
when :EXP
|
13
|
-
$type == :Ruby ? '**' : '^'
|
14
|
-
when :MUL
|
15
|
-
sss = StringScanner.new(ss[0])
|
16
|
-
ary = []
|
17
|
-
until sss.eos?
|
18
|
-
[/pi/, /[1-9a-z]/].each do |rgx2|
|
19
|
-
ary << sss[0] if sss.scan(rgx2)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
ary.join(' * ')
|
23
|
-
else
|
24
|
-
ss[0]
|
25
|
-
end
|
26
|
-
result += item
|
27
|
-
break
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
result
|
32
|
-
end
|
33
|
-
module_function :execute
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'Regular expressions' do
|
4
|
-
def self.should_match(num, rgx, str)
|
5
|
-
it 'ex' + num.to_s do
|
6
|
-
expect(rgx =~ str).to eq(0)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
describe 'function' do
|
10
|
-
should_match(1, /[fgh]\(\w( ?, ?\w)*\) ?= ?[^\r\n]+/, 'f(x) = xy')
|
11
|
-
end
|
12
|
-
|
13
|
-
describe 'differentiate' do
|
14
|
-
rgx = /d\/d[a-zA-Z] .*/
|
15
|
-
should_match(1, rgx, 'd/dx sin(x)')
|
16
|
-
should_match(2, rgx, 'd/dz z^2')
|
17
|
-
end
|
18
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Qlang do
|
4
|
-
describe 'Function' do
|
5
|
-
context 'into R' do
|
6
|
-
it do
|
7
|
-
expect(
|
8
|
-
Q.to_r.compile('f(x, y) = x + y')
|
9
|
-
).to eq(
|
10
|
-
"f <- function(x, y) x + y"
|
11
|
-
)
|
12
|
-
|
13
|
-
expect(
|
14
|
-
Q.to_r.compile('g(x) = x ^ 2')
|
15
|
-
).to eq(
|
16
|
-
"g <- function(x) x ^ 2"
|
17
|
-
)
|
18
|
-
|
19
|
-
expect(
|
20
|
-
Q.to_r.compile('g(x) = x ^ (2 + 2)')
|
21
|
-
).to eq(
|
22
|
-
"g <- function(x) x ^ (2 + 2)"
|
23
|
-
)
|
24
|
-
|
25
|
-
expect(
|
26
|
-
Q.to_r.compile('h(a, b, c) = a ^ 2 + b ^ 2 + c ^ 2')
|
27
|
-
).to eq(
|
28
|
-
"h <- function(a, b, c) a ^ 2 + b ^ 2 + c ^ 2"
|
29
|
-
)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
data/spec/objects/list_spec.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Qlang do
|
4
|
-
describe 'List' do
|
5
|
-
it do
|
6
|
-
# expect(
|
7
|
-
# Q.to_r.compile('{name: "Gogotanaka", age: 21, birth: (1992 8 10) }')
|
8
|
-
# ).to eq(
|
9
|
-
# "list(name=\"Gogotanaka\", age=21, birth=c(1992, 8, 10))"
|
10
|
-
# )
|
11
|
-
|
12
|
-
expect(
|
13
|
-
Q.to_r.compile('{key1: 234234, key2: 387342 }')
|
14
|
-
).to eq(
|
15
|
-
"list(key1=234234, key2=387342)"
|
16
|
-
)
|
17
|
-
|
18
|
-
expect(
|
19
|
-
Q.to_r.compile('{key1:234234,key2:387342,key3:38733242}')
|
20
|
-
).to eq(
|
21
|
-
"list(key1=234234, key2=387342, key3=38733242)"
|
22
|
-
)
|
23
|
-
|
24
|
-
# expect(
|
25
|
-
# Q.to_r.compile('{key1:(1 3 2; 8 2 3),key2:387342,key3:38733242}')
|
26
|
-
# ).to eq(
|
27
|
-
# "list(key1=matrix(c(1, 3, 2, 8, 2, 3), 2, 3, byrow = TRUE), key2=387342, key3=38733242)"
|
28
|
-
# )
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|