qlang 0.0.14 → 0.0.27

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a994c4d36e4047ddd0e73fcd767404e2705de2d3
4
- data.tar.gz: 2cd5585e470142c5f0b54851944e9ebe85821006
3
+ metadata.gz: 805e11f0c327e3f7fd63d3d5a0de10c34d7f120b
4
+ data.tar.gz: 420cbcdcc4461907c7092a8405cf85d6e1af40d2
5
5
  SHA512:
6
- metadata.gz: f3d04413323acf98d1a7521fa755ab9945ce86252ba2f453bd68112cb7965462cb1fec60211df1f007c35abfe0f05a21639cea9f4846ac0abc85f5a454fe4df7
7
- data.tar.gz: 924e5bd208a209883ed4f7df5f6e0e01977a5c85c30029326c7ebd77285cfffbf8c276bafd349781bf5c62e9be14f8b993142d11e5595e714310c1e6ec3c11be
6
+ metadata.gz: f08fd5daf625fcde5decd4504267fdc05e57688ac716440f71c3d0a6ab01f5b94d3a4f56ec7a0476f5892aadbf2ee69163bfc4b094655415f14ba309a8228059
7
+ data.tar.gz: e4f188b8714777ea728bbb8e7e8ab23e745867b09fe96a2f40d1fc1fa178e4d406df11aa38650e71f969d6917ec6551fa01b31f96421d19081ba52b2901a9d0b
data/.coveralls.yml ADDED
@@ -0,0 +1,2 @@
1
+ repo_token: ZdXKADwEPNW5PJkIaC76yjqq4w04dIpuZ
2
+ service_name: travis-ci
data/Gemfile CHANGED
@@ -1,9 +1,7 @@
1
1
  source 'https://rubygems.org'
2
- ruby '2.1.2'
3
-
4
- gem 'dydx'
5
2
 
6
3
  gem 'rubocop'
4
+ gem 'coveralls', require: false
7
5
  gem 'pry'
8
6
 
9
7
  gemspec
data/README.md CHANGED
@@ -1,28 +1,85 @@
1
1
  # Qlang
2
2
 
3
- TODO: Write a gem description
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
4
 
5
- ## Installation
5
+ Enjoy MATH with Keyboard.
6
6
 
7
- Add this line to your application's Gemfile:
7
+ ### Differentiate
8
8
 
9
- gem 'qlang'
9
+ ```
10
+ d/dx(cos(x))
11
+ => ( - sin( x ) )
10
12
 
11
- And then execute:
13
+ d/dx(log(x))
14
+ => ( 1 / x )
12
15
 
13
- $ bundle
16
+ # You can omit parentheses
14
17
 
15
- Or install it yourself as:
18
+ d/dy y^2
19
+ => ( 2 * y )
20
+
21
+ d/dy xy
22
+ => ( x )
23
+ ```
24
+
25
+
26
+ ### Integrate
27
+
28
+ ```
29
+ S(log(x)dx)[0..1]
30
+ => - oo
31
+
32
+ S(sin(x)dx)[0..pi]
33
+ => 2.0
34
+
35
+ S(cos(x)dx)[0..pi]
36
+ => 0.0
37
+ ```
38
+
39
+
40
+ ### Matrix
41
+
42
+ ```
43
+ (1 2 3; 4 5 6)
44
+ => (1 2 3; 4 5 6)
45
+
46
+ (1 2 3; 4 5 6) + (1 2 3; 4 5 6)
47
+ => (2 4 6; 8 10 12)
48
+
49
+ (1 2 3; 4 5 6) * (1 2 3)
50
+ => (14 32)
51
+ ```
52
+
53
+ ### Function
54
+ ```
55
+ f(x, y) = xy
56
+ f(1, 2)
57
+ => 2
58
+ ```
59
+
60
+
61
+ ## How to use
62
+
63
+ Install it yourself as:
16
64
 
17
65
  $ gem install qlang
18
66
 
19
- ## Usage
67
+ ### Compiler into R
68
+
69
+ $ qlang -c -R foo.q
70
+
71
+ ### Compiler into Ruby
72
+
73
+ $ qlang -c -Ruby foo.q
74
+
75
+ ### Interpreter
76
+
77
+ $ qlang -i
20
78
 
21
- TODO: Write usage instructions here
22
79
 
23
80
  ## Contributing
24
81
 
25
- 1. Fork it ( https://github.com/[my-github-username]/qlang/fork )
82
+ 1. Fork it ( https://github.com/gogotanaka/Q/fork )
26
83
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
84
  3. Commit your changes (`git commit -am 'Add some feature'`)
28
85
  4. Push to the branch (`git push origin my-new-feature`)
data/bin/qlang ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ require 'qlang'
3
+ include Qlang
4
+
5
+ case ARGV.shift
6
+ when '-i'
7
+ loop do
8
+ print 'Q:-> '
9
+ begin
10
+ input = $stdin.gets
11
+ output = Iq.execute(input)
12
+ $stdout.puts output
13
+ rescue => e
14
+ puts e
15
+ end
16
+ end
17
+ when '-c'
18
+ compiler = Qlang::Exec::Compiler.new(ARGV)
19
+ compiler.parse!
20
+ end
data/lib/qlang.rb CHANGED
@@ -8,9 +8,10 @@ require 'qlang/parser'
8
8
 
9
9
  require 'qlang/exec'
10
10
 
11
- require 'qlang/q_on_irb'
11
+ require 'qlang/iq'
12
12
 
13
- require "kconv"
13
+ require 'kconv'
14
+ require 'matrix'
14
15
 
15
16
  module Qlang
16
17
  # compiles into R as default.
data/lib/qlang/api.rb CHANGED
@@ -2,8 +2,55 @@ require 'qlang/api/matrix_api'
2
2
  require 'qlang/api/vector_api'
3
3
  require 'qlang/api/list_api'
4
4
  require 'qlang/api/func_api'
5
+ require 'qlang/api/integral_api'
5
6
 
6
7
  module Qlang
7
8
  module Api
9
+ # TODO:
10
+ class ::String
11
+ def rm(str_or_rgx)
12
+ gsub(str_or_rgx, '')
13
+ end
14
+
15
+ def rm!(str_or_rgx)
16
+ gsub!(str_or_rgx, '')
17
+ self
18
+ end
19
+
20
+ def rms!(*str_or_rgxs)
21
+ str_or_rgxs.each do |str_or_rgx|
22
+ rm!(str_or_rgx)
23
+ end
24
+ self
25
+ 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
+ end
42
+
43
+ class ::Matrix
44
+ def to_q
45
+ q_rows = rows.map { |row| row.join(' ') }.join('; ')
46
+ "(#{q_rows})"
47
+ end
48
+ end
49
+
50
+ class ::Vector
51
+ def to_q
52
+ "(#{elements.join(' ')})"
53
+ end
54
+ end
8
55
  end
9
56
  end
@@ -2,7 +2,13 @@ module Qlang
2
2
  module Api
3
3
  module FuncApi
4
4
  def execute(func_name, args, contents)
5
- "#{func_name} <- function(#{ args.join(' ,') }) #{contents}"
5
+ case $type
6
+ when :R
7
+ "#{func_name} <- function(#{ args.join(' ,') }) #{contents}"
8
+ when :Ruby
9
+ "#{func_name}(#{ args.join(' ,') }) <= #{contents}"
10
+ end
11
+
6
12
  end
7
13
  module_function :execute
8
14
  end
@@ -0,0 +1,17 @@
1
+ module Qlang
2
+ module Api
3
+ module IntegralApi
4
+ def execute(func, delta, range)
5
+ a, b = range.split('..')
6
+ case $type
7
+ when :R
8
+ fail 'Integral is not implemented for R'
9
+ when :Ruby
10
+ "S(#{func}, #{delta})[#{a}, #{b}]"
11
+ end
12
+
13
+ end
14
+ module_function :execute
15
+ end
16
+ end
17
+ end
@@ -2,8 +2,14 @@ module Qlang
2
2
  module Api
3
3
  module ListApi
4
4
  def execute(arys)
5
- combineds_by_equal = arys.map { |ary| "#{ary[0]}=#{ary[1]}" }.join(', ')
6
- "list(#{combineds_by_equal})"
5
+ case $type
6
+ when :R
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
+
7
13
  end
8
14
  module_function :execute
9
15
  end
data/lib/qlang/exec.rb CHANGED
@@ -6,6 +6,7 @@ module Qlang
6
6
  end
7
7
 
8
8
  def parse!
9
+ ch_compile_type(ARGV.shift)
9
10
  parse
10
11
  rescue Exception => e
11
12
  raise e if @options[:trace] || e.is_a?(SystemExit)
@@ -18,23 +19,36 @@ module Qlang
18
19
  exit 0
19
20
  end
20
21
 
21
- private def parse
22
- raise '#{@args[0]} is unsupported option' unless @args[0] == '-q'
23
- filename = @args[1]
24
- file = open_file(filename)
25
- string = read_file(file)
26
- print(Kconv.tosjis(Qlang.compile(string)), '\n')
27
- file.close
28
- end
22
+ private
29
23
 
30
- private def open_file(filename, flag = 'r')
31
- return if filename.nil?
32
- File.open(filename, flag)
33
- end
24
+ def ch_compile_type(lang)
25
+ case lang
26
+ when '-Ruby'
27
+ Qlang.to_ruby
28
+ when '-R'
29
+ Qlang.to_r
30
+ else
31
+ print 'Q support Ruby and R now.'
32
+ end
33
+ end
34
34
 
35
- private def read_file(file)
36
- file.read
37
- end
35
+ def parse
36
+ raise '#{@args[0]} is unsupported option' unless @args[0] == '-q'
37
+ filename = @args[1]
38
+ file = open_file(filename)
39
+ string = read_file(file)
40
+ print(Kconv.tosjis(Qlang.compile(string)), '\n')
41
+ file.close
42
+ end
43
+
44
+ def open_file(filename, flag = 'r')
45
+ return if filename.nil?
46
+ File.open(filename, flag)
47
+ end
48
+
49
+ def read_file(file)
50
+ file.read
51
+ end
38
52
  end
39
53
  end
40
54
  end
data/lib/qlang/iq.rb ADDED
@@ -0,0 +1,39 @@
1
+ module Qlang
2
+ module Iq
3
+ class Dydx::Algebra::Formula
4
+ # FIX:
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)
25
+ case ruby_obj
26
+ when Matrix, Vector, Dydx::Algebra::Formula
27
+ ruby_obj.to_q
28
+ when Float::INFINITY
29
+ 'oo'
30
+ when - Float::INFINITY
31
+ '-oo'
32
+ else
33
+ str = ruby_obj.to_s
34
+ str.equalize!
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -1,8 +1,12 @@
1
1
  require 'strscan'
2
+ require 'qlang/lexer/tokens'
3
+
2
4
 
3
5
  module Qlang
4
6
  module Lexer
5
7
  class Base
8
+ attr_accessor :lexeds
9
+ include Tokens
6
10
  class << self
7
11
  attr_reader :token_hash
8
12
 
@@ -96,10 +100,18 @@ module Qlang
96
100
  end
97
101
  end
98
102
 
99
- private def to_num(token_with_num)
100
- token_with_num =~ /\d+/
101
- $&.to_i
103
+ # NEW APIs
104
+ def parsed!(token_position, parsed)
105
+ @lexeds.delete_at(token_position)
106
+ @lexeds.insert(token_position, { R: parsed })
102
107
  end
108
+
109
+ private
110
+
111
+ def to_num(token_with_num)
112
+ token_with_num =~ /\d+/
113
+ $&.to_i
114
+ end
103
115
  end
104
116
  end
105
117
  end
@@ -11,7 +11,10 @@ module Qlang
11
11
  rule(/[ \t\f]/)
12
12
 
13
13
  rule(/\r\n/) { :NLIN }
14
- rule(/\w+/) { :OTHER }
14
+
15
+ rule(/\w+/) { :SYM }
16
+
17
+ rule(/.+/) { :OTHER }
15
18
  end
16
19
  end
17
20
  end
@@ -1,13 +1,13 @@
1
1
  module Qlang
2
2
  module Lexer
3
3
  class FuncLexer < Base
4
- rule(/\w\(\w( ?, ?\w)*\)/) { :FDEF }
4
+ rule(%r@#{FUNCCV}@) { :FDEF }
5
5
  rule(/\=/) { :EQL }
6
6
 
7
7
  rule(/[ \t\f]/)
8
8
 
9
9
  rule(/\r\n/) { :NLIN }
10
- rule(/\w.*/) { :OTHER }
10
+ rule(/[\w\(].*/) { :FOML }
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,45 @@
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