qlang 0.0.14 → 0.0.27

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